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

Last change on this file since 957 was 955, checked in by djay, 5 years ago

Fix issue when RELY_ON_DB is on and data is published. Ensure to use WPS 3 only when required. Set wmfs_link, wfs_link or wcs_link only when found in the metadata.

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