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

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

Move jobs management and execution endpoint from /processes/{procssId}/jobs to /jobs

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 104.8 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 (m);
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(cgiContentLength==1){
2092      if(strncasecmp(cgiRequestMethod,"GET",3)!=0){
2093        setMapInMaps(m,"lenv","status_code","405");
2094        map* pamError=createMap("code","InvalidMethod");
2095        const char* pccErr=_("This API does not support the method.");
2096        addToMap(pamError,"message",pccErr);
2097        printExceptionReportResponseJ(m,pamError);
2098        // TODO: cleanup memory
2099        return 1;
2100      }
2101      map* tmpMap=getMapFromMaps(m,"main","serverAddress");
2102      json_object *res1=json_object_new_array();
2103
2104      map* pmVal=getMapFromMaps(m,"openapi","links");
2105      char *orig=zStrdup(pmVal->value);
2106      char *saveptr;
2107      char *tmps = strtok_r (orig, ",", &saveptr);
2108      map* tmpUrl=getMapFromMaps(m,"openapi","rootUrl");
2109      while(tmps!=NULL){
2110        maps* tmpMaps=getMaps(m,tmps);
2111        if(tmpMaps!=NULL){
2112          json_object *res2;
2113          res2=mapToJson(tmpMaps->content);
2114          char* tmpStr=(char*) malloc((strlen(tmpUrl->value)+strlen(tmps)+2)*sizeof(char));
2115          sprintf(tmpStr,"%s%s",tmpUrl->value,tmps);
2116          json_object_object_add(res2,"href",json_object_new_string(tmpStr));
2117          free(tmpStr);
2118          json_object_array_add(res1,res2);
2119
2120          map* pmTmp=getMap(tmpMaps->content,"title");
2121          char *pacTitle=NULL;
2122          if(pmTmp!=NULL)
2123            pacTitle=zStrdup(pmTmp->value);
2124          char* pacTmp=(char*) malloc((strlen(tmps)+6)*sizeof(char));
2125          sprintf(pacTmp,"%s.html",tmps);
2126          tmpMaps=getMaps(m,pacTmp);
2127          if(tmpMaps==NULL && strncasecmp(pacTmp,"/.html",6)==0)
2128            tmpMaps=getMaps(m,"/index.html");
2129          if(tmpMaps!=NULL){
2130            json_object *res3;
2131            res3=mapToJson(tmpMaps->content);
2132            if(getMap(tmpMaps->content,"title")==NULL && pacTitle!=NULL){
2133              json_object_object_add(res3,"title",json_object_new_string(pacTitle));
2134            }
2135            char* tmpStr=NULL;
2136            if(strncasecmp(pacTmp,"/.html",6)==0){
2137              tmpStr=(char*) malloc((strlen(tmpUrl->value)+12)*sizeof(char));
2138              sprintf(tmpStr,"%s/index.html",tmpUrl->value);
2139            }else{map* tmpUrl=getMapFromMaps(m,"openapi","rootUrl");
2140              tmpStr=(char*) malloc((strlen(tmpUrl->value)+strlen(tmps)+6)*sizeof(char));
2141              sprintf(tmpStr,"%s%s.html",tmpUrl->value,tmps);
2142            }
2143            json_object_object_add(res3,"href",json_object_new_string(tmpStr));
2144            free(tmpStr);
2145            json_object_array_add(res1,res3);
2146          }
2147          free(pacTmp);
2148          if(pacTitle!=NULL)
2149            free(pacTitle);       
2150        }
2151        tmps = strtok_r (NULL, ",", &saveptr);
2152      }
2153      free(orig);
2154     
2155      map* pmTmp=getMapFromMaps(m,"identification","title");
2156      if(pmTmp!=NULL)
2157        json_object_object_add(res,"title",json_object_new_string(pmTmp->value));
2158      pmTmp=getMapFromMaps(m,"identification","abstract");
2159      if(pmTmp!=NULL)
2160        json_object_object_add(res,"description",json_object_new_string(pmTmp->value));
2161      json_object_object_add(res,"links",res1);
2162    }else if(strcmp(cgiQueryString,"/conformance")==0){
2163      /* - /conformance url */
2164      map* rootUrl=getMapFromMaps(m,"conformsTo","rootUrl");
2165      json_object *res1=json_object_new_array();
2166      map* length=getMapFromMaps(m,"conformsTo","length");
2167      maps* tmpMaps=getMaps(m,"conformsTo");
2168      for(int kk=0;kk<atoi(length->value);kk++){
2169        map* tmpMap1=getMapArray(tmpMaps->content,"link",kk);
2170        json_object *res2;
2171        if(tmpMap1!=NULL){
2172          char* tmpStr=(char*) malloc((strlen(rootUrl->value)+strlen(tmpMap1->value)+1)*sizeof(char));
2173          sprintf(tmpStr,"%s%s",rootUrl->value,tmpMap1->value);
2174          json_object_array_add(res1,json_object_new_string(tmpStr));
2175        }
2176      }
2177      json_object_object_add(res,"conformsTo",res1);
2178    }else if(strncasecmp(cgiQueryString,"/api",4)==0){
2179      if(strstr(cgiQueryString,".html")==NULL)
2180        produceApi(m,res);
2181      else{     
2182        char* pacTmp=(char*)malloc(9*sizeof(char));
2183        sprintf(pacTmp,"%s",cgiQueryString+1);
2184        map* pmTmp=getMapFromMaps(m,pacTmp,"href");
2185        free(pacTmp);
2186        if(pmTmp!=NULL)
2187          setMapInMaps(m,"headers","Location",pmTmp->value);
2188      } 
2189    }else if(strcmp(cgiQueryString,"/processes")==0 || strcmp(cgiQueryString,"/processes/")==0){
2190      /* - /processes */
2191      setMapInMaps(m,"lenv","requestType","desc");
2192      json_object *res3=json_object_new_array();
2193      int saved_stdout = zDup (fileno (stdout));
2194      zDup2 (fileno (stderr), fileno (stdout));
2195      if (int res0 =             
2196          recursReaddirF (m, NULL, res3, NULL, ntmp, NULL, saved_stdout, 0,
2197                          printGetCapabilitiesForProcessJ) < 0)
2198        {
2199        }     
2200      zDup2 (saved_stdout, fileno (stdout));
2201      zClose(saved_stdout);
2202      res=res3;
2203      //json_object_object_add(res,"processes",res3);
2204    }
2205    else if(strstr(cgiQueryString,"/processes")==NULL && (strstr(cgiQueryString,"/jobs")!=NULL || strstr(cgiQueryString,"/jobs/")!=NULL)){
2206      /* - /jobs url */
2207      fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
2208      fflush(stderr);
2209      if(strncasecmp(cgiRequestMethod,"DELETE",6)==0) {
2210        fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
2211        fflush(stderr);
2212        char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
2213        setMapInMaps(m,"lenv","gs_usid",jobId);
2214        setMapInMaps(m,"lenv","file.statusFile",json_getStatusFilePath(m));
2215        fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
2216        fflush(stderr);
2217        runDismiss(m,jobId);
2218        fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
2219        fflush(stderr);
2220        map* pmError=getMapFromMaps(m,"lenv","error");
2221        if(pmError!=NULL && strncasecmp(pmError->value,"true",4)==0){
2222          printExceptionReportResponseJ(m,getMapFromMaps(m,"lenv","code"));
2223          return 1;
2224        }
2225        else{
2226          setMapInMaps(m,"lenv","gs_location","false");
2227          res=createStatus(m,SERVICE_DISMISSED);
2228        }
2229        fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
2230        fflush(stderr);
2231      }
2232      else if(strcasecmp(cgiRequestMethod,"get")==0){
2233        /* - /jobs List (GET) */
2234        if(strlen(cgiQueryString)<=6)
2235          res=printJobList(m);
2236        else{
2237
2238         
2239          char* tmpUrl=strstr(cgiQueryString,"/jobs/");
2240          if(tmpUrl!=NULL && strlen(tmpUrl)>6){
2241            if(strncasecmp(cgiRequestMethod,"DELETE",6)==0){
2242              char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
2243              setMapInMaps(m,"lenv","gs_usid",jobId);
2244              setMapInMaps(m,"lenv","file.statusFile",json_getStatusFilePath(m));
2245              runDismiss(m,jobId);
2246              map* pmError=getMapFromMaps(m,"lenv","error");
2247              if(pmError!=NULL && strncasecmp(pmError->value,"true",4)==0){
2248                printExceptionReportResponseJ(m,getMapFromMaps(m,"lenv","code"));
2249                return 1;
2250              }
2251              else{
2252                setMapInMaps(m,"lenv","gs_location","false");
2253                res=createStatus(m,SERVICE_DISMISSED);
2254              }
2255            }else{
2256              char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
2257              if(strlen(jobId)==36){
2258                res=printJobStatus(m,jobId);
2259              }else{
2260
2261                // In case the service has run, then forward request to target result file
2262                //char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
2263                jobId[strlen(jobId)-8]=0;
2264                fprintf(stderr,"%s %d %s \n",__FILE__,__LINE__,jobId);
2265                fflush(stderr);
2266                char *sid=getStatusId(m,jobId);
2267                if(sid==NULL){
2268                  fprintf(stderr,"%s %d %s \n",__FILE__,__LINE__,jobId);
2269                  fflush(stderr);
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                  fprintf(stderr,"%s %d %s \n",__FILE__,__LINE__,jobId);
2276                  fflush(stderr);
2277                  if(isRunning(m,jobId)>0){
2278                    map* error=createMap("code","ResultNotReady");
2279                    addToMap(error,"message",_("The job is still running."));
2280                    printExceptionReportResponseJ(m,error);
2281                    return 1;
2282                  }else{
2283                    fprintf(stderr,"%s %d %s \n",__FILE__,__LINE__,jobId);
2284                    fflush(stderr);
2285                    char *Url0=getResultPath(m,jobId);
2286                    fprintf(stderr,"%s %d %s \n",__FILE__,__LINE__,Url0);
2287                    fflush(stderr);
2288                    //map *cIdentifier = getMapFromMaps (m, "lenv", "oIdentifier");
2289                    zStatStruct f_status;
2290                    int s=zStat(Url0, &f_status);
2291                    if(s==0 && f_status.st_size>0){
2292                      fprintf(stderr,"%s %d %s \n",__FILE__,__LINE__,Url0);
2293                      fflush(stderr);
2294                     
2295                      if(f_status.st_size>15){
2296                        json_object* pjoTmp=json_readFile(m,Url0);
2297                        json_object* pjoCode=NULL;
2298                        json_object* pjoMessage=NULL;
2299                        if(pjoTmp!=NULL &&
2300                           json_object_object_get_ex(pjoTmp,"code",&pjoCode)!=FALSE &&
2301                           json_object_object_get_ex(pjoTmp,"description",&pjoMessage)!=FALSE){
2302                          map* error=createMap("code",json_object_get_string(pjoCode));
2303                          addToMap(error,"message",json_object_get_string(pjoMessage));
2304                          printExceptionReportResponseJ(m,error);
2305                          return 1;                     
2306                        }else{
2307
2308                          map* tmpPath = getMapFromMaps (m, "main", "tmpUrl");
2309                          Url0=(char*) realloc(Url0,(strlen(tmpPath->value)+
2310                                                     //strlen(cIdentifier->value)+
2311                                                     strlen(jobId)+8)*sizeof(char));
2312                          sprintf(Url0,"%s/%s.json",tmpPath->value,jobId);
2313                          setMapInMaps(m,"headers","Location",Url0);
2314                        }
2315                        free(Url0);
2316                      }else{
2317                        // Service Failed
2318                        map* statusInfo=createMap("JobID",jobId);
2319                        readFinalRes(m,jobId,statusInfo);
2320                        {
2321                          map* pmStatus=getMap(statusInfo,"status");
2322                          if(pmStatus!=NULL)
2323                            setMapInMaps(m,"lenv","status",pmStatus->value);
2324                        }
2325                        char* tmpStr=_getStatus(m,jobId);
2326                        if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
2327                          char *tmpStr1=zStrdup(tmpStr);
2328                          char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
2329                          free(tmpStr);
2330                          tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
2331                          addToMap(statusInfo,"PercentCompleted",tmpStr1);
2332                          addToMap(statusInfo,"Message",tmpStr0);
2333                          setMapInMaps(m,"lenv","PercentCompleted",tmpStr1);
2334                          setMapInMaps(m,"lenv","Message",tmpStr0);
2335                          free(tmpStr0);
2336                          free(tmpStr1);
2337                        }
2338                        map* error=createMap("code","NoApplicableCode");
2339                        addToMap(error,"message",_("The service failed to execute."));
2340                        printExceptionReportResponseJ(m,error);
2341                        return 1;
2342                      }
2343
2344                    }else{
2345                      map* error=createMap("code","NoSuchJob");
2346                      addToMap(error,"message",_("The JobID seem to be running on this server but not for this process id"));
2347                      printExceptionReportResponseJ(m,error);
2348                      return 1;
2349                    }
2350                  }
2351                }
2352
2353               
2354              }
2355              free(jobId);
2356            }
2357          }
2358        }
2359         
2360      }else if(strcasecmp(cgiRequestMethod,"post")==0 && (strcmp(cgiQueryString,"/jobs")==0 || strcmp(cgiQueryString,"/jobs/")==0)){
2361        /* - /jobs Execution (POST) */
2362        eres = SERVICE_STARTED;
2363        initAllEnvironment(m,request_inputs,ntmp,"jrequest");
2364        map* req=getMapFromMaps(m,"renv","jrequest");
2365        json_object *jobj = NULL;
2366        const char *mystring = NULL;
2367        int slen = 0;
2368        enum json_tokener_error jerr;
2369        struct json_tokener* tok=json_tokener_new();
2370        do {
2371          mystring = req->value;  // get JSON string, e.g. read from file, etc...
2372          slen = strlen(mystring);
2373          jobj = json_tokener_parse_ex(tok, mystring, slen);
2374        } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
2375        if (jerr != json_tokener_success) {
2376          map* pamError=createMap("code","InvalidParameterValue");
2377          const char* pcTmpErr=json_tokener_error_desc(jerr);
2378          const char* pccErr=_("ZOO-Kernel cannot parse your POST data: %s");
2379          char* pacMessage=(char*)malloc((strlen(pcTmpErr)+strlen(pccErr)+1)*sizeof(char));
2380          sprintf(pacMessage,pccErr,pcTmpErr);
2381          addToMap(pamError,"message",pacMessage);
2382          printExceptionReportResponseJ(m,pamError);
2383          fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
2384          return 1;
2385        }
2386        if (tok->char_offset < slen){
2387          map* pamError=createMap("code","InvalidParameterValue");
2388          const char* pcTmpErr="None";
2389          const char* pccErr=_("ZOO-Kernel cannot parse your POST data: %s");
2390          char* pacMessage=(char*)malloc((strlen(pcTmpErr)+strlen(pccErr)+1)*sizeof(char));
2391          sprintf(pacMessage,pccErr,pcTmpErr);
2392          addToMap(pamError,"message",pacMessage);
2393          printExceptionReportResponseJ(m,pamError);
2394          fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
2395          return 1;
2396        }
2397
2398        json_object* json_io=NULL;
2399        char* cIdentifier=NULL;
2400        if(json_object_object_get_ex(jobj,"id",&json_io)!=FALSE){
2401          cIdentifier=zStrdup(json_object_get_string(json_io));
2402        }
2403        fprintf(stderr,"%s %d \n", __FILE__,__LINE__);
2404        fflush(stderr);
2405        fetchService(zooRegistry,m,&s1,request_inputs,ntmp,cIdentifier,printExceptionReportResponseJ);
2406        fprintf(stderr,"%s %d \n", __FILE__,__LINE__);
2407        fflush(stderr); 
2408        //maps* inputs_real_format=NULL, *outputs_real_format= NULL;
2409        parseJRequest(m,s1,jobj,request_inputs,&request_input_real_format,&request_output_real_format);
2410        fprintf(stderr,"%s %d \n", __FILE__,__LINE__);
2411        fflush(stderr); 
2412        map* preference=getMapFromMaps(m,"renv","HTTP_PREFER");
2413        map* mode=getMap(request_inputs,"mode");
2414        if((preference!=NULL && strcasecmp(preference->value,"respond-async")==0) ||
2415           (mode!=NULL && strncasecmp(mode->value,"async",5)==0)) {
2416          int pid;
2417#ifdef DEBUG
2418          fprintf (stderr, "\nPID : %d\n", cpid);
2419#endif
2420#ifndef WIN32
2421          pid = fork ();
2422#else
2423          if (cgiSid == NULL)
2424            {
2425              createProcess (m, request_inputs, s1, NULL, cpid,
2426                             request_input_real_format,
2427                             request_output_real_format);
2428              pid = cpid;
2429            }
2430          else
2431            {
2432              pid = 0;
2433              cpid = atoi (cgiSid);
2434              updateStatus(m,0,_("Initializing"));
2435            }
2436#endif
2437          if (pid > 0)
2438            {
2439              //
2440              // dady :
2441              // set status to SERVICE_ACCEPTED
2442              //
2443#ifdef DEBUG
2444              fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
2445                       zGetpid ());
2446#endif
2447              eres = SERVICE_ACCEPTED;
2448              createStatusFile(m,eres);
2449              //invokeBasicCallback(m,SERVICE_ACCEPTED);
2450              printHeaders(m);
2451              printf("Status: 201 Created \r\n\r\n");
2452              return 1;
2453            }
2454          else if (pid == 0)
2455            {
2456              eres = SERVICE_STARTED;
2457              //
2458              // son : have to close the stdout, stdin and stderr to let the parent
2459              // process answer to http client.
2460              //
2461              map* oid = getMapFromMaps (m, "lenv", "oIdentifier");
2462              map* usid = getMapFromMaps (m, "lenv", "uusid");
2463              map* tmpm = getMapFromMaps (m, "lenv", "osid");
2464              int cpid = atoi (tmpm->value);
2465              pid=cpid;
2466              r_inputs = getMapFromMaps (m, "main", "tmpPath");
2467              setMapInMaps (m, "lenv", "async","true");
2468              map* r_inputs1 = createMap("ServiceName", s1->name);
2469              // Create the filename for the result file (.res)
2470              fbkpres =
2471                (char *)
2472                malloc ((strlen (r_inputs->value) +
2473                         strlen (usid->value) + 7) * sizeof (char));                   
2474              sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
2475              bmap = createMaps("status");
2476              bmap->content=createMap("usid",usid->value);
2477              addToMap(bmap->content,"sid",tmpm->value);
2478              addIntToMap(bmap->content,"pid",zGetpid());
2479         
2480              // Create PID file referencing the OS process identifier
2481              fbkpid =
2482                (char *)
2483                malloc ((strlen (r_inputs->value) +
2484                         strlen (usid->value) + 7) * sizeof (char));
2485              sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
2486              setMapInMaps (m, "lenv", "file.pid", fbkpid);
2487
2488              f0 = freopen (fbkpid, "w+",stdout);
2489              printf("%d",zGetpid());
2490              fflush(stdout);
2491
2492              // Create SID file referencing the semaphore name
2493              fbkp =
2494                (char *)
2495                malloc ((strlen (r_inputs->value) + strlen (oid->value) +
2496                         strlen (usid->value) + 7) * sizeof (char));
2497              sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
2498              setMapInMaps (m, "lenv", "file.sid", fbkp);
2499              FILE* f2 = freopen (fbkp, "w+",stdout);
2500              printf("%s",tmpm->value);
2501              fflush(f2);
2502              free(fbkp);
2503
2504              fbkp =
2505                (char *)
2506                malloc ((strlen (r_inputs->value) + 
2507                         strlen (usid->value) + 7) * sizeof (char));
2508              sprintf (fbkp, "%s/%s.json", r_inputs->value, 
2509                       usid->value);
2510              setMapInMaps (m, "lenv", "file.responseInit", fbkp);
2511              flog =
2512                (char *)
2513                malloc ((strlen (r_inputs->value) + strlen (oid->value) +
2514                         strlen (usid->value) + 13) * sizeof (char));
2515              sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
2516                       oid->value, usid->value);
2517              setMapInMaps (m, "lenv", "file.log", flog);
2518#ifdef DEBUG
2519              fprintf (stderr, "RUN IN BACKGROUND MODE \n");
2520              fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
2521                       zGetpid ());
2522              fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
2523#endif
2524              freopen (flog, "w+", stderr);
2525              fflush (stderr);
2526              f0 = freopen (fbkp, "w+", stdout);
2527              rewind (stdout);
2528#ifndef WIN32
2529              fclose (stdin);
2530#endif
2531#ifdef RELY_ON_DB
2532              init_sql(m);
2533              recordServiceStatus(m);
2534#endif
2535#ifdef USE_CALLBACK
2536              invokeCallback(m,NULL,NULL,0,0);
2537#endif
2538              invokeBasicCallback(m,SERVICE_STARTED);
2539              createStatusFile(m,SERVICE_STARTED);
2540              fbkp1 =
2541                (char *)
2542                malloc ((strlen (r_inputs->value) + strlen (oid->value) +
2543                         strlen (usid->value) + 15) * sizeof (char));
2544              sprintf (fbkp1, "%s/%s_final_%s.json", r_inputs->value,
2545                       oid->value, usid->value);
2546              setMapInMaps (m, "lenv", "file.responseFinal", fbkp1);
2547
2548              f1 = freopen (fbkp1, "w+", stdout);
2549
2550              map* serviceTypeMap=getMap(s1->content,"serviceType");
2551              if(serviceTypeMap!=NULL)
2552                setMapInMaps (m, "lenv", "serviceType", serviceTypeMap->value);
2553
2554              char *flenv =
2555                (char *)
2556                malloc ((strlen (r_inputs->value) + 
2557                         strlen (usid->value) + 12) * sizeof (char));
2558              sprintf (flenv, "%s/%s_lenv.cfg", r_inputs->value, usid->value);
2559              maps* lenvMaps=getMaps(m,"lenv");
2560              dumpMapsToFile(lenvMaps,flenv,1);
2561              free(flenv);
2562
2563              map* testMap=getMapFromMaps(m,"main","memory");
2564              loadHttpRequests(m,request_input_real_format);
2565
2566              if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,NULL)<0)
2567                return -1;
2568              loadServiceAndRun (&m, s1, request_inputs,
2569                                 &request_input_real_format,
2570                                 &request_output_real_format, &eres);
2571              setMapInMaps(m,"lenv","force","true");
2572              createStatusFile(m,eres);
2573              setMapInMaps(m,"lenv","force","false");
2574              setMapInMaps(m,"lenv","no-headers","true");
2575              fflush(stdout);
2576              rewind(stdout);
2577              res=printJResult(m,s1,request_output_real_format,eres);
2578              const char* jsonStr0=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
2579              if(getMapFromMaps(m,"lenv","jsonStr")==NULL)
2580                setMapInMaps(m,"lenv","jsonStr",jsonStr0);
2581              invokeBasicCallback(m,eres);
2582            }
2583        }else{
2584          loadHttpRequests(m,request_input_real_format);
2585          if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,NULL)<0)
2586            return -1;
2587          loadServiceAndRun (&m,s1,request_inputs,
2588                             &request_input_real_format,
2589                             &request_output_real_format,&eres);
2590          res=printJResult(m,s1,request_output_real_format,eres);
2591        }
2592
2593           
2594      }//else error
2595   
2596    }
2597    else{
2598      service* s1=NULL;
2599      int t=0;
2600      if(strstr(cgiQueryString,"/processes/")==NULL){
2601        map* error=createMap("code","BadRequest");
2602        addToMap(error,"message",_("The ressource is not available"));
2603        //setMapInMaps(conf,"lenv","status_code","404 Bad Request");
2604        printExceptionReportResponseJ(m,error);
2605        freeMaps (&m);
2606        free (m);
2607        free (REQUEST);
2608        xmlCleanupParser ();
2609        zooXmlCleanupNs ();                     
2610        return 1;
2611      } else
2612        if(strstr(cgiQueryString,"/jobs")==NULL && strstr(cgiQueryString,"/jobs/")==NULL){
2613          /* - /processes/{id}/ */
2614          //DIR *dirp = opendir (ntmp);
2615          json_object *res3=json_object_new_object();
2616          char *orig = NULL;
2617          orig = zStrdup (strstr(cgiQueryString,"/processes/")+11);
2618          if(orig[strlen(orig)-1]=='/')
2619            orig[strlen(orig)-1]=0;
2620          json_object* res1=json_object_new_object();
2621          setMapInMaps(m,"lenv","requestType","GetCapabilities");
2622          int t=fetchServicesForDescription(NULL, m, orig,
2623                                            printGetCapabilitiesForProcessJ,
2624                                            NULL, (void*) res3, ntmp,
2625                                            request_inputs,
2626                                            printExceptionReportResponseJ);
2627          if(t==1){
2628            /*map* error=createMap("code","BadRequest");
2629              addToMap(error,"message",_("Failed to acces the requested service"));
2630              printExceptionReportResponseJ(m,error);*/
2631            return 1;
2632          }
2633          res=json_object_get(res3);
2634        }else{
2635          char* cIdentifier=NULL;
2636          if(strstr(cgiQueryString,"/processes/")!=NULL){
2637
2638           
2639            int len0=strlen(strstr(cgiQueryString,"/processes/")+11);
2640            int len1=strlen(cgiQueryString)-strlen(strstr(cgiQueryString,"/job"));
2641            cIdentifier=(char*)malloc((len1-10)*sizeof(char));
2642            int cnt=0;
2643            for(int j=11;j<len1;j++){
2644              cIdentifier[cnt]=cgiQueryString[j];
2645              cIdentifier[cnt+1]=0;
2646              cnt++;
2647            }
2648
2649            fprintf(stderr,"%s %d \n", __FILE__,__LINE__);
2650            fflush(stderr);
2651            fetchService(zooRegistry,m,&s1,request_inputs,ntmp,cIdentifier,printExceptionReportResponseJ);
2652            fprintf(stderr,"%s %d \n", __FILE__,__LINE__);
2653            fflush(stderr);     
2654
2655
2656          }
2657
2658         
2659        }
2660
2661    }
2662    map* pmHasPrinted=getMapFromMaps(m,"lenv","hasPrinted");
2663    if(res!=NULL && (pmHasPrinted==NULL || strncasecmp(pmHasPrinted->value,"false",5)==0)){
2664      if(getMapFromMaps(m,"lenv","no-headers")==NULL){
2665        printHeaders(m);
2666        printf("Status: 200 OK \r\n\r\n");
2667      }
2668      const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
2669      printf(jsonStr);
2670      printf("\n");
2671      fflush(stdout);
2672      json_object_put(res);
2673    }
2674    //return 1;
2675#endif
2676  }else{
2677    //
2678    // WPS 1.0.0 and 2.0.0 starts here
2679    //
2680    setMapInMaps(m,"main","executionType","xml");
2681    //Check for minimum inputs
2682    map* version=getMap(request_inputs,"version");
2683    if(version==NULL)
2684      version=getMapFromMaps(m,"main","version");
2685    setMapInMaps(m,"main","rversion",version->value);
2686    int vid=getVersionId(version->value);
2687    if(vid<0)
2688      vid=0;
2689    map* err=NULL;
2690    const char **vvr=(const char**)requests[vid];
2691    checkValidValue(request_inputs,&err,"request",vvr,1);
2692    const char *vvs[]={
2693      "WPS",
2694      NULL
2695    };
2696    if(err!=NULL){
2697      checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
2698      printExceptionReportResponse (m, err);
2699      freeMap(&err);
2700      free(err);
2701      if (count (request_inputs) == 1)
2702        {
2703          freeMap (&request_inputs);
2704          free (request_inputs);
2705        }
2706      freeMaps (&m);
2707      free (m);
2708      return 1;
2709    }
2710    checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
2711
2712    const char *vvv[]={
2713      "1.0.0",
2714      "2.0.0",
2715      NULL
2716    };
2717    r_inputs = getMap (request_inputs, "Request");
2718    if(r_inputs!=NULL)
2719      REQUEST = zStrdup (r_inputs->value);
2720    int reqId=-1;
2721    if (strncasecmp (REQUEST, "GetCapabilities", 15) != 0){
2722      checkValidValue(request_inputs,&err,"version",(const char**)vvv,1);
2723      int j=0;
2724      for(j=0;j<nbSupportedRequests;j++){
2725        if(requests[vid][j]!=NULL && requests[vid][j+1]!=NULL){
2726          if(j<nbReqIdentifier && strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
2727            checkValidValue(request_inputs,&err,"identifier",NULL,1);
2728            reqId=j+1;
2729            break;
2730          }
2731          else
2732            if(j>=nbReqIdentifier && j<nbReqIdentifier+nbReqJob && 
2733               strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
2734              checkValidValue(request_inputs,&err,"jobid",NULL,1);
2735              reqId=j+1;
2736              break;
2737            }
2738        }else
2739          break;
2740      }
2741    }else{
2742      checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
2743      map* version1=getMap(request_inputs,"AcceptVersions");
2744      if(version1!=NULL){
2745        if(strstr(version1->value,schemas[1][0])!=NULL){
2746          addToMap(request_inputs,"version",schemas[1][0]);
2747          setMapInMaps(m,"main","rversion",schemas[1][0]);
2748        }
2749        else{
2750          addToMap(request_inputs,"version",version1->value);
2751          setMapInMaps(m,"main","rversion",version1->value);
2752        }
2753        version=getMap(request_inputs,"version");
2754      }
2755    }
2756    if(err!=NULL){
2757      printExceptionReportResponse (m, err);
2758      freeMap(&err);
2759      free(err);
2760      if (count (request_inputs) == 1)
2761        {
2762          freeMap (&request_inputs);
2763          free (request_inputs);
2764        }
2765      free(REQUEST);
2766      freeMaps (&m);
2767      free (m);
2768      return 1;
2769    }
2770
2771    r_inputs = getMap (request_inputs, "serviceprovider");
2772    if (r_inputs == NULL)
2773      {
2774        addToMap (request_inputs, "serviceprovider", "");
2775      }
2776
2777    map *tmpm = getMapFromMaps (m, "main", "serverAddress");
2778    if (tmpm != NULL)
2779      SERVICE_URL = zStrdup (tmpm->value);
2780    else
2781      SERVICE_URL = zStrdup (DEFAULT_SERVICE_URL);
2782
2783
2784    int scount = 0;
2785#ifdef DEBUG
2786    dumpMap (r_inputs);
2787#endif
2788
2789    if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
2790      {
2791#ifdef DEBUG
2792        dumpMap (r_inputs);
2793#endif
2794        xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
2795        xmlNodePtr n=printGetCapabilitiesHeader(doc,m,(version!=NULL?version->value:"1.0.0"));
2796        /**
2797         * Here we need to close stdout to ensure that unsupported chars
2798         * has been found in the zcfg and then printed on stdout
2799         */
2800        int saved_stdout = zDup (fileno (stdout));
2801        zDup2 (fileno (stderr), fileno (stdout));
2802
2803        maps* imports = getMaps(m, IMPORTSERVICE);
2804        if (imports != NULL) {       
2805          map* zcfg = imports->content;
2806       
2807          while (zcfg != NULL) {
2808            if (zcfg->value != NULL) {
2809              service* svc = (service*) malloc(SERVICE_SIZE);
2810              if (svc == NULL || readServiceFile(m, zcfg->value, &svc, zcfg->name) < 0) {
2811                // pass over silently
2812                zcfg = zcfg->next;
2813                continue;
2814              }
2815              inheritance(zooRegistry, &svc);
2816              printGetCapabilitiesForProcess(zooRegistry, m, doc, n, svc);
2817              freeService(&svc);
2818              free(svc);                             
2819            }
2820            zcfg = zcfg->next;
2821          }           
2822        }
2823
2824        if (int res =             
2825            recursReaddirF (m, zooRegistry, doc, n, conf_dir, NULL, saved_stdout, 0,
2826                            printGetCapabilitiesForProcess) < 0)
2827          {
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 res;
2838          }
2839        fflush (stdout);
2840        zDup2 (saved_stdout, fileno (stdout));
2841#ifdef META_DB
2842        fetchServicesFromDb(zooRegistry,m,doc,n,printGetCapabilitiesForProcess,1);
2843        close_sql(m,0);
2844#endif     
2845        printDocument (m, doc, zGetpid ());
2846        freeMaps (&m);
2847        free (m);
2848        if(zooRegistry!=NULL){
2849          freeRegistry(&zooRegistry);
2850          free(zooRegistry);
2851        }
2852        free (REQUEST);
2853        free (SERVICE_URL);
2854        fflush (stdout);
2855        return 0;
2856      }
2857    else
2858      {
2859        r_inputs = getMap (request_inputs, "JobId");
2860        if(reqId>nbReqIdentifier){
2861          if (strncasecmp (REQUEST, "GetStatus", 9) == 0 ||
2862              strncasecmp (REQUEST, "GetResult", 9) == 0){
2863            runGetStatus(m,r_inputs->value,REQUEST);
2864#ifdef RELY_ON_DB
2865            map* dsNb=getMapFromMaps(m,"lenv","ds_nb");
2866            if(dsNb!=NULL && atoi(dsNb->value)>1)
2867              close_sql(m,1);
2868            close_sql(m,0);
2869#endif
2870         
2871            freeMaps (&m);
2872            free(m);
2873            if(zooRegistry!=NULL){
2874              freeRegistry(&zooRegistry);
2875              free(zooRegistry);
2876            }
2877            free (REQUEST);
2878            free (SERVICE_URL);
2879            return 0;
2880          }
2881          else
2882            if (strncasecmp (REQUEST, "Dismiss", strlen(REQUEST)) == 0){
2883              runDismiss(m,r_inputs->value);
2884              freeMaps (&m);
2885              free (m);
2886              if(zooRegistry!=NULL){
2887                freeRegistry(&zooRegistry);
2888                free(zooRegistry);
2889              }
2890              free (REQUEST);
2891              free (SERVICE_URL);
2892              return 0;
2893           
2894            }
2895          return 0;
2896        }
2897        if(reqId<=nbReqIdentifier){
2898          r_inputs = getMap (request_inputs, "Identifier");
2899
2900          struct dirent *dp;
2901          DIR *dirp = opendir (conf_dir);
2902          if (dirp == NULL)
2903            {
2904              errorException (m, _("The specified path does not exist."),
2905                              "InternalError", NULL);
2906              freeMaps (&m);
2907              free (m);
2908              if(zooRegistry!=NULL){
2909                freeRegistry(&zooRegistry);
2910                free(zooRegistry);
2911              }
2912              free (REQUEST);
2913              free (SERVICE_URL);
2914              return 0;
2915            }
2916          if (strncasecmp (REQUEST, "DescribeProcess", 15) == 0)
2917            {
2918              /**
2919               * Loop over Identifier list
2920               */
2921              xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
2922              r_inputs = NULL;
2923              r_inputs = getMap (request_inputs, "version");
2924#ifdef DEBUG
2925              fprintf(stderr," ** DEBUG %s %d \n",__FILE__,__LINE__);
2926              fflush(stderr);
2927#endif
2928              xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
2929                                            root_nodes[vid][1],(version!=NULL?version->value:"1.0.0"),1);
2930
2931              r_inputs = getMap (request_inputs, "Identifier");
2932
2933              fetchServicesForDescription(zooRegistry, m, r_inputs->value,
2934                                          printDescribeProcessForProcess,
2935                                          (void*) doc, (void*) n, conf_dir,
2936                                          request_inputs,printExceptionReportResponse);
2937
2938              printDocument (m, doc, zGetpid ());
2939              freeMaps (&m);
2940              free (m);
2941              if(zooRegistry!=NULL){
2942                freeRegistry(&zooRegistry);
2943                free(zooRegistry);
2944              }
2945              free (REQUEST);
2946              free (SERVICE_URL);
2947              fflush (stdout);
2948#ifdef META_DB
2949              close_sql(m,0);
2950              //end_sql();
2951#endif
2952              return 0;
2953            }
2954          else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
2955            {
2956              map* version=getMapFromMaps(m,"main","rversion");
2957              int vid=getVersionId(version->value);         
2958              int len = 0;
2959              int j = 0;
2960              for(j=0;j<nbSupportedRequests;j++){
2961                if(requests[vid][j]!=NULL)
2962                  len+=strlen(requests[vid][j])+2;
2963                else{
2964                  len+=4;
2965                  break;
2966                }
2967              }
2968              char *tmpStr=(char*)malloc(len*sizeof(char));
2969              int it=0;
2970              for(j=0;j<nbSupportedRequests;j++){
2971                if(requests[vid][j]!=NULL){
2972                  if(it==0){
2973                    sprintf(tmpStr,"%s",requests[vid][j]);
2974                    it++;
2975                  }else{
2976                    char *tmpS=zStrdup(tmpStr);
2977                    if(j+1<nbSupportedRequests && requests[vid][j+1]==NULL){
2978                      sprintf(tmpStr,"%s and %s",tmpS,requests[vid][j]);
2979                    }else{
2980                      sprintf(tmpStr,"%s, %s",tmpS,requests[vid][j]);
2981                 
2982                    }
2983                    free(tmpS);
2984                  }
2985                }
2986                else{
2987                  len+=4;
2988                  break;
2989                }
2990              }
2991              char* message=(char*)malloc((61+len)*sizeof(char));
2992              sprintf(message,"The <request> value was not recognized. Allowed values are %s.",tmpStr);
2993              errorException (m,_(message),"InvalidParameterValue", "request");
2994#ifdef DEBUG
2995              fprintf (stderr, "No request found %s", REQUEST);
2996#endif
2997              closedir (dirp);
2998              freeMaps (&m);
2999              free (m);
3000              if(zooRegistry!=NULL){
3001                freeRegistry(&zooRegistry);
3002                free(zooRegistry);
3003              }
3004              free (REQUEST);
3005              free (SERVICE_URL);
3006              fflush (stdout);
3007              return 0;
3008            }
3009          closedir (dirp);
3010        }
3011      }
3012
3013    map *postRequest = NULL;
3014    postRequest = getMap (request_inputs, "xrequest");
3015 
3016    if(vid==1 && postRequest==NULL){
3017      errorException (m,_("Unable to run Execute request using the GET HTTP method"),"InvalidParameterValue", "request"); 
3018      freeMaps (&m);
3019      free (m);
3020      if(zooRegistry!=NULL){
3021        freeRegistry(&zooRegistry);
3022        free(zooRegistry);
3023      }
3024      free (REQUEST);
3025      free (SERVICE_URL);
3026      fflush (stdout);
3027      return 0;
3028    }
3029    s1 = NULL;
3030
3031    r_inputs = getMap (request_inputs, "Identifier");
3032
3033    fetchService(zooRegistry,m,&s1,request_inputs,ntmp,r_inputs->value,printExceptionReportResponse);
3034    /*
3035    //*****************
3036    // Fetch S1
3037    //*****************
3038    map* import = getMapFromMaps (m, IMPORTSERVICE, r_inputs->value);
3039    if (import != NULL && import->value != NULL) {
3040      strncpy(tmps1, import->value, 1024);
3041      setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
3042      setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
3043    }
3044    else {
3045      snprintf (tmps1, 1024, "%s/%s.zcfg", conf_dir, r_inputs->value);
3046#ifdef DEBUG
3047      fprintf (stderr, "Trying to load %s\n", tmps1);
3048#endif
3049      if (strstr (r_inputs->value, ".") != NULL)
3050        {
3051          char *identifier = zStrdup (r_inputs->value);
3052          parseIdentifier (m, conf_dir, identifier, tmps1);
3053          map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
3054          if (tmpMap != NULL)
3055            addToMap (request_inputs, "metapath", tmpMap->value);
3056          free (identifier);
3057        }
3058      else
3059        {
3060          setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
3061          setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
3062        }
3063    }
3064
3065    r_inputs = getMapFromMaps (m, "lenv", "Identifier");
3066 
3067#ifdef META_DB
3068    int metadb_id=_init_sql(m,"metadb");
3069    //FAILED CONNECTING DB
3070    if(getMapFromMaps(m,"lenv","dbIssue")!=NULL || metadb_id<0){
3071      fprintf(stderr,"ERROR CONNECTING METADB\n");
3072    }
3073    if(metadb_id>=0)
3074      s1=extractServiceFromDb(m,r_inputs->value,0);
3075    //close_sql(m,0);
3076    if(s1!=NULL){
3077      inheritance(zooRegistry,&s1);
3078#ifdef USE_HPC
3079      addNestedOutputs(&s1);
3080#endif
3081      if(zooRegistry!=NULL){
3082        freeRegistry(&zooRegistry);
3083        free(zooRegistry);
3084      }
3085    }else /* Not found in MetaDB /{
3086#endif
3087      s1 = createService();
3088      if (s1 == NULL)
3089        {
3090          freeMaps (&m);
3091          free (m);
3092          if(zooRegistry!=NULL){
3093            freeRegistry(&zooRegistry);
3094            free(zooRegistry);
3095          }
3096          free (REQUEST);
3097          free (SERVICE_URL);
3098          return errorException (m, _("Unable to allocate memory"),
3099                                 "InternalError", NULL);
3100        }
3101
3102      int saved_stdout = zDup (fileno (stdout));
3103      zDup2 (fileno (stderr), fileno (stdout));
3104      t = readServiceFile (m, tmps1, &s1, r_inputs->value);
3105      if(t>=0){
3106        inheritance(zooRegistry,&s1);
3107#ifdef USE_HPC
3108        addNestedOutputs(&s1);
3109#endif
3110      }
3111      if(zooRegistry!=NULL){
3112        freeRegistry(&zooRegistry);
3113        free(zooRegistry);
3114      }
3115      fflush (stdout);
3116      zDup2 (saved_stdout, fileno (stdout));
3117      if (t < 0)
3118        {
3119          char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
3120          sprintf (tmpMsg,
3121                   _
3122                   ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
3123                   r_inputs->value);
3124          errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
3125          free (tmpMsg);
3126          free (s1);
3127          freeMaps (&m);
3128          free (m);
3129          free (REQUEST);
3130          free (SERVICE_URL);
3131          return 0;
3132        }
3133      zClose (saved_stdout);
3134#ifdef META_DB
3135    }
3136#endif
3137    //*****************
3138    // End Fetch S1
3139    //*****************
3140*/
3141 
3142#ifdef DEBUG
3143    dumpService (s1);
3144#endif
3145    int j;
3146
3147
3148    /**
3149     * Create the input and output maps data structure
3150     */
3151    int i = 0;
3152    HINTERNET res;
3153    hInternet = InternetOpen (
3154#ifndef WIN32
3155                              (LPCTSTR)
3156#endif
3157                              "ZooWPSClient\0",
3158                              INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
3159
3160#ifndef WIN32
3161    if (!CHECK_INET_HANDLE (hInternet))
3162      fprintf (stderr, "WARNING : hInternet handle failed to initialize");
3163#endif
3164    maps *tmpmaps = request_input_real_format;
3165
3166    if(parseRequest(&m,&request_inputs,s1,&request_input_real_format,&request_output_real_format,&hInternet)<0){
3167      freeMaps (&m);
3168      free (m);
3169      free (REQUEST);
3170      free (SERVICE_URL);
3171      InternetCloseHandle (&hInternet);
3172      freeService (&s1);
3173      free (s1);
3174      return 0;
3175    }
3176    //InternetCloseHandle (&hInternet);
3177
3178    initAllEnvironment(m,request_inputs,ntmp,"xrequest");
3179
3180
3181#ifdef DEBUG
3182    dumpMap (request_inputs);
3183#endif
3184
3185    map *status = getMap (request_inputs, "status");
3186    if(vid==0){
3187      // Need to check if we need to fork to load a status enabled
3188      r_inputs = NULL;
3189      map *store = getMap (request_inputs, "storeExecuteResponse");
3190      /**
3191       * 05-007r7 WPS 1.0.0 page 57 :
3192       * 'If status="true" and storeExecuteResponse is "false" then the service
3193       * shall raise an exception.'
3194       */
3195      if (status != NULL && strcmp (status->value, "true") == 0 &&
3196          store != NULL && strcmp (store->value, "false") == 0)
3197        {
3198          errorException (m,
3199                          _
3200                          ("The status parameter cannot be set to true if storeExecuteResponse is set to false. Please modify your request parameters."),
3201                          "InvalidParameterValue", "storeExecuteResponse");
3202          freeService (&s1);
3203          free (s1);
3204          freeMaps (&m);
3205          free (m);
3206       
3207          freeMaps (&request_input_real_format);
3208          free (request_input_real_format);
3209       
3210          freeMaps (&request_output_real_format);
3211          free (request_output_real_format);
3212
3213          free (REQUEST);
3214          free (SERVICE_URL);
3215          return 1;
3216        }
3217      r_inputs = getMap (request_inputs, "storeExecuteResponse");
3218    }else{
3219      // Define status depending on the WPS 2.0.0 mode attribute
3220      status = getMap (request_inputs, "mode");
3221      map* mode=getMap(s1->content,"mode");
3222      if(strcasecmp(status->value,"async")==0){
3223        if(mode!=NULL && strcasecmp(mode->value,"async")==0)
3224          addToMap(request_inputs,"status","true");
3225        else{
3226          if(mode!=NULL){
3227            // see ref. http://docs.opengeospatial.org/is/14-065/14-065.html#61
3228            errorException (m,_("The process does not permit the desired execution mode."),"NoSuchMode", mode->value); 
3229            fflush (stdout);
3230            freeMaps (&m);
3231            free (m);
3232            if(zooRegistry!=NULL){
3233              freeRegistry(&zooRegistry);
3234              free(zooRegistry);
3235            }
3236            freeMaps (&request_input_real_format);
3237            free (request_input_real_format);
3238            freeMaps (&request_output_real_format);
3239            free (request_output_real_format);
3240            free (REQUEST);
3241            free (SERVICE_URL);
3242            return 0;
3243          }else
3244            addToMap(request_inputs,"status","true");
3245        }
3246      }
3247      else{
3248        if(strcasecmp(status->value,"auto")==0){
3249          if(mode!=NULL){
3250            if(strcasecmp(mode->value,"async")==0)
3251              addToMap(request_inputs,"status","false");
3252            else
3253              addToMap(request_inputs,"status","true");
3254          }
3255          else
3256            addToMap(request_inputs,"status","false");
3257        }else
3258          addToMap(request_inputs,"status","false");
3259      }
3260      status = getMap (request_inputs, "status");
3261    }
3262
3263    if (status != NULL)
3264      if (strcasecmp (status->value, "false") == 0)
3265        status = NULLMAP;
3266    if (status == NULLMAP)
3267      {
3268        if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
3269          freeService (&s1);
3270          free (s1);
3271          freeMaps (&m);
3272          free (m);
3273          free (REQUEST);
3274          free (SERVICE_URL);
3275          freeMaps (&request_input_real_format);
3276          free (request_input_real_format);
3277          freeMaps (&request_output_real_format);
3278          free (request_output_real_format);
3279          freeMaps (&tmpmaps);
3280          free (tmpmaps);
3281          return -1;
3282        }
3283        map* testMap=getMapFromMaps(m,"main","memory");
3284        if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
3285          dumpMapsValuesToFiles(&m,&request_input_real_format);
3286        loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
3287                           &request_output_real_format, &eres);   
3288
3289#ifdef META_DB
3290        close_sql(m,0);     
3291#endif     
3292      }
3293    else
3294      {
3295        int pid;
3296#ifdef DEBUG
3297        fprintf (stderr, "\nPID : %d\n", cpid);
3298#endif
3299#ifndef WIN32
3300        pid = fork ();
3301#else
3302        if (cgiSid == NULL)
3303          {
3304            createProcess (m, request_inputs, s1, NULL, cpid,
3305                           request_input_real_format,
3306                           request_output_real_format);
3307            pid = cpid;
3308          }
3309        else
3310          {
3311            pid = 0;
3312            cpid = atoi (cgiSid);
3313            updateStatus(m,0,_("Initializing"));
3314          }
3315#endif
3316        if (pid > 0)
3317          {
3318            //
3319            // dady :
3320            // set status to SERVICE_ACCEPTED
3321            //
3322#ifdef DEBUG
3323            fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
3324                     zGetpid ());
3325#endif
3326            eres = SERVICE_ACCEPTED;
3327          }
3328        else if (pid == 0)
3329          {
3330            eres = SERVICE_ACCEPTED;
3331            //
3332            // son : have to close the stdout, stdin and stderr to let the parent
3333            // process answer to http client.
3334            //
3335            map* usid = getMapFromMaps (m, "lenv", "uusid");
3336            map* tmpm = getMapFromMaps (m, "lenv", "osid");
3337            int cpid = atoi (tmpm->value);
3338            pid=cpid;
3339            r_inputs = getMapFromMaps (m, "main", "tmpPath");
3340            setMapInMaps (m, "lenv", "async","true");
3341            map* r_inputs1 = createMap("ServiceName", s1->name);
3342
3343            // Create the filename for the result file (.res)
3344            fbkpres =
3345              (char *)
3346              malloc ((strlen (r_inputs->value) +
3347                       strlen (usid->value) + 7) * sizeof (char));                   
3348            sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
3349            bmap = createMaps("status");
3350            bmap->content=createMap("usid",usid->value);
3351            addToMap(bmap->content,"sid",tmpm->value);
3352            addIntToMap(bmap->content,"pid",zGetpid());
3353         
3354            // Create PID file referencing the OS process identifier
3355            fbkpid =
3356              (char *)
3357              malloc ((strlen (r_inputs->value) +
3358                       strlen (usid->value) + 7) * sizeof (char));
3359            sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
3360            setMapInMaps (m, "lenv", "file.pid", fbkpid);
3361
3362            f0 = freopen (fbkpid, "w+",stdout);
3363            printf("%d",zGetpid());
3364            fflush(stdout);
3365
3366            // Create SID file referencing the semaphore name
3367            fbkp =
3368              (char *)
3369              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3370                       strlen (usid->value) + 7) * sizeof (char));
3371            sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
3372            setMapInMaps (m, "lenv", "file.sid", fbkp);
3373            FILE* f2 = freopen (fbkp, "w+",stdout);
3374            printf("%s",tmpm->value);
3375            fflush(f2);
3376            free(fbkp);
3377
3378            fbkp =
3379              (char *)
3380              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3381                       strlen (usid->value) + 7) * sizeof (char));
3382            sprintf (fbkp, "%s/%s_%s.xml", r_inputs->value, r_inputs1->value,
3383                     usid->value);
3384            setMapInMaps (m, "lenv", "file.responseInit", fbkp);
3385            flog =
3386              (char *)
3387              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3388                       strlen (usid->value) + 13) * sizeof (char));
3389            sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
3390                     r_inputs1->value, usid->value);
3391            setMapInMaps (m, "lenv", "file.log", flog);
3392#ifdef DEBUG
3393            fprintf (stderr, "RUN IN BACKGROUND MODE \n");
3394            fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
3395                     zGetpid ());
3396            fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
3397#endif
3398            freopen (flog, "w+", stderr);
3399            fflush (stderr);
3400            f0 = freopen (fbkp, "w+", stdout);
3401            rewind (stdout);
3402#ifndef WIN32
3403            fclose (stdin);
3404#endif
3405#ifdef RELY_ON_DB
3406            init_sql(m);
3407            recordServiceStatus(m);
3408#endif
3409#ifdef USE_CALLBACK
3410            invokeCallback(m,NULL,NULL,0,0);
3411#endif
3412            if(vid==0){
3413              //
3414              // set status to SERVICE_STARTED and flush stdout to ensure full
3415              // content was outputed (the file used to store the ResponseDocument).
3416              // Then, rewind stdout to restart writing from the begining of the file.
3417              // This way, the data will be updated at the end of the process run.
3418              //
3419              printProcessResponse (m, request_inputs, cpid, s1, r_inputs1->value,
3420                                    SERVICE_STARTED, request_input_real_format,
3421                                    request_output_real_format);
3422              fflush (stdout);
3423#ifdef RELY_ON_DB
3424              recordResponse(m,fbkp);
3425#endif
3426            }
3427
3428            fflush (stderr);
3429
3430            fbkp1 =
3431              (char *)
3432              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3433                       strlen (usid->value) + 13) * sizeof (char));
3434            sprintf (fbkp1, "%s/%s_final_%s.xml", r_inputs->value,
3435                     r_inputs1->value, usid->value);
3436            setMapInMaps (m, "lenv", "file.responseFinal", fbkp1);
3437
3438            f1 = freopen (fbkp1, "w+", stdout);
3439
3440            map* serviceTypeMap=getMap(s1->content,"serviceType");
3441            if(serviceTypeMap!=NULL)
3442              setMapInMaps (m, "lenv", "serviceType", serviceTypeMap->value);
3443
3444            char *flenv =
3445              (char *)
3446              malloc ((strlen (r_inputs->value) + 
3447                       strlen (usid->value) + 12) * sizeof (char));
3448            sprintf (flenv, "%s/%s_lenv.cfg", r_inputs->value, usid->value);
3449            maps* lenvMaps=getMaps(m,"lenv");
3450            dumpMapsToFile(lenvMaps,flenv,0);
3451            free(flenv);
3452
3453#ifdef USE_CALLBACK
3454            invokeCallback(m,request_input_real_format,NULL,1,0);
3455#endif
3456            if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
3457              freeService (&s1);
3458              free (s1);
3459              fflush (stdout);
3460              fflush (stderr);
3461              fclose (f0);
3462              fclose (f1);
3463              if(dumpBackFinalFile(m,fbkp,fbkp1)<0)
3464                return -1;
3465#ifndef RELY_ON_DB
3466              dumpMapsToFile(bmap,fbkpres,1);
3467              removeShmLock (m, 1);
3468#else
3469              recordResponse(m,fbkp1);
3470#ifdef USE_CALLBACK
3471              invokeCallback(m,NULL,NULL,7,0);
3472#endif
3473#endif
3474              zUnlink (fbkpid);
3475              unhandleStatus (m);
3476#ifdef RELY_ON_DB
3477#ifdef META_DB
3478              cleanupCallbackThreads();
3479              close_sql(m,1);
3480#endif
3481              close_sql(m,0);
3482#endif
3483              freeMaps (&m);
3484              free (m);
3485              free (REQUEST);
3486              free (SERVICE_URL);
3487              freeMaps (&request_input_real_format);
3488              free (request_input_real_format);
3489              freeMaps (&request_output_real_format);
3490              free (request_output_real_format);
3491              freeMaps (&tmpmaps);
3492              free (tmpmaps);
3493              return -1;
3494            }
3495            if(getMapFromMaps(m,"lenv","mapError")!=NULL){
3496              setMapInMaps(m,"lenv","message",_("Issue with geographic data"));
3497#ifdef USE_CALLBACK
3498              invokeCallback(m,NULL,NULL,7,0);
3499#endif
3500              eres=-1;//SERVICE_FAILED;
3501            }else{
3502              map* testMap=getMapFromMaps(m,"main","memory");
3503              if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
3504                dumpMapsValuesToFiles(&m,&request_input_real_format);
3505              loadServiceAndRun (&m, s1, request_inputs,
3506                                 &request_input_real_format,
3507                                 &request_output_real_format, &eres);
3508            }
3509          }
3510        else
3511          {
3512            /**
3513             * error server don't accept the process need to output a valid
3514             * error response here !!!
3515             */
3516            eres = -1;
3517            errorException (m, _("Unable to run the child process properly"),
3518                            "InternalError", NULL);
3519          }
3520      }
3521       
3522#ifdef DEBUG
3523    fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
3524    dumpMaps (request_output_real_format);
3525    fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
3526#endif
3527    fflush(stdout);
3528    rewind(stdout);
3529
3530    if (eres != -1)
3531      outputResponse (s1, request_input_real_format,
3532                      request_output_real_format, request_inputs,
3533                      cpid, m, eres);
3534    fflush (stdout);
3535  }
3536  /**
3537   * Ensure that if error occurs when freeing memory, no signal will return
3538   * an ExceptionReport document as the result was already returned to the
3539   * client.
3540   */
3541#ifndef USE_GDB
3542  signal (SIGSEGV, donothing);
3543  signal (SIGTERM, donothing);
3544  signal (SIGINT, donothing);
3545  signal (SIGILL, donothing);
3546  signal (SIGFPE, donothing);
3547  signal (SIGABRT, donothing);
3548#endif
3549
3550  if (((int) zGetpid ()) != cpid || cgiSid != NULL)
3551    {
3552      if (eres == SERVICE_SUCCEEDED)
3553#ifdef USE_CALLBACK
3554        invokeCallback(m,NULL,request_output_real_format,5,1);
3555#endif
3556      fflush(stderr);
3557      fflush(stdout);
3558
3559      fclose (stdout);
3560
3561      fclose (f0);
3562
3563      fclose (f1);
3564
3565      if(dumpBackFinalFile(m,fbkp,fbkp1)<0)
3566        return -1;
3567      zUnlink (fbkpid);
3568      switch(eres){
3569      default:
3570      case SERVICE_FAILED:
3571        setMapInMaps(bmap,"status","status",wpsStatus[1]);
3572        setMapInMaps(m,"lenv","fstate",wpsStatus[1]);
3573        break;
3574      case SERVICE_SUCCEEDED:
3575        setMapInMaps(bmap,"status","status",wpsStatus[0]);
3576        setMapInMaps(m,"lenv","fstate",wpsStatus[0]);
3577        break;
3578      }     
3579#ifndef RELY_ON_DB
3580      dumpMapsToFile(bmap,fbkpres,1);
3581      removeShmLock (m, 1);
3582#else
3583      recordResponse(m,fbkp1);
3584#ifdef USE_CALLBACK
3585      if (eres == SERVICE_SUCCEEDED)
3586        invokeCallback(m,NULL,request_output_real_format,6,0);
3587#endif
3588#endif
3589      freeMaps(&bmap);
3590      free(bmap);
3591      zUnlink (fbkp1);
3592      unhandleStatus (m);
3593#if defined(USE_JSON) || defined(USE_CALLBACK)
3594      cleanupCallbackThreads();
3595#endif
3596
3597#ifdef RELY_ON_DB
3598#ifdef META_DB
3599      close_sql(m,1);
3600#endif
3601      close_sql(m,0);
3602      end_sql();
3603#endif
3604      free(fbkpid);
3605      free(fbkpres);
3606      free (fbkp1);
3607      if(cgiSid!=NULL)
3608        free(cgiSid);
3609      map* tMap=getMapFromMaps(m,"main","executionType");
3610      if(tMap!=NULL && strncasecmp(tMap->value,"xml",3)==0)
3611        InternetCloseHandle (&hInternet);
3612      fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
3613      fflush(stderr);
3614      fclose (stderr);
3615      zUnlink (flog);
3616      free (flog);
3617    }
3618  else{
3619    //InternetCloseHandle (&hInternet); 
3620#ifdef META_DB
3621    close_sql(m,0);
3622#endif
3623  }
3624
3625  if(s1!=NULL){
3626    freeService (&s1);
3627    free (s1);
3628  }
3629  freeMaps (&m);
3630  free (m);
3631
3632  freeMaps (&request_input_real_format);
3633  free (request_input_real_format);
3634
3635  freeMaps (&request_output_real_format);
3636  free (request_output_real_format);
3637
3638  free (REQUEST);
3639  free (SERVICE_URL);
3640
3641#ifdef DEBUG
3642  fprintf (stderr, "Processed response \n");
3643  fflush (stdout);
3644  fflush (stderr);
3645#endif
3646
3647  if (((int) zGetpid ()) != cpid || cgiSid != NULL)
3648    {
3649      exit (0);
3650    }
3651
3652  return 0;
3653}
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

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

Become a sponsor !

Knowledge partners

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

Become a knowledge partner

Related links

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