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

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

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

  • Property svn:keywords set to Id
File size: 39.4 KB
Line 
1/*
2 * Author : Gérald Fenoy
3 *
4 *  Copyright 2008-2015 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
25#include "server_internal.h"
26#include "service_internal.h"
27#include "response_print.h"
28//#include "service_callback.h"
29#include "mimetypes.h"
30#ifndef WIN32
31#include <dlfcn.h>
32#include <uuid/uuid.h>
33#else
34#include <rpc.h>
35#define ERROR_MSG_MAX_LENGTH 1024
36#endif
37#include <signal.h>
38
39// #include <stdlib.h>
40/*
41 * Compare two file path strings to see if they refer to the same file.
42 *
43 * @param path1 the first file path
44 * @param path2 the second file path
45 *
46 * @return 0 if the files are identical
47 */
48#define PATHBUFSIZE 4096
49int zoo_path_compare(char* path1, char* path2) {
50
51  if (path1 == NULL || path2 == NULL) {
52    return -1;
53  }
54
55  char realpath1[PATHBUFSIZE];
56  char realpath2[PATHBUFSIZE];
57
58#ifdef WIN32
59  int res1 = GetFullPathName(path1, PATHBUFSIZE, realpath1, NULL);
60  int res2 = GetFullPathName(path2, PATHBUFSIZE, realpath2, NULL);
61
62  if (res1 == 0 || res2 == 0) {
63    return -1;
64  }
65  else {
66    return strncasecmp(realpath1, realpath2, PATHBUFSIZE);
67  }
68#else
69  char* ptr1 = realpath(path1, realpath1);
70  char* ptr2 = realpath(path2, realpath2);
71
72  if (ptr1 == NULL || ptr2 == NULL) {
73    return -1;
74  }
75  else {
76    return strncmp(realpath1, realpath2, PATHBUFSIZE);
77  }
78#endif
79}
80
81/**
82 * Detect WPS version used (1.0.0 or 2.0.0).
83 *
84 * @param version number as char* (1.0.0 or 2.0.0)
85 * @return 0 in case of version 1.0.0, 1 for 2.0.0, -1 in other case
86 */
87int getVersionId(const char* version){
88  int schemaId=0;
89  for(;schemaId<2;schemaId++){
90    if(strncasecmp(version,schemas[schemaId][0],5)==0)
91      return schemaId;
92  }
93  return -1;
94}
95
96/**
97 * Generate a UUID.
98 * ref: https://www.ietf.org/rfc/rfc4122.txt / 4.2
99 *
100 * @return a new char* containing the UUID, make sure to free the returned
101 *  resource once used.
102 */
103char *get_uuid(){
104  char *res=(char*)malloc(37*sizeof(char));
105#ifdef WIN32
106  UUID uuid;
107  UuidCreate(&uuid);
108  RPC_CSTR rest = NULL;
109  UuidToString(&uuid,&rest);
110#else
111  uuid_t uuid;
112  uuid_generate_time(uuid);
113  char rest[128];
114  uuid_unparse(uuid,rest);
115#endif
116  sprintf(res,"%s",rest);
117#ifdef WIN32
118  RpcStringFree(&rest);
119#endif
120  return res;
121}
122
123/**
124 * Extract the service identifier from the full service identifier
125 * ie:
126 *  - Full service name: OTB.BandMath
127 *  - Service name: BandMath
128 *
129 * @param conf the maps containing the settings of the main.cfg file
130 * @param conf_dir the full path to the ZOO-Kernel directory
131 * @param identifier the full service name (potentialy including a prefix, ie:
132 *  Prefix.MyService)
133 * @param buffer the resulting service identifier (without any prefix)
134 */
135void parseIdentifier(maps* conf,char* conf_dir,char *identifier,char* buffer){
136  setMapInMaps(conf,"lenv","oIdentifier",identifier);
137  char *lid=zStrdup(identifier);
138  char *saveptr1;
139  char *tmps1=strtok_r(lid,".",&saveptr1);
140  int level=0;
141  char key[25];
142  char levels[18];
143  while(tmps1!=NULL){
144    char *test=zStrdup(tmps1);
145    char* tmps2=(char*)malloc((strlen(test)+2)*sizeof(char));
146    sprintf(key,"sprefix_%d",level);
147    sprintf(tmps2,"%s.",test);
148    sprintf(levels,"%d",level);
149    setMapInMaps(conf,"lenv","level",levels);
150    setMapInMaps(conf,"lenv",key,tmps2);
151    free(tmps2);
152    free(test);
153    level++;
154    tmps1=strtok_r(NULL,".",&saveptr1);
155  }
156  int i=0;
157  sprintf(buffer,"%s",conf_dir);
158  for(i=0;i<level;i++){
159    char *tmp0=zStrdup(buffer);
160    sprintf(key,"sprefix_%d",i);
161    map* tmp00=getMapFromMaps(conf,"lenv",key);
162    if(tmp00!=NULL)
163      sprintf(buffer,"%s/%s",tmp0,tmp00->value);
164    free(tmp0);
165    buffer[strlen(buffer)-1]=0;
166    if(i+1<level){ 
167      #ifdef IGNORE_METAPATH
168        map* tmpMap = createMap("metapath", "");
169      #else 
170        map* tmpMap=getMapFromMaps(conf,"lenv","metapath");
171      #endif     
172      if(tmpMap==NULL || strlen(tmpMap->value)==0){
173        char *tmp01=zStrdup(tmp00->value);
174        tmp01[strlen(tmp01)-1]=0;
175        setMapInMaps(conf,"lenv","metapath",tmp01);
176        free(tmp01);
177        tmp01=NULL;
178      }
179      else{
180        if(tmp00!=NULL && tmpMap!=NULL){
181          char *tmp00s=zStrdup(tmp00->value);
182          tmp00s[strlen(tmp00s)-1]=0;
183          char *value=(char*)malloc((strlen(tmp00s)+strlen(tmpMap->value)+2)*sizeof(char));
184          sprintf(value,"%s/%s",tmpMap->value,tmp00s);
185          setMapInMaps(conf,"lenv","metapath",value);
186          free(value);
187          free(tmp00s);
188          value=NULL;
189        }
190      }
191    }else{
192      char *tmp01=zStrdup(tmp00->value);
193      tmp01[strlen(tmp01)-1]=0;
194      setMapInMaps(conf,"lenv","Identifier",tmp01);
195      free(tmp01);
196    }
197  }
198  char *tmp0=zStrdup(buffer);
199  sprintf(buffer,"%s.zcfg",tmp0);
200  free(tmp0);
201  free(lid);
202}
203
204/**
205 * Converts a hex character to its integer value
206 *
207 * @param ch the char to convert
208 * @return the converted char
209 */
210char from_hex(char ch) {
211  return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
212}
213
214/**
215 * Converts an integer value to its hec character
216 *
217 * @param code the char to convert
218 * @return the converted char
219 */
220char to_hex(char code) {
221  static char hex[] = "0123456789abcdef";
222  return hex[code & 15];
223}
224
225/**
226 * URLEncode an url
227 *
228 * @param str the url to encode
229 * @return a url-encoded version of str
230 * @warning be sure to free() the returned string after use
231 */
232char *url_encode(char *str) {
233  char *pstr = str, *buf = (char*) malloc(strlen(str) * 3 + 1), *pbuf = buf;
234  while (*pstr) {
235    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
236      *pbuf++ = *pstr;
237    else if (*pstr == ' ') 
238      *pbuf++ = '+';
239    else 
240      *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
241    pstr++;
242  }
243  *pbuf = '\0';
244  return buf;
245}
246
247/**
248 * Decode an URLEncoded url
249 *
250 * @param str the URLEncoded url to decode
251 * @return a url-decoded version of str
252 * @warning be sure to free() the returned string after use
253 */
254char *url_decode(char *str) {
255  char *pstr = str, *buf = (char*) malloc(strlen(str) + 1), *pbuf = buf;
256  while (*pstr) {
257    if (*pstr == '%') {
258      if (pstr[1] && pstr[2]) {
259        *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
260        pstr += 2;
261      }
262    } else if (*pstr == '+') { 
263      *pbuf++ = ' ';
264    } else {
265      *pbuf++ = *pstr;
266    }
267    pstr++;
268  }
269  *pbuf = '\0';
270  return buf;
271}
272
273/**
274 * Verify if a given language is listed in the lang list defined in the [main]
275 * section of the main.cfg file.
276 *
277 * @param conf the map containing the settings from the main.cfg file
278 * @param str the specific language
279 * @return 1 if the specific language is listed, -1 in other case.
280 */
281int isValidLang(maps* conf,const char *str){
282  map *tmpMap=getMapFromMaps(conf,"main","language");
283  char *tmp0=NULL,*tmp=NULL,*tmp1=NULL;
284  if(tmpMap!=NULL)
285    tmp0=zStrdup(tmpMap->value);
286  tmpMap=getMapFromMaps(conf,"main","lang");
287  if(tmpMap!=NULL)
288    tmp=zStrdup(tmpMap->value);
289  if(tmp0!=NULL && tmp!=NULL){
290    tmp1=(char*)malloc((strlen(tmp0)+strlen(tmp)+2)*sizeof(char));
291    sprintf(tmp1,"%s,%s",tmp0,tmp);
292    free(tmp0);
293    free(tmp);
294  }else{
295    if(tmp!=NULL){
296      tmp1=zStrdup(tmp);
297      free(tmp);
298    }else{
299      if(tmp0!=NULL){
300        tmp1=zStrdup(tmp0);
301        free(tmp0);
302      }
303    }
304  }
305  char *pToken,*saveptr;
306  pToken=strtok_r(tmp1,",",&saveptr);
307  int res=-1;
308  while(pToken!=NULL){
309    if(strcasecmp(str,pToken)==0){
310      res=1;
311      break;
312    }
313    pToken=strtok_r(NULL,",",&saveptr);
314  }
315  if(tmp1!=NULL)
316    free(tmp1);
317  return res;
318}
319
320
321/**
322 * Access the value of the encoding key in a maps
323 *
324 * @param m the maps to search for the encoding key
325 * @return the value of the encoding key in a maps if encoding key exists,
326 *  "UTF-8" in other case.
327 */
328char* getEncoding(maps* m){
329  if(m!=NULL){
330    map* tmp=getMap(m->content,"encoding");
331    if(tmp!=NULL){
332      return tmp->value;
333    }
334    else
335      return (char*)"UTF-8";
336  }
337  else
338    return (char*)"UTF-8"; 
339}
340
341/**
342 * Access the value of the version key in a maps
343 *
344 * @param m the maps to search for the version key
345 * @return the value of the version key in a maps if encoding key exists,
346 *  "1.0.0" in other case.
347 */
348char* getVersion(maps* m){
349  if(m!=NULL){
350    map* tmp=getMap(m->content,"version");
351    if(tmp!=NULL){
352      return tmp->value;
353    }
354    else
355      return (char*)"1.0.0";
356  }
357  else
358    return (char*)"1.0.0";
359}
360
361/**
362 * Read a file generated by a service.
363 *
364 * @param m the conf maps
365 * @param content the output item
366 * @param filename the file to read
367 */
368void readGeneratedFile(maps* m,map* content,char* filename){
369  char rsize[1024];
370  FILE * file=fopen(filename,"rb");
371  if(file==NULL){
372    setMapInMaps(m,"lenv","message","Unable to read produced file. Please try again later");
373    return ;
374  }
375  zStatStruct f_status;
376  int s=zStat(filename, &f_status);
377  sprintf(rsize,"%ld",f_status.st_size);
378  if(getMap(content,"storage")==NULL){
379    map* tmpMap1=getMap(content,"value");
380    if(tmpMap1==NULL){
381      addToMap(content,"value","");
382      tmpMap1=getMap(content,"value");
383    }
384    free(tmpMap1->value);
385    tmpMap1->value=(char*) malloc((f_status.st_size+1)*sizeof(char));
386    if(tmpMap1->value==NULL){
387      setMapInMaps(m,"lenv","message","Unable to allocate the memory required to read the produced file.");
388      return;
389    }
390    fread(tmpMap1->value,1,f_status.st_size,file);
391    tmpMap1->value[f_status.st_size]=0;
392  }
393  fclose(file);
394  if(content!=NULL)
395    addToMap(content,"size",rsize);
396}
397
398
399/**
400 * Write a file from value and length
401 *
402 * @param fname the file name
403 * @param val the value
404 * @param length the value length
405 */
406int writeFile(char* fname,char* val,int length){
407  FILE* of=fopen(fname,"wb");
408  if(of==NULL){
409    return -1;
410  }
411  size_t ret=fwrite(val,sizeof(char),length,of);
412  if(ret<length){
413    fprintf(stderr,"Write error occurred!\n");
414    fclose(of);
415    return -1;
416  }
417  fclose(of);
418  return 1;
419}
420
421/**
422 * Dump all values in a maps as files
423 *
424 * @param main_conf the maps containing the settings of the main.cfg file
425 * @param in the maps containing values to dump as files
426 */
427void dumpMapsValuesToFiles(maps** main_conf,maps** in){
428  map* tmpPath=getMapFromMaps(*main_conf,"main","tmpPath");
429  map* tmpUrl=getMapFromMaps(*main_conf,"main","tmpUrl");
430  map* tmpSid=getMapFromMaps(*main_conf,"lenv","usid");
431  maps* inputs=*in;
432  int length=0;
433  while(inputs!=NULL){
434    if(getMap(inputs->content,"mimeType")!=NULL &&
435       getMap(inputs->content,"cache_file")==NULL){
436      map* cMap=inputs->content;
437      if(getMap(cMap,"length")!=NULL){
438        map* tmpLength=getMap(cMap,"length");
439        int len=atoi(tmpLength->value);
440        int k=0;
441        for(k=0;k<len;k++){
442          map* cMimeType=getMapArray(cMap,"mimeType",k);
443          map* cValue=getMapArray(cMap,"value",k);
444          map* cSize=getMapArray(cMap,"size",k);
445          char file_ext[32];
446          getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
447          char* val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
448          sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,k,file_ext);
449          length=0;
450          if(cSize!=NULL){
451            length=atoi(cSize->value);
452          }else
453            length=strlen(cValue->value);
454          writeFile(val,cValue->value,length);
455          setMapArray(cMap,"cache_file",k,val);
456          free(val);
457          val=(char*)malloc((strlen(tmpUrl->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
458          sprintf(val,"%s/Input_%s_%s_%d.%s",tmpUrl->value,inputs->name,tmpSid->value,k,file_ext);
459          setMapArray(cMap,"cache_url",k,val);
460          setMapArray(cMap,"byValue",k,"true");
461          free(val);
462        }
463      }else{
464        int length=0;
465        map* cMimeType=getMap(cMap,"mimeType");
466        map* cValue=getMap(cMap,"value");
467        map* cSize=getMap(cMap,"size");
468        char file_ext[32];
469        getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
470        char *val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
471        sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,0,file_ext);
472        if(cSize!=NULL){
473          length=atoi(cSize->value);
474        }else
475          length=strlen(cValue->value);
476        writeFile(val,cValue->value,length);
477        addToMap(cMap,"cache_file",val);
478        free(val);
479        val=(char*)malloc((strlen(tmpUrl->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
480        sprintf(val,"%s/Input_%s_%s_%d.%s",tmpUrl->value,inputs->name,tmpSid->value,0,file_ext);
481        addToMap(cMap,"cache_url",val);
482        addToMap(cMap,"byValue",val);
483        free(val);
484      }
485    }
486    inputs=inputs->next;
487  }
488}
489
490
491/**
492 * Base64 encoding of a char*
493 *
494 * @param input the value to encode
495 * @param length the value length
496 * @return the buffer containing the base64 value
497 * @warning make sure to free the returned value
498 */
499char *base64(const char *input, int length)
500{
501  BIO *bmem, *b64;
502  BUF_MEM *bptr;
503
504  b64 = BIO_new(BIO_f_base64());
505  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
506  bmem = BIO_new(BIO_s_mem());
507  b64 = BIO_push(b64, bmem);
508  BIO_write(b64, input, length);
509  BIO_flush(b64);
510  BIO_get_mem_ptr(b64, &bptr);
511
512  char *buff = (char *)malloc((bptr->length+1)*sizeof(char));
513  memcpy(buff, bptr->data, bptr->length);
514  buff[bptr->length] = 0;
515
516  BIO_free_all(b64);
517
518  return buff;
519}
520
521/**
522 * Base64 decoding of a char*
523 *
524 * @param input the value to decode
525 * @param length the value length
526 * @param red the value length
527 * @return the buffer containing the base64 value
528 * @warning make sure to free the returned value
529 */
530char *base64d(const char *input, int length,int* red)
531{
532  BIO *b64, *bmem;
533
534  char *buffer = (char *)malloc(length);
535  if(buffer){
536    memset(buffer, 0, length);
537    b64 = BIO_new(BIO_f_base64());
538    if(b64){
539      bmem = BIO_new_mem_buf((unsigned char*)input,length);
540      bmem = BIO_push(b64, bmem);
541      *red=BIO_read(bmem, buffer, length);
542      buffer[length-1]=0;
543      BIO_free_all(bmem);
544    }
545  }
546  return buffer;
547}
548
549/**
550 * Read Base64 value and split it value by lines of 64 char.
551 *
552 * @param in the map containing the value to split
553 */
554void readBase64(map **in){
555  char *res = NULL;
556  char *curs = (*in)->value;
557  int i = 0;
558  for (i = 0; i <= strlen ((*in)->value) / 64;
559       i++)
560    {
561      if (res == NULL)
562        res =
563          (char *) malloc (65 * sizeof (char));
564      else
565        res =
566          (char *) realloc (res,
567                            (((i + 1) * 65) +
568                             i) * sizeof (char));
569      int csize = i * 65;
570      strncpy (res + csize, curs, 64);
571      if (i == strlen ((*in)->value) / 64)
572        strcat (res, "\n\0");
573      else
574        {
575          strncpy (res + (((i + 1) * 64) + i),
576                   "\n\0", 2);
577          curs += 64;
578        }
579    }
580  free ((*in)->value);
581  (*in)->value = zStrdup (res);
582  free (res);
583}
584
585
586/**
587 * Add the default values defined in the zcfg to a maps.
588 *
589 * @param out the maps containing the inputs or outputs given in the initial
590 *  HTTP request
591 * @param in the description of all inputs or outputs available for a service
592 * @param m the maps containing the settings of the main.cfg file
593 * @param type 0 for inputs and 1 for outputs
594 * @param err the map to store potential missing mandatory input parameters or
595 *  wrong output names depending on the type.
596 * @return "" if no error was detected, the name of last input or output causing
597 *  an error.
598 */
599char* addDefaultValues(maps** out,elements* in,maps* m,int type,map** err){
600  map *res=*err;
601  elements* tmpInputs=in;
602  elements* tmpInputss=NULL;
603  maps* out1=*out;
604  maps* out1s=NULL;
605  char *result=NULL;
606  int nb=0;
607  int inb=0;
608 loopOnInputs:
609  if(type==1){
610    while(out1!=NULL){
611      if(getElements(in,out1->name)==NULL){
612        if(res==NULL){
613          res=createMap("value",out1->name);
614        }else{
615          setMapArray(res,"value",nb,out1->name);
616        }
617        nb++;
618        result=out1->name;
619      }
620      inb++;
621      out1=out1->next;
622    }
623    if(res!=NULL){
624      fflush(stderr);
625      *err=res;
626      return result;
627    }
628    if(out1==NULL && inb>=1)
629      out1=*out;
630  }
631  while(tmpInputs!=NULL){
632    maps *tmpMaps=getMaps(out1,tmpInputs->name);
633    if(tmpMaps==NULL){
634      maps* tmpMaps2=createMaps(tmpInputs->name);
635      if(type==0){
636        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
637        if(tmpMapMinO!=NULL){
638          if(atoi(tmpMapMinO->value)>=1){
639            freeMaps(&tmpMaps2);
640            free(tmpMaps2);
641            if(res==NULL){
642              res=createMap("value",tmpInputs->name);
643            }else{
644              setMapArray(res,"value",nb,tmpInputs->name);
645            }
646            nb++;
647            result=tmpInputs->name;
648          }
649          else{
650            if(tmpMaps2->content==NULL)
651              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
652            else
653              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
654          }
655        }
656        if(res==NULL){
657          map* tmpMaxO0=getMap(tmpInputs->content,"useMapserver");
658          if(tmpMaxO0!=NULL){
659            if(tmpMaps2->content==NULL)
660              tmpMaps2->content=createMap("useMapserver",tmpMaxO0->value);
661            else
662              addToMap(tmpMaps2->content,"useMapserver",tmpMaxO0->value);
663          }
664          map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
665          if(tmpMaxO!=NULL){
666            if(tmpMaps2->content==NULL)
667              tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
668            else
669              addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
670          }
671          map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
672          if(tmpMaxMB!=NULL){
673            if(tmpMaps2->content==NULL)
674              tmpMaps2->content=createMap("maximumMegabytes",tmpMaxMB->value);
675            else
676              addToMap(tmpMaps2->content,"maximumMegabytes",tmpMaxMB->value);
677          }
678        }
679      }
680     
681      if(res==NULL){
682        iotype* tmpIoType=tmpInputs->defaults;
683        if(tmpIoType!=NULL){
684          map* tmpm=tmpIoType->content;
685          while(tmpm!=NULL){
686            if(tmpMaps2->content==NULL)
687              tmpMaps2->content=createMap(tmpm->name,tmpm->value);
688            else{
689              addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
690            }
691            tmpm=tmpm->next;
692          }
693        }
694        if(tmpMaps2->content==NULL){
695          tmpMaps2->content=createMap("inRequest","false");
696          dumpMaps(tmpMaps2);
697        }
698        else
699          addToMap(tmpMaps2->content,"inRequest","false");
700        if(type==0){
701          map *tmpMap=getMap(tmpMaps2->content,"value");
702          if(tmpMap==NULL)
703            addToMap(tmpMaps2->content,"value","NULL");
704        }
705        elements* tmpElements=getElements(in,tmpMaps2->name);
706        if(tmpElements!=NULL && tmpElements->child!=NULL){
707          char *res=addDefaultValues(&tmpMaps2->child,tmpElements->child,m,type,err);
708          if(strlen(res)>0){
709            return res;
710          }
711        }
712
713        if(out1==NULL){
714          *out=dupMaps(&tmpMaps2);
715          out1=*out;
716        }
717        else
718          addMapsToMaps(&out1,tmpMaps2);
719        freeMap(&tmpMaps2->content);
720        free(tmpMaps2->content);
721        tmpMaps2->content=NULL;
722        freeMaps(&tmpMaps2);
723        free(tmpMaps2);
724        tmpMaps2=NULL;
725      }
726    }
727    else /*toto*/{ 
728      iotype* tmpIoType=NULL;
729      if(tmpMaps->content!=NULL){
730        tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
731                                       tmpMaps->content);
732        if(type==0) {
733          /**
734           * In case of an Input maps, then add the minOccurs and maxOccurs to the
735           * content map.
736           */
737          const char* keys[4]={
738            "minOccurs",
739            "maxOccurs",
740            "maximumMegabytes",
741            "useMapserver"
742          };
743          int i=0;
744          for(i=0;i<4;i++){
745            map* tmpMap1=getMap(tmpInputs->content,keys[i]);
746            if(tmpMap1!=NULL){
747              addToMap(tmpMaps->content,keys[i],tmpMap1->value);
748            }
749          }
750          /**
751           * Parsing BoundingBoxData, fill the following map and then add it to
752           * the content map of the Input maps:
753           * lowerCorner, upperCorner, srs and dimensions
754           * cf. parseBoundingBox
755           */
756          if(tmpInputs->format!=NULL && strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
757            maps* tmpI=getMaps(*out,tmpInputs->name);
758            if(tmpI!=NULL){
759              map* tmpV=getMap(tmpI->content,"value");
760              if(tmpV!=NULL){
761                char *tmpVS=zStrdup(tmpV->value);
762                map* tmp=parseBoundingBox(tmpVS);
763                free(tmpVS);
764                map* tmpC=tmp;
765                while(tmpC!=NULL){
766                  addToMap(tmpMaps->content,tmpC->name,tmpC->value);
767                  tmpC=tmpC->next;
768                }
769                freeMap(&tmp);
770                free(tmp);
771              }
772            }
773          }
774        }
775      }else{
776        if(tmpInputs!=NULL){
777          tmpIoType=tmpInputs->defaults;
778        }
779      }
780
781      if(tmpIoType!=NULL){
782        map* tmpContent=tmpIoType->content;
783        map* cval=NULL;
784        int hasPassed=-1;
785        while(tmpContent!=NULL){
786          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
787#ifdef DEBUG
788            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
789#endif
790            if(tmpMaps->content==NULL)
791              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
792            else
793              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
794           
795            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
796              map* length=getMap(tmpMaps->content,"length");
797              int i;
798              char *tcn=zStrdup(tmpContent->name);
799              for(i=1;i<atoi(length->value);i++){
800#ifdef DEBUG
801                dumpMap(tmpMaps->content);
802                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
803#endif
804                int len=strlen((char*) tcn);
805                char *tmp1=(char *)malloc((len+10)*sizeof(char));
806                sprintf(tmp1,"%s_%d",tcn,i);
807#ifdef DEBUG
808                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
809#endif
810                addToMap(tmpMaps->content,tmp1,tmpContent->value);
811                free(tmp1);
812                hasPassed=1;
813              }
814              free(tcn);
815            }
816          }
817          tmpContent=tmpContent->next;
818        }
819#ifdef USE_MS
820        /**
821         * check for useMapServer presence
822         */
823        if(tmpIoType!=NULL){
824          map* tmpCheck=getMap(tmpIoType->content,"useMapserver");
825          if(tmpCheck!=NULL && strncasecmp(tmpCheck->value,"true",4)==0){
826            // Get the default value
827            addToMap(tmpMaps->content,"useMapserver","true");
828            tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
829            tmpCheck=getMap(tmpMaps->content,"mimeType");
830            addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
831            map* cursor=tmpIoType->content;
832            while(cursor!=NULL){
833              addToMap(tmpMaps->content,cursor->name,cursor->value);
834              cursor=cursor->next;
835            }
836         
837            cursor=tmpInputs->content;
838            while(cursor!=NULL){
839              if(strcasecmp(cursor->name,"Title")==0 ||
840                 strcasecmp(cursor->name,"Abstract")==0)
841                addToMap(tmpMaps->content,cursor->name,cursor->value);
842              cursor=cursor->next;
843            }
844          }
845        }
846#endif
847      }
848      if(tmpMaps->content==NULL)
849        tmpMaps->content=createMap("inRequest","true");
850      else
851        addToMap(tmpMaps->content,"inRequest","true");
852      elements* tmpElements=getElements(in,tmpMaps->name);
853      if(/*tmpMaps->child!=NULL && */tmpElements!=NULL && tmpElements->child!=NULL){
854        char *res=addDefaultValues(&tmpMaps->child,tmpElements->child,m,type,err);
855        if(strlen(res)>0){
856          return res;
857        }
858      }
859    }
860    if(tmpInputs->child!=NULL){
861      tmpInputss=tmpInputs->next;
862      tmpInputs=tmpInputs->child;
863      if(tmpMaps!=NULL){
864        out1=tmpMaps->child;
865        out1s=tmpMaps;
866      }
867    }
868    tmpInputs=tmpInputs->next;
869  }
870  if(tmpInputss!=NULL){
871    out1=out1s;
872    tmpInputs=tmpInputss;
873    tmpInputss=NULL;
874    out1s=NULL;
875    goto loopOnInputs;
876  }
877  if(res!=NULL){
878    *err=res;
879    return result;
880  }
881  return "";
882}
883
884/**
885 * Access the last error message returned by the OS when trying to dynamically
886 * load a shared library.
887 *
888 * @return the last error message
889 * @warning The character string returned from getLastErrorMessage resides
890 * in a static buffer. The application should not write to this
891 * buffer or attempt to free() it.
892 */ 
893char* getLastErrorMessage() {                                             
894#ifdef WIN32
895  LPVOID lpMsgBuf;
896  DWORD errCode = GetLastError();
897  static char msg[ERROR_MSG_MAX_LENGTH];
898  size_t i;
899 
900  DWORD length = FormatMessage(
901                               FORMAT_MESSAGE_ALLOCATE_BUFFER | 
902                               FORMAT_MESSAGE_FROM_SYSTEM |
903                               FORMAT_MESSAGE_IGNORE_INSERTS,
904                               NULL,
905                               errCode,
906                               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
907                               (LPTSTR) &lpMsgBuf,
908                               0, NULL );       
909 
910#ifdef UNICODE         
911  wcstombs_s( &i, msg, ERROR_MSG_MAX_LENGTH,
912              (wchar_t*) lpMsgBuf, _TRUNCATE );
913#else
914  strcpy_s( msg, ERROR_MSG_MAX_LENGTH,
915            (char *) lpMsgBuf );               
916#endif 
917  LocalFree(lpMsgBuf);
918
919  return msg;
920#else
921  return dlerror();
922#endif
923}
924
925#include <dirent.h>
926#ifndef RELY_ON_DB
927/**
928 * Read the Result file (.res).
929 *
930 * @param conf the maps containing the setting of the main.cfg file
931 * @param pid the service identifier (usid key from the [lenv] section)
932 */
933void readFinalRes(maps* conf,char* pid,map* statusInfo){
934  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
935  char* fbkpid =
936    (char *)
937    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
938  sprintf (fbkpid, "%s/%s.res", r_inputs->value, pid);
939  struct stat file_status;
940  int istat = stat (fbkpid, &file_status);
941  if (istat == 0 && file_status.st_size > 0)
942    {
943      maps *res = (maps *) malloc (MAPS_SIZE);
944      conf_read (fbkpid, res);
945      res->child=NULL;
946      map* status=getMapFromMaps(res,"status","status");
947      addToMap(statusInfo,"Status",status->value);
948      freeMaps(&res);
949      free(res);
950    }
951  else{
952    addToMap(statusInfo,"Status","Failed");
953    addToMap(statusInfo,"NotFound",pid);
954  }
955  free(fbkpid);
956}
957
958/**
959 * Check if a service is running.
960 *
961 * @param conf the maps containing the setting of the main.cfg file
962 * @param pid the unique service identifier (usid from the lenv section)
963 * @return 1 in case the service is still running, 0 otherwise
964 */
965int isRunning(maps* conf,char* pid){
966  int res=0;
967  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
968  char* fbkpid =
969    (char *)
970    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
971  sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid); 
972  FILE* f0 = fopen (fbkpid, "r");
973  if(f0!=NULL){
974    fclose(f0);
975    res=1;
976  }
977  free(fbkpid);
978  return res;
979}
980#else
981#include "sqlapi.h"
982#endif
983
984/**
985 * Run GetStatus requests.
986 *
987 * @param conf the maps containing the setting of the main.cfg file
988 * @param pid the service identifier (usid key from the [lenv] section)
989 * @param req the request (GetStatus / GetResult)
990 */
991void runGetStatus(maps* conf,char* pid,char* req){
992  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
993  map* e_type = getMapFromMaps (conf, "main", "executionType");
994  char *sid=getStatusId(conf,pid);
995  if(sid==NULL){
996    if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
997      errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
998                      "NoSuchJob", pid);
999    else{
1000      setMapInMaps(conf,"lenv","error","true");
1001      setMapInMaps(conf,"lenv","code","NoSuchJob");
1002      setMapInMaps(conf,"lenv","message",_("The JobID from the request does not match any of the Jobs running on this server"));
1003    }
1004  }else{
1005    map* statusInfo=createMap("JobID",pid);
1006    if(isRunning(conf,pid)>0){
1007      if(strncasecmp(req,"GetResult",strlen(req))==0){
1008        if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
1009          errorException (conf, _("The result for the requested JobID has not yet been generated. The service is currently running."),
1010                          "ResultNotReady", pid);
1011        else{
1012          setMapInMaps(conf,"lenv","error","true");
1013          setMapInMaps(conf,"lenv","code","ResultNotReady");
1014          setMapInMaps(conf,"lenv","message",_("The result for the requested JobID has not yet been generated. The service is currently running."));
1015        }
1016        return;
1017      }
1018      else{
1019        if(strncasecmp(req,"GetStatus",strlen(req))==0){
1020          addToMap(statusInfo,"Status","Running");
1021          setMapInMaps(conf,"lenv","status","Running");
1022          char* tmpStr=_getStatus(conf,pid);
1023          if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
1024            char *tmpStr1=zStrdup(tmpStr);
1025            char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
1026            free(tmpStr);
1027            tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
1028            addToMap(statusInfo,"PercentCompleted",tmpStr1);
1029            addToMap(statusInfo,"Message",tmpStr0);
1030            setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
1031            setMapInMaps(conf,"lenv","Message",tmpStr0);
1032            free(tmpStr0);
1033            free(tmpStr1);
1034          }
1035        }
1036      }
1037    }
1038    else{
1039      if(strncasecmp(req,"GetResult",strlen(req))==0){
1040        char* result=_getStatusFile(conf,pid);
1041        if(result!=NULL){
1042          char *encoding=getEncoding(conf);
1043          printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1044          printf("%s",result);
1045          fflush(stdout);
1046          free(sid);
1047          freeMap(&statusInfo);
1048          free(statusInfo);
1049          free(result);
1050          return;
1051        }else{
1052          errorException (conf, _("The result for the requested JobID has not yet been generated. The service ends but it still needs to produce the outputs."),
1053                          "ResultNotReady", pid);
1054          freeMap(&statusInfo);
1055          free(statusInfo);
1056          return;
1057        }
1058      }else
1059        if(strncasecmp(req,"GetStatus",strlen(req))==0){
1060          readFinalRes(conf,pid,statusInfo);
1061          if(e_type==NULL || strncasecmp(e_type->value,"json",4)==0){
1062            map* pmStatus=getMap(statusInfo,"status");     
1063            if(pmStatus!=NULL)
1064              setMapInMaps(conf,"lenv","status",pmStatus->value);   
1065          }
1066          char* tmpStr=_getStatus(conf,pid);
1067          if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
1068            char *tmpStr1=zStrdup(tmpStr);
1069            char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
1070            free(tmpStr);
1071            tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
1072            addToMap(statusInfo,"PercentCompleted",tmpStr1);
1073            addToMap(statusInfo,"Message",tmpStr0);
1074            setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
1075            setMapInMaps(conf,"lenv","Message",tmpStr0);
1076            free(tmpStr0);
1077            free(tmpStr1);
1078          }
1079        }
1080    }
1081    free(sid);
1082    if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
1083      printStatusInfo(conf,statusInfo,req);
1084    else
1085      setMapInMaps(conf,"lenv","error","false");
1086    freeMap(&statusInfo);
1087    free(statusInfo);
1088  }
1089  return;
1090}
1091
1092/**
1093 * Run Dismiss requests.
1094 *
1095 * @param conf the maps containing the setting of the main.cfg file
1096 * @param pid the service identifier (usid key from the [lenv] section)
1097 */
1098void runDismiss(maps* conf,char* pid){
1099  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
1100  map* e_type = getMapFromMaps (conf, "main", "executionType");
1101  char *sid=getStatusId(conf,pid);
1102  if(sid==NULL){
1103    if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
1104      errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
1105                      "NoSuchJob", pid);
1106    else{
1107      setMapInMaps(conf,"lenv","error","true");
1108      setMapInMaps(conf,"lenv","code","NoSuchJob");
1109      setMapInMaps(conf,"lenv","message",_("The JobID from the request does not match any of the Jobs running on this server"));
1110    }
1111    return;
1112  }else{
1113    // We should send the Dismiss request to the target host if it differs
1114    char* fbkpid =
1115      (char *)
1116      malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
1117    sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid);
1118    FILE* f0 = fopen (fbkpid, "r");
1119    if(f0!=NULL){
1120      long flen;
1121      char *fcontent;
1122      fseek (f0, 0, SEEK_END);
1123      flen = ftell (f0);
1124      fseek (f0, 0, SEEK_SET);
1125      fcontent = (char *) malloc ((flen + 1) * sizeof (char));
1126      fread(fcontent,flen,1,f0);
1127      fcontent[flen]=0;
1128      fclose(f0);
1129#ifndef WIN32
1130      kill(atoi(fcontent),SIGKILL);
1131#else
1132      HANDLE myZooProcess=OpenProcess(PROCESS_ALL_ACCESS,false,atoi(fcontent));
1133      TerminateProcess(myZooProcess,1);
1134      CloseHandle(myZooProcess);
1135#endif
1136      free(fcontent);
1137    }
1138    free(fbkpid);
1139    struct dirent *dp;
1140    DIR *dirp = opendir(r_inputs->value);
1141    char fileName[1024];
1142    int hasFile=-1;
1143    if(dirp!=NULL){
1144      while ((dp = readdir(dirp)) != NULL){
1145        if(strstr(dp->d_name,pid)!=0){
1146          sprintf(fileName,"%s/%s",r_inputs->value,dp->d_name);
1147          if(zUnlink(fileName)!=0){
1148            if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
1149              errorException (conf, 
1150                              _("The job cannot be removed, a file cannot be removed"),
1151                              "NoApplicableCode", NULL);
1152            else{
1153                    setMapInMaps(conf,"lenv","error","true");
1154                    setMapInMaps(conf,"lenv","code","NoApplicableCode");
1155                    setMapInMaps(conf,"lenv","message",_("The job cannot be removed, a file cannot be removed"));
1156            }
1157            return;
1158          }
1159         
1160        }
1161      }
1162    }
1163#ifdef RELY_ON_DB
1164    removeService(conf,pid);
1165#endif
1166    if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0){
1167      map* statusInfo=createMap("JobID",pid);
1168      addToMap(statusInfo,"Status","Dismissed");
1169      printStatusInfo(conf,statusInfo,"Dismiss");
1170      free(statusInfo);
1171    }else{
1172      setMapInMaps(conf,"lenv","error","false");
1173    }
1174  }
1175  return;
1176}
1177
1178extern int getServiceFromFile (maps *, const char *, service **);
1179
1180/**
1181 * Parse the service file using getServiceFromFile or use getServiceFromYAML
1182 * if YAML support was activated.
1183 *
1184 * @param conf the conf maps containing the main.cfg settings
1185 * @param file the file name to parse
1186 * @param service the service to update witht the file content
1187 * @param name the service name
1188 * @return true if the file can be parsed or false
1189 * @see getServiceFromFile, getServiceFromYAML
1190 */
1191int readServiceFile (maps * conf, char *file, service ** service, char *name){
1192  int t = getServiceFromFile (conf, file, service);
1193#ifdef YAML
1194  if (t < 0){
1195    t = getServiceFromYAML (conf, file, service, name);
1196  }
1197#endif
1198  return t;
1199}
1200
1201/**
1202 * Create the profile registry.
1203 *
1204 * The profile registry is optional (created only if the registry key is
1205 * available in the [main] section of the main.cfg file) and can be used to
1206 * store the profiles hierarchy. The registry is a directory which should
1207 * contain the following sub-directories:
1208 *  * concept: direcotry containing .html files describing concept
1209 *  * generic: directory containing .zcfg files for wps:GenericProcess
1210 *  * implementation: directory containing .zcfg files for wps:Process
1211 *
1212 * @param m the conf maps containing the main.cfg settings
1213 * @param r the registry to update
1214 * @param reg_dir the resgitry
1215 * @return 0 if the resgitry is null or was correctly updated, -1 on failure
1216 */
1217int createRegistry (maps* m,registry ** r, char *reg_dir)
1218{
1219  char registryKeys[3][15]={
1220    "concept",
1221    "generic",
1222    "implementation"
1223  };
1224  int scount = 0,i=0;
1225  if (reg_dir == NULL)
1226    return 0;
1227  for(i=0;i<3;i++){
1228    char * tmpName =
1229      (char *) malloc ((strlen (reg_dir) + strlen (registryKeys[i]) + 2) *
1230                       sizeof (char));
1231    sprintf (tmpName, "%s/%s", reg_dir, registryKeys[i]);
1232   
1233    DIR *dirp1 = opendir (tmpName);
1234    if(dirp1==NULL){
1235      setMapInMaps(m,"lenv","message",_("Unable to open the registry directory."));
1236      setMapInMaps(m,"lenv","type","InternalError");
1237      return -1;
1238    }
1239    struct dirent *dp1;
1240    while ((dp1 = readdir (dirp1)) != NULL){
1241      char* extn = strstr(dp1->d_name, ".zcfg");
1242      if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
1243        {
1244          int t;
1245          char *tmps1=
1246            (char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) *
1247                             sizeof (char));
1248          sprintf (tmps1, "%s/%s", tmpName, dp1->d_name);
1249          char *tmpsn = zStrdup (dp1->d_name);
1250          tmpsn[strlen (tmpsn) - 5] = 0;
1251          service* s1 = (service *) malloc (SERVICE_SIZE);
1252          if (s1 == NULL)
1253            {
1254              setMapInMaps(m,"lenv","message",_("Unable to allocate memory."));
1255              setMapInMaps(m,"lenv","type","InternalError");
1256              return -2;
1257            }
1258          t = readServiceFile (m, tmps1, &s1, tmpsn);
1259          free (tmpsn);
1260          if (t < 0)
1261            {
1262              map *tmp00 = getMapFromMaps (m, "lenv", "message");
1263              char tmp01[1024];
1264              if (tmp00 != NULL)
1265                sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
1266                         dp1->d_name, tmp00->value);
1267              else
1268                sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
1269                         dp1->d_name);
1270              setMapInMaps(m,"lenv","message",tmp01);
1271              setMapInMaps(m,"lenv","type","InternalError");
1272              return -1;
1273            }
1274          if(strncasecmp(registryKeys[i],"implementation",14)==0){
1275            inheritance(*r,&s1);
1276          }
1277          addServiceToRegistry(r,registryKeys[i],s1);
1278          freeService (&s1);
1279          free (s1);
1280          scount++;
1281        }
1282    }
1283    (void) closedir (dirp1);
1284  }
1285  return 0;
1286}
1287
1288/**
1289 * Create a string containing the basic error message.
1290 *
1291 * @param pmConf the main configuration maps pointer
1292 * @return a new char* containing the error message (ressource should be freed)
1293 */
1294char* produceErrorMessage(maps* pmConf){
1295  char *pacTmp;
1296  map *pmLenv=getMapFromMaps(pmConf,"lenv","message");
1297  if(pmLenv!=NULL){
1298    pacTmp=(char*)malloc((strlen(pmLenv->value)+strlen(_("Unable to run the Service. The message returned back by the Service was the following: "))+1)*sizeof(char));
1299    sprintf(pacTmp,_("Unable to run the Service. The message returned back by the Service was the following: %s"),pmLenv->value);
1300  }
1301  else{
1302    pacTmp=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
1303    sprintf(pacTmp,"%s",_("Unable to run the Service. No more information was returned back by the Service."));
1304  }
1305  return pacTmp;
1306}
1307
1308#ifdef WIN32
1309/**
1310 * Create a KVP request for executing background task.
1311 * TODO: use the XML request in case of input POST request.
1312 *
1313 * @param m the maps containing the parameters from the main.cfg file
1314 * @param length the total length of the KVP parameters
1315 * @param type
1316 */
1317char* getMapsAsKVP(maps* m,int length,int type){
1318  char *dataInputsKVP=(char*) malloc(length*sizeof(char));
1319  char *dataInputsKVPi=NULL;
1320  maps* curs=m;
1321  int i=0;
1322  while(curs!=NULL){
1323    map *inRequest=getMap(curs->content,"inRequest");
1324    map *hasLength=getMap(curs->content,"length");
1325    if((inRequest!=NULL && strncasecmp(inRequest->value,"true",4)==0) ||
1326       inRequest==NULL){
1327      if(i==0)
1328        if(type==0){
1329          sprintf(dataInputsKVP,"%s=",curs->name);
1330          if(hasLength!=NULL){
1331            dataInputsKVPi=(char*)malloc((strlen(curs->name)+2)*sizeof(char));
1332            sprintf(dataInputsKVPi,"%s=",curs->name);
1333          }
1334        }
1335        else
1336          sprintf(dataInputsKVP,"%s",curs->name);
1337      else{
1338        char *temp=zStrdup(dataInputsKVP);
1339        if(type==0)
1340          sprintf(dataInputsKVP,"%s;%s=",temp,curs->name);
1341        else
1342          sprintf(dataInputsKVP,"%s;%s",temp,curs->name);
1343      }
1344      map* icurs=curs->content;
1345      if(type==0){
1346        char *temp=zStrdup(dataInputsKVP);
1347        if(getMap(curs->content,"xlink:href")!=NULL)
1348          sprintf(dataInputsKVP,"%sReference",temp);
1349        else{
1350          if(hasLength!=NULL){
1351            int j;
1352            for(j=0;j<atoi(hasLength->value);j++){
1353              map* tmp0=getMapArray(curs->content,"value",j);
1354              if(j==0)
1355                free(temp);
1356              temp=zStrdup(dataInputsKVP);
1357              if(j==0)
1358                sprintf(dataInputsKVP,"%s%s",temp,tmp0->value);
1359              else
1360                sprintf(dataInputsKVP,"%s;%s%s",temp,dataInputsKVPi,tmp0->value);
1361            }
1362          }
1363          else
1364            sprintf(dataInputsKVP,"%s%s",temp,icurs->value);
1365        }
1366        free(temp);
1367      }
1368      while(icurs!=NULL){
1369        if(strncasecmp(icurs->name,"value",5)!=0 &&
1370           strncasecmp(icurs->name,"mimeType_",9)!=0 &&
1371           strncasecmp(icurs->name,"dataType_",9)!=0 &&
1372           strncasecmp(icurs->name,"size",4)!=0 &&
1373           strncasecmp(icurs->name,"length",4)!=0 &&
1374           strncasecmp(icurs->name,"isArray",7)!=0 &&
1375           strcasecmp(icurs->name,"Reference")!=0 &&
1376           strcasecmp(icurs->name,"minOccurs")!=0 &&
1377           strcasecmp(icurs->name,"maxOccurs")!=0 &&
1378           strncasecmp(icurs->name,"fmimeType",9)!=0 &&
1379           strcasecmp(icurs->name,"inRequest")!=0){
1380          char *itemp=zStrdup(dataInputsKVP);
1381          if(strcasecmp(icurs->name,"xlink:href")!=0)
1382            sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,icurs->value);
1383          else
1384            sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,url_encode(icurs->value));
1385          free(itemp);
1386        }
1387        icurs=icurs->next;
1388      }
1389    }
1390    curs=curs->next;
1391    i++;
1392  }
1393  return dataInputsKVP;
1394}
1395#endif
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

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