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

Last change on this file since 984 was 984, checked in by djay, 4 years ago

Take into account building ZOO-Project on ubuntu focal (cf. https://trac.osgeo.org/osgeolive/ticket/2282). Add the OTB and SAGA support to the Dockerfile to make the corresponding demos using docker WPS server. Add OGC API - Processes demo to the demos list.

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