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

Last change on this file since 973 was 973, checked in by djay, 12 months ago

Include caching.h on win32 or when json is activated and define loadHttpRequests when json is activated.

  • 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#ifdef 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;
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    }
2555    //return 1;
2556#endif
2557  }else{
2558    //
2559    // WPS 1.0.0 and 2.0.0 starts here
2560    //
2561    setMapInMaps(m,"main","executionType","xml");
2562    //Check for minimum inputs
2563    map* version=getMap(request_inputs,"version");
2564    if(version==NULL)
2565      version=getMapFromMaps(m,"main","version");
2566    setMapInMaps(m,"main","rversion",version->value);
2567    int vid=getVersionId(version->value);
2568    if(vid<0)
2569      vid=0;
2570    map* err=NULL;
2571    const char **vvr=(const char**)requests[vid];
2572    checkValidValue(request_inputs,&err,"request",vvr,1);
2573    const char *vvs[]={
2574      "WPS",
2575      NULL
2576    };
2577    if(err!=NULL){
2578      checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
2579      printExceptionReportResponse (m, err);
2580      freeMap(&err);
2581      free(err);
2582      if (count (request_inputs) == 1)
2583        {
2584          freeMap (&request_inputs);
2585          free (request_inputs);
2586        }
2587      freeMaps (&m);
2588      free (m);
2589      return 1;
2590    }
2591    checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
2592
2593    const char *vvv[]={
2594      "1.0.0",
2595      "2.0.0",
2596      NULL
2597    };
2598    r_inputs = getMap (request_inputs, "Request");
2599    if(r_inputs!=NULL)
2600      REQUEST = zStrdup (r_inputs->value);
2601    int reqId=-1;
2602    if (strncasecmp (REQUEST, "GetCapabilities", 15) != 0){
2603      checkValidValue(request_inputs,&err,"version",(const char**)vvv,1);
2604      int j=0;
2605      for(j=0;j<nbSupportedRequests;j++){
2606        if(requests[vid][j]!=NULL && requests[vid][j+1]!=NULL){
2607          if(j<nbReqIdentifier && strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
2608            checkValidValue(request_inputs,&err,"identifier",NULL,1);
2609            reqId=j+1;
2610            break;
2611          }
2612          else
2613            if(j>=nbReqIdentifier && j<nbReqIdentifier+nbReqJob && 
2614               strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
2615              checkValidValue(request_inputs,&err,"jobid",NULL,1);
2616              reqId=j+1;
2617              break;
2618            }
2619        }else
2620          break;
2621      }
2622    }else{
2623      checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
2624      map* version1=getMap(request_inputs,"AcceptVersions");
2625      if(version1!=NULL){
2626        if(strstr(version1->value,schemas[1][0])!=NULL){
2627          addToMap(request_inputs,"version",schemas[1][0]);
2628          setMapInMaps(m,"main","rversion",schemas[1][0]);
2629        }
2630        else{
2631          addToMap(request_inputs,"version",version1->value);
2632          setMapInMaps(m,"main","rversion",version1->value);
2633        }
2634        version=getMap(request_inputs,"version");
2635      }
2636    }
2637    if(err!=NULL){
2638      printExceptionReportResponse (m, err);
2639      freeMap(&err);
2640      free(err);
2641      if (count (request_inputs) == 1)
2642        {
2643          freeMap (&request_inputs);
2644          free (request_inputs);
2645        }
2646      free(REQUEST);
2647      freeMaps (&m);
2648      free (m);
2649      return 1;
2650    }
2651
2652    r_inputs = getMap (request_inputs, "serviceprovider");
2653    if (r_inputs == NULL)
2654      {
2655        addToMap (request_inputs, "serviceprovider", "");
2656      }
2657
2658    map *tmpm = getMapFromMaps (m, "main", "serverAddress");
2659    if (tmpm != NULL)
2660      SERVICE_URL = zStrdup (tmpm->value);
2661    else
2662      SERVICE_URL = zStrdup (DEFAULT_SERVICE_URL);
2663
2664
2665    int scount = 0;
2666#ifdef DEBUG
2667    dumpMap (r_inputs);
2668#endif
2669
2670    if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
2671      {
2672#ifdef DEBUG
2673        dumpMap (r_inputs);
2674#endif
2675        xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
2676        xmlNodePtr n=printGetCapabilitiesHeader(doc,m,(version!=NULL?version->value:"1.0.0"));
2677        /**
2678         * Here we need to close stdout to ensure that unsupported chars
2679         * has been found in the zcfg and then printed on stdout
2680         */
2681        int saved_stdout = zDup (fileno (stdout));
2682        zDup2 (fileno (stderr), fileno (stdout));
2683
2684        maps* imports = getMaps(m, IMPORTSERVICE);
2685        if (imports != NULL) {       
2686          map* zcfg = imports->content;
2687       
2688          while (zcfg != NULL) {
2689            if (zcfg->value != NULL) {
2690              service* svc = (service*) malloc(SERVICE_SIZE);
2691              if (svc == NULL || readServiceFile(m, zcfg->value, &svc, zcfg->name) < 0) {
2692                // pass over silently
2693                zcfg = zcfg->next;
2694                continue;
2695              }
2696              inheritance(zooRegistry, &svc);
2697              printGetCapabilitiesForProcess(zooRegistry, m, doc, n, svc);
2698              freeService(&svc);
2699              free(svc);                             
2700            }
2701            zcfg = zcfg->next;
2702          }           
2703        }
2704
2705        if (int res =             
2706            recursReaddirF (m, zooRegistry, doc, n, conf_dir, NULL, saved_stdout, 0,
2707                            printGetCapabilitiesForProcess) < 0)
2708          {
2709            freeMaps (&m);
2710            free (m);
2711            if(zooRegistry!=NULL){
2712              freeRegistry(&zooRegistry);
2713              free(zooRegistry);
2714            }
2715            free (REQUEST);
2716            free (SERVICE_URL);
2717            fflush (stdout);
2718            return res;
2719          }
2720        fflush (stdout);
2721        zDup2 (saved_stdout, fileno (stdout));
2722#ifdef META_DB
2723        fetchServicesFromDb(zooRegistry,m,doc,n,printGetCapabilitiesForProcess,1);
2724        close_sql(m,0);
2725#endif     
2726        printDocument (m, doc, zGetpid ());
2727        freeMaps (&m);
2728        free (m);
2729        if(zooRegistry!=NULL){
2730          freeRegistry(&zooRegistry);
2731          free(zooRegistry);
2732        }
2733        free (REQUEST);
2734        free (SERVICE_URL);
2735        fflush (stdout);
2736        return 0;
2737      }
2738    else
2739      {
2740        r_inputs = getMap (request_inputs, "JobId");
2741        if(reqId>nbReqIdentifier){
2742          if (strncasecmp (REQUEST, "GetStatus", 9) == 0 ||
2743              strncasecmp (REQUEST, "GetResult", 9) == 0){
2744            runGetStatus(m,r_inputs->value,REQUEST);
2745#ifdef RELY_ON_DB
2746            map* dsNb=getMapFromMaps(m,"lenv","ds_nb");
2747            if(dsNb!=NULL && atoi(dsNb->value)>1)
2748              close_sql(m,1);
2749            close_sql(m,0);
2750#endif
2751         
2752            freeMaps (&m);
2753            free(m);
2754            if(zooRegistry!=NULL){
2755              freeRegistry(&zooRegistry);
2756              free(zooRegistry);
2757            }
2758            free (REQUEST);
2759            free (SERVICE_URL);
2760            return 0;
2761          }
2762          else
2763            if (strncasecmp (REQUEST, "Dismiss", strlen(REQUEST)) == 0){
2764              runDismiss(m,r_inputs->value);
2765              freeMaps (&m);
2766              free (m);
2767              if(zooRegistry!=NULL){
2768                freeRegistry(&zooRegistry);
2769                free(zooRegistry);
2770              }
2771              free (REQUEST);
2772              free (SERVICE_URL);
2773              return 0;
2774           
2775            }
2776          return 0;
2777        }
2778        if(reqId<=nbReqIdentifier){
2779          r_inputs = getMap (request_inputs, "Identifier");
2780
2781          struct dirent *dp;
2782          DIR *dirp = opendir (conf_dir);
2783          if (dirp == NULL)
2784            {
2785              errorException (m, _("The specified path does not exist."),
2786                              "InternalError", NULL);
2787              freeMaps (&m);
2788              free (m);
2789              if(zooRegistry!=NULL){
2790                freeRegistry(&zooRegistry);
2791                free(zooRegistry);
2792              }
2793              free (REQUEST);
2794              free (SERVICE_URL);
2795              return 0;
2796            }
2797          if (strncasecmp (REQUEST, "DescribeProcess", 15) == 0)
2798            {
2799              /**
2800               * Loop over Identifier list
2801               */
2802              xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
2803              r_inputs = NULL;
2804              r_inputs = getMap (request_inputs, "version");
2805#ifdef DEBUG
2806              fprintf(stderr," ** DEBUG %s %d \n",__FILE__,__LINE__);
2807              fflush(stderr);
2808#endif
2809              xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
2810                                            root_nodes[vid][1],(version!=NULL?version->value:"1.0.0"),1);
2811
2812              r_inputs = getMap (request_inputs, "Identifier");
2813
2814              fetchServicesForDescription(zooRegistry, m, r_inputs->value,
2815                                          printDescribeProcessForProcess,
2816                                          (void*) doc, (void*) n, conf_dir,
2817                                          request_inputs,printExceptionReportResponse);
2818
2819              printDocument (m, doc, zGetpid ());
2820              freeMaps (&m);
2821              free (m);
2822              if(zooRegistry!=NULL){
2823                freeRegistry(&zooRegistry);
2824                free(zooRegistry);
2825              }
2826              free (REQUEST);
2827              free (SERVICE_URL);
2828              fflush (stdout);
2829#ifdef META_DB
2830              close_sql(m,0);
2831              //end_sql();
2832#endif
2833              return 0;
2834            }
2835          else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
2836            {
2837              map* version=getMapFromMaps(m,"main","rversion");
2838              int vid=getVersionId(version->value);         
2839              int len = 0;
2840              int j = 0;
2841              for(j=0;j<nbSupportedRequests;j++){
2842                if(requests[vid][j]!=NULL)
2843                  len+=strlen(requests[vid][j])+2;
2844                else{
2845                  len+=4;
2846                  break;
2847                }
2848              }
2849              char *tmpStr=(char*)malloc(len*sizeof(char));
2850              int it=0;
2851              for(j=0;j<nbSupportedRequests;j++){
2852                if(requests[vid][j]!=NULL){
2853                  if(it==0){
2854                    sprintf(tmpStr,"%s",requests[vid][j]);
2855                    it++;
2856                  }else{
2857                    char *tmpS=zStrdup(tmpStr);
2858                    if(j+1<nbSupportedRequests && requests[vid][j+1]==NULL){
2859                      sprintf(tmpStr,"%s and %s",tmpS,requests[vid][j]);
2860                    }else{
2861                      sprintf(tmpStr,"%s, %s",tmpS,requests[vid][j]);
2862                 
2863                    }
2864                    free(tmpS);
2865                  }
2866                }
2867                else{
2868                  len+=4;
2869                  break;
2870                }
2871              }
2872              char* message=(char*)malloc((61+len)*sizeof(char));
2873              sprintf(message,"The <request> value was not recognized. Allowed values are %s.",tmpStr);
2874              errorException (m,_(message),"InvalidParameterValue", "request");
2875#ifdef DEBUG
2876              fprintf (stderr, "No request found %s", REQUEST);
2877#endif
2878              closedir (dirp);
2879              freeMaps (&m);
2880              free (m);
2881              if(zooRegistry!=NULL){
2882                freeRegistry(&zooRegistry);
2883                free(zooRegistry);
2884              }
2885              free (REQUEST);
2886              free (SERVICE_URL);
2887              fflush (stdout);
2888              return 0;
2889            }
2890          closedir (dirp);
2891        }
2892      }
2893
2894    map *postRequest = NULL;
2895    postRequest = getMap (request_inputs, "xrequest");
2896 
2897    if(vid==1 && postRequest==NULL){
2898      errorException (m,_("Unable to run Execute request using the GET HTTP method"),"InvalidParameterValue", "request"); 
2899      freeMaps (&m);
2900      free (m);
2901      if(zooRegistry!=NULL){
2902        freeRegistry(&zooRegistry);
2903        free(zooRegistry);
2904      }
2905      free (REQUEST);
2906      free (SERVICE_URL);
2907      fflush (stdout);
2908      return 0;
2909    }
2910    s1 = NULL;
2911 
2912    r_inputs = getMap (request_inputs, "Identifier");
2913    map* import = getMapFromMaps (m, IMPORTSERVICE, r_inputs->value); 
2914    if (import != NULL && import->value != NULL) { 
2915      strncpy(tmps1, import->value, 1024);
2916      setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
2917      setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
2918    } 
2919    else {
2920      snprintf (tmps1, 1024, "%s/%s.zcfg", conf_dir, r_inputs->value);
2921#ifdef DEBUG
2922      fprintf (stderr, "Trying to load %s\n", tmps1);
2923#endif
2924      if (strstr (r_inputs->value, ".") != NULL)
2925        {
2926          char *identifier = zStrdup (r_inputs->value);
2927          parseIdentifier (m, conf_dir, identifier, tmps1);
2928          map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
2929          if (tmpMap != NULL)
2930            addToMap (request_inputs, "metapath", tmpMap->value);
2931          free (identifier);
2932        }
2933      else
2934        {
2935          setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
2936          setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
2937        }
2938    }
2939
2940    r_inputs = getMapFromMaps (m, "lenv", "Identifier");
2941 
2942#ifdef META_DB
2943    int metadb_id=_init_sql(m,"metadb");
2944    //FAILED CONNECTING DB
2945    if(getMapFromMaps(m,"lenv","dbIssue")!=NULL || metadb_id<0){
2946      fprintf(stderr,"ERROR CONNECTING METADB\n");
2947    }
2948    if(metadb_id>=0)
2949      s1=extractServiceFromDb(m,r_inputs->value,0);
2950    //close_sql(m,0);
2951    if(s1!=NULL){
2952      inheritance(zooRegistry,&s1);
2953#ifdef USE_HPC
2954      addNestedOutputs(&s1);
2955#endif
2956      if(zooRegistry!=NULL){
2957        freeRegistry(&zooRegistry);
2958        free(zooRegistry);
2959      }
2960    }else /* Not found in MetaDB */{
2961#endif
2962      s1 = createService();
2963      if (s1 == NULL)
2964        {
2965          freeMaps (&m);
2966          free (m);
2967          if(zooRegistry!=NULL){
2968            freeRegistry(&zooRegistry);
2969            free(zooRegistry);
2970          }
2971          free (REQUEST);
2972          free (SERVICE_URL);
2973          return errorException (m, _("Unable to allocate memory"),
2974                                 "InternalError", NULL);
2975        }
2976
2977      int saved_stdout = zDup (fileno (stdout));
2978      zDup2 (fileno (stderr), fileno (stdout));
2979      t = readServiceFile (m, tmps1, &s1, r_inputs->value);
2980      if(t>=0){
2981        inheritance(zooRegistry,&s1);
2982#ifdef USE_HPC
2983        addNestedOutputs(&s1);
2984#endif
2985      }
2986      if(zooRegistry!=NULL){
2987        freeRegistry(&zooRegistry);
2988        free(zooRegistry);
2989      }
2990      fflush (stdout);
2991      zDup2 (saved_stdout, fileno (stdout));
2992      if (t < 0)
2993        {
2994          char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
2995          sprintf (tmpMsg,
2996                   _
2997                   ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
2998                   r_inputs->value);
2999          errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
3000          free (tmpMsg);
3001          free (s1);
3002          freeMaps (&m);
3003          free (m);
3004          free (REQUEST);
3005          free (SERVICE_URL);
3006          return 0;
3007        }
3008      zClose (saved_stdout);
3009#ifdef META_DB
3010    }
3011#endif
3012 
3013#ifdef DEBUG
3014    dumpService (s1);
3015#endif
3016    int j;
3017
3018
3019    /**
3020     * Create the input and output maps data structure
3021     */
3022    int i = 0;
3023    HINTERNET res;
3024    hInternet = InternetOpen (
3025#ifndef WIN32
3026                              (LPCTSTR)
3027#endif
3028                              "ZooWPSClient\0",
3029                              INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
3030
3031#ifndef WIN32
3032    if (!CHECK_INET_HANDLE (hInternet))
3033      fprintf (stderr, "WARNING : hInternet handle failed to initialize");
3034#endif
3035    maps *tmpmaps = request_input_real_format;
3036
3037    if(parseRequest(&m,&request_inputs,s1,&request_input_real_format,&request_output_real_format,&hInternet)<0){
3038      freeMaps (&m);
3039      free (m);
3040      free (REQUEST);
3041      free (SERVICE_URL);
3042      InternetCloseHandle (&hInternet);
3043      freeService (&s1);
3044      free (s1);
3045      return 0;
3046    }
3047    //InternetCloseHandle (&hInternet);
3048
3049    initAllEnvironment(m,request_inputs,ntmp,"xrequest");
3050
3051
3052#ifdef DEBUG
3053    dumpMap (request_inputs);
3054#endif
3055
3056    map *status = getMap (request_inputs, "status");
3057    if(vid==0){
3058      // Need to check if we need to fork to load a status enabled
3059      r_inputs = NULL;
3060      map *store = getMap (request_inputs, "storeExecuteResponse");
3061      /**
3062       * 05-007r7 WPS 1.0.0 page 57 :
3063       * 'If status="true" and storeExecuteResponse is "false" then the service
3064       * shall raise an exception.'
3065       */
3066      if (status != NULL && strcmp (status->value, "true") == 0 &&
3067          store != NULL && strcmp (store->value, "false") == 0)
3068        {
3069          errorException (m,
3070                          _
3071                          ("The status parameter cannot be set to true if storeExecuteResponse is set to false. Please modify your request parameters."),
3072                          "InvalidParameterValue", "storeExecuteResponse");
3073          freeService (&s1);
3074          free (s1);
3075          freeMaps (&m);
3076          free (m);
3077       
3078          freeMaps (&request_input_real_format);
3079          free (request_input_real_format);
3080       
3081          freeMaps (&request_output_real_format);
3082          free (request_output_real_format);
3083
3084          free (REQUEST);
3085          free (SERVICE_URL);
3086          return 1;
3087        }
3088      r_inputs = getMap (request_inputs, "storeExecuteResponse");
3089    }else{
3090      // Define status depending on the WPS 2.0.0 mode attribute
3091      status = getMap (request_inputs, "mode");
3092      map* mode=getMap(s1->content,"mode");
3093      if(strcasecmp(status->value,"async")==0){
3094        if(mode!=NULL && strcasecmp(mode->value,"async")==0)
3095          addToMap(request_inputs,"status","true");
3096        else{
3097          if(mode!=NULL){
3098            // see ref. http://docs.opengeospatial.org/is/14-065/14-065.html#61
3099            errorException (m,_("The process does not permit the desired execution mode."),"NoSuchMode", mode->value); 
3100            fflush (stdout);
3101            freeMaps (&m);
3102            free (m);
3103            if(zooRegistry!=NULL){
3104              freeRegistry(&zooRegistry);
3105              free(zooRegistry);
3106            }
3107            freeMaps (&request_input_real_format);
3108            free (request_input_real_format);
3109            freeMaps (&request_output_real_format);
3110            free (request_output_real_format);
3111            free (REQUEST);
3112            free (SERVICE_URL);
3113            return 0;
3114          }else
3115            addToMap(request_inputs,"status","true");
3116        }
3117      }
3118      else{
3119        if(strcasecmp(status->value,"auto")==0){
3120          if(mode!=NULL){
3121            if(strcasecmp(mode->value,"async")==0)
3122              addToMap(request_inputs,"status","false");
3123            else
3124              addToMap(request_inputs,"status","true");
3125          }
3126          else
3127            addToMap(request_inputs,"status","false");
3128        }else
3129          addToMap(request_inputs,"status","false");
3130      }
3131      status = getMap (request_inputs, "status");
3132    }
3133
3134    if (status != NULL)
3135      if (strcasecmp (status->value, "false") == 0)
3136        status = NULLMAP;
3137    if (status == NULLMAP)
3138      {
3139        if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
3140          freeService (&s1);
3141          free (s1);
3142          freeMaps (&m);
3143          free (m);
3144          free (REQUEST);
3145          free (SERVICE_URL);
3146          freeMaps (&request_input_real_format);
3147          free (request_input_real_format);
3148          freeMaps (&request_output_real_format);
3149          free (request_output_real_format);
3150          freeMaps (&tmpmaps);
3151          free (tmpmaps);
3152          return -1;
3153        }
3154        map* testMap=getMapFromMaps(m,"main","memory");
3155        if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
3156          dumpMapsValuesToFiles(&m,&request_input_real_format);
3157        loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
3158                           &request_output_real_format, &eres);   
3159
3160#ifdef META_DB
3161        close_sql(m,0);     
3162#endif     
3163      }
3164    else
3165      {
3166        int pid;
3167#ifdef DEBUG
3168        fprintf (stderr, "\nPID : %d\n", cpid);
3169#endif
3170#ifndef WIN32
3171        pid = fork ();
3172#else
3173        if (cgiSid == NULL)
3174          {
3175            createProcess (m, request_inputs, s1, NULL, cpid,
3176                           request_input_real_format,
3177                           request_output_real_format);
3178            pid = cpid;
3179          }
3180        else
3181          {
3182            pid = 0;
3183            cpid = atoi (cgiSid);
3184            updateStatus(m,0,_("Initializing"));
3185          }
3186#endif
3187        if (pid > 0)
3188          {
3189            //
3190            // dady :
3191            // set status to SERVICE_ACCEPTED
3192            //
3193#ifdef DEBUG
3194            fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
3195                     zGetpid ());
3196#endif
3197            eres = SERVICE_ACCEPTED;
3198          }
3199        else if (pid == 0)
3200          {
3201            eres = SERVICE_ACCEPTED;
3202            //
3203            // son : have to close the stdout, stdin and stderr to let the parent
3204            // process answer to http client.
3205            //
3206            map* usid = getMapFromMaps (m, "lenv", "uusid");
3207            map* tmpm = getMapFromMaps (m, "lenv", "osid");
3208            int cpid = atoi (tmpm->value);
3209            pid=cpid;
3210            r_inputs = getMapFromMaps (m, "main", "tmpPath");
3211            setMapInMaps (m, "lenv", "async","true");
3212            map* r_inputs1 = createMap("ServiceName", s1->name);
3213
3214            // Create the filename for the result file (.res)
3215            fbkpres =
3216              (char *)
3217              malloc ((strlen (r_inputs->value) +
3218                       strlen (usid->value) + 7) * sizeof (char));                   
3219            sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
3220            bmap = createMaps("status");
3221            bmap->content=createMap("usid",usid->value);
3222            addToMap(bmap->content,"sid",tmpm->value);
3223            addIntToMap(bmap->content,"pid",zGetpid());
3224         
3225            // Create PID file referencing the OS process identifier
3226            fbkpid =
3227              (char *)
3228              malloc ((strlen (r_inputs->value) +
3229                       strlen (usid->value) + 7) * sizeof (char));
3230            sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
3231            setMapInMaps (m, "lenv", "file.pid", fbkpid);
3232
3233            f0 = freopen (fbkpid, "w+",stdout);
3234            printf("%d",zGetpid());
3235            fflush(stdout);
3236
3237            // Create SID file referencing the semaphore name
3238            fbkp =
3239              (char *)
3240              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3241                       strlen (usid->value) + 7) * sizeof (char));
3242            sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
3243            setMapInMaps (m, "lenv", "file.sid", fbkp);
3244            FILE* f2 = freopen (fbkp, "w+",stdout);
3245            printf("%s",tmpm->value);
3246            fflush(f2);
3247            free(fbkp);
3248
3249            fbkp =
3250              (char *)
3251              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3252                       strlen (usid->value) + 7) * sizeof (char));
3253            sprintf (fbkp, "%s/%s_%s.xml", r_inputs->value, r_inputs1->value,
3254                     usid->value);
3255            setMapInMaps (m, "lenv", "file.responseInit", fbkp);
3256            flog =
3257              (char *)
3258              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3259                       strlen (usid->value) + 13) * sizeof (char));
3260            sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
3261                     r_inputs1->value, usid->value);
3262            setMapInMaps (m, "lenv", "file.log", flog);
3263#ifdef DEBUG
3264            fprintf (stderr, "RUN IN BACKGROUND MODE \n");
3265            fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
3266                     zGetpid ());
3267            fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
3268#endif
3269            freopen (flog, "w+", stderr);
3270            fflush (stderr);
3271            f0 = freopen (fbkp, "w+", stdout);
3272            rewind (stdout);
3273#ifndef WIN32
3274            fclose (stdin);
3275#endif
3276#ifdef RELY_ON_DB
3277            init_sql(m);
3278            recordServiceStatus(m);
3279#endif
3280#ifdef USE_CALLBACK
3281            invokeCallback(m,NULL,NULL,0,0);
3282#endif
3283            if(vid==0){
3284              //
3285              // set status to SERVICE_STARTED and flush stdout to ensure full
3286              // content was outputed (the file used to store the ResponseDocument).
3287              // Then, rewind stdout to restart writing from the begining of the file.
3288              // This way, the data will be updated at the end of the process run.
3289              //
3290              printProcessResponse (m, request_inputs, cpid, s1, r_inputs1->value,
3291                                    SERVICE_STARTED, request_input_real_format,
3292                                    request_output_real_format);
3293              fflush (stdout);
3294#ifdef RELY_ON_DB
3295              recordResponse(m,fbkp);
3296#endif
3297            }
3298
3299            fflush (stderr);
3300
3301            fbkp1 =
3302              (char *)
3303              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3304                       strlen (usid->value) + 13) * sizeof (char));
3305            sprintf (fbkp1, "%s/%s_final_%s.xml", r_inputs->value,
3306                     r_inputs1->value, usid->value);
3307            setMapInMaps (m, "lenv", "file.responseFinal", fbkp1);
3308
3309            f1 = freopen (fbkp1, "w+", stdout);
3310
3311            map* serviceTypeMap=getMap(s1->content,"serviceType");
3312            if(serviceTypeMap!=NULL)
3313              setMapInMaps (m, "lenv", "serviceType", serviceTypeMap->value);
3314
3315            char *flenv =
3316              (char *)
3317              malloc ((strlen (r_inputs->value) + 
3318                       strlen (usid->value) + 12) * sizeof (char));
3319            sprintf (flenv, "%s/%s_lenv.cfg", r_inputs->value, usid->value);
3320            maps* lenvMaps=getMaps(m,"lenv");
3321            dumpMapsToFile(lenvMaps,flenv,0);
3322            free(flenv);
3323
3324#ifdef USE_CALLBACK
3325            invokeCallback(m,request_input_real_format,NULL,1,0);
3326#endif
3327            if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
3328              freeService (&s1);
3329              free (s1);
3330              fflush (stdout);
3331              fflush (stderr);
3332              fclose (f0);
3333              fclose (f1);
3334              if(dumpBackFinalFile(m,fbkp,fbkp1)<0)
3335                return -1;
3336#ifndef RELY_ON_DB
3337              dumpMapsToFile(bmap,fbkpres,1);
3338              removeShmLock (m, 1);
3339#else
3340              recordResponse(m,fbkp1);
3341#ifdef USE_CALLBACK
3342              invokeCallback(m,NULL,NULL,7,0);
3343#endif
3344#endif
3345              zUnlink (fbkpid);
3346              unhandleStatus (m);
3347#ifdef RELY_ON_DB
3348#ifdef META_DB
3349              cleanupCallbackThreads();
3350              close_sql(m,1);
3351#endif
3352              close_sql(m,0);
3353#endif
3354              freeMaps (&m);
3355              free (m);
3356              free (REQUEST);
3357              free (SERVICE_URL);
3358              freeMaps (&request_input_real_format);
3359              free (request_input_real_format);
3360              freeMaps (&request_output_real_format);
3361              free (request_output_real_format);
3362              freeMaps (&tmpmaps);
3363              free (tmpmaps);
3364              return -1;
3365            }
3366            if(getMapFromMaps(m,"lenv","mapError")!=NULL){
3367              setMapInMaps(m,"lenv","message",_("Issue with geographic data"));
3368#ifdef USE_CALLBACK
3369              invokeCallback(m,NULL,NULL,7,0);
3370#endif
3371              eres=-1;//SERVICE_FAILED;
3372            }else{
3373              map* testMap=getMapFromMaps(m,"main","memory");
3374              if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
3375                dumpMapsValuesToFiles(&m,&request_input_real_format);
3376              loadServiceAndRun (&m, s1, request_inputs,
3377                                 &request_input_real_format,
3378                                 &request_output_real_format, &eres);
3379            }
3380          }
3381        else
3382          {
3383            /**
3384             * error server don't accept the process need to output a valid
3385             * error response here !!!
3386             */
3387            eres = -1;
3388            errorException (m, _("Unable to run the child process properly"),
3389                            "InternalError", NULL);
3390          }
3391      }
3392       
3393#ifdef DEBUG
3394    fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
3395    dumpMaps (request_output_real_format);
3396    fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
3397#endif
3398    fflush(stdout);
3399    rewind(stdout);
3400
3401    if (eres != -1)
3402      outputResponse (s1, request_input_real_format,
3403                      request_output_real_format, request_inputs,
3404                      cpid, m, eres);
3405    fflush (stdout);
3406  }
3407  /**
3408   * Ensure that if error occurs when freeing memory, no signal will return
3409   * an ExceptionReport document as the result was already returned to the
3410   * client.
3411   */
3412#ifndef USE_GDB
3413  signal (SIGSEGV, donothing);
3414  signal (SIGTERM, donothing);
3415  signal (SIGINT, donothing);
3416  signal (SIGILL, donothing);
3417  signal (SIGFPE, donothing);
3418  signal (SIGABRT, donothing);
3419#endif
3420    fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
3421    fflush(stderr);
3422
3423  if (((int) zGetpid ()) != cpid || cgiSid != NULL)
3424    {
3425    fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
3426    fflush(stderr);
3427      if (eres == SERVICE_SUCCEEDED)
3428#ifdef USE_CALLBACK
3429        invokeCallback(m,NULL,request_output_real_format,5,1);
3430#endif
3431      fflush(stderr);
3432      fflush(stdout);
3433
3434      fclose (stdout);
3435
3436      fclose (f0);
3437
3438      fclose (f1);
3439
3440      if(dumpBackFinalFile(m,fbkp,fbkp1)<0)
3441        return -1;
3442      zUnlink (fbkpid);
3443      switch(eres){
3444      default:
3445      case SERVICE_FAILED:
3446        setMapInMaps(bmap,"status","status",wpsStatus[1]);
3447        setMapInMaps(m,"lenv","fstate",wpsStatus[1]);
3448        break;
3449      case SERVICE_SUCCEEDED:
3450        setMapInMaps(bmap,"status","status",wpsStatus[0]);
3451        setMapInMaps(m,"lenv","fstate",wpsStatus[0]);
3452        break;
3453      }     
3454#ifndef RELY_ON_DB
3455      dumpMapsToFile(bmap,fbkpres,1);
3456      removeShmLock (m, 1);
3457#else
3458      recordResponse(m,fbkp1);
3459      if (eres == SERVICE_SUCCEEDED)
3460#ifdef USE_CALLBACK
3461        invokeCallback(m,NULL,request_output_real_format,6,0);
3462#endif
3463#endif
3464      freeMaps(&bmap);
3465      free(bmap);
3466      zUnlink (fbkp1);
3467      unhandleStatus (m);
3468#if defined(USE_JSON) || defined(USE_CALLBACK)
3469      cleanupCallbackThreads();
3470#endif
3471
3472#ifdef RELY_ON_DB
3473#ifdef META_DB
3474      close_sql(m,1);
3475#endif
3476      close_sql(m,0);
3477      end_sql();
3478#endif
3479      free(fbkpid);
3480      free(fbkpres);
3481      free (fbkp1);
3482      if(cgiSid!=NULL)
3483        free(cgiSid);
3484      map* tMap=getMapFromMaps(m,"main","executionType");
3485      if(tMap!=NULL && strncasecmp(tMap->value,"xml",3)==0)
3486        InternetCloseHandle (&hInternet);
3487      fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
3488      fflush(stderr);
3489      fclose (stderr);
3490      zUnlink (flog);
3491      free (flog);
3492    }
3493  else{
3494    //InternetCloseHandle (&hInternet); 
3495#ifdef META_DB
3496    close_sql(m,0);
3497#endif
3498  }
3499 
3500  freeService (&s1);
3501  free (s1);
3502  freeMaps (&m);
3503  free (m);
3504
3505  freeMaps (&request_input_real_format);
3506  free (request_input_real_format);
3507
3508  freeMaps (&request_output_real_format);
3509  free (request_output_real_format);
3510
3511  free (REQUEST);
3512  free (SERVICE_URL);
3513
3514#ifdef DEBUG
3515  fprintf (stderr, "Processed response \n");
3516  fflush (stdout);
3517  fflush (stderr);
3518#endif
3519
3520  if (((int) zGetpid ()) != cpid || cgiSid != NULL)
3521    {
3522      exit (0);
3523    }
3524
3525  return 0;
3526}
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