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

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

Fix issue in kvParseInput when memory!=load and handle session from the OGC API - Processes

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