source: branches/prototype-v0/zoo-project/zoo-kernel/server_internal.c @ 933

Last change on this file since 933 was 933, checked in by knut, 5 years ago

Resolve certain string-related type conflicts, e.g., char* vs. const char* or char[N], that may cause errors in some build environments. Resolve a problem with the include order of fcgi_stdio.h (note: should verify that this harmonizes with resolution of same problem in trunk).

  • Property svn:keywords set to Id
File size: 36.9 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  fseek(file, 0, SEEK_END);
376  zStatStruct f_status;
377  int s=zStat(filename, &f_status);
378  sprintf(rsize,"%lld",f_status.st_size);
379  rewind(file);
380  if(getMap(content,"storage")==NULL){
381    map* memUse=getMapFromMaps(m,"main","memory");
382    if(memUse==NULL || strncmp(memUse->value,"load",4)==0){
383      map* tmpMap1=getMap(content,"value");
384      if(tmpMap1==NULL){
385        addToMap(content,"value","");
386        tmpMap1=getMap(content,"value");
387      }
388      free(tmpMap1->value);
389      tmpMap1->value=(char*) malloc((f_status.st_size+1)*sizeof(char));
390      if(tmpMap1->value==NULL){
391        setMapInMaps(m,"lenv","message","Unable to allocate the memory required to read the produced file.");
392      }
393      fread(&tmpMap1->value,1,f_status.st_size,file);
394      tmpMap1->value[f_status.st_size]=0;
395    }
396  }
397  fclose(file); 
398  addToMap(content,"size",rsize);
399}
400
401
402/**
403 * Write a file from value and length
404 *
405 * @param fname the file name
406 * @param val the value
407 * @param length the value length
408 */
409int writeFile(char* fname,char* val,int length){
410  FILE* of=fopen(fname,"wb");
411  if(of==NULL){
412    return -1;
413  }
414  size_t ret=fwrite(val,sizeof(char),length,of);
415  if(ret<length){
416    fprintf(stderr,"Write error occurred!\n");
417    fclose(of);
418    return -1;
419  }
420  fclose(of);
421  return 1;
422}
423
424/**
425 * Dump all values in a maps as files
426 *
427 * @param main_conf the maps containing the settings of the main.cfg file
428 * @param in the maps containing values to dump as files
429 */
430void dumpMapsValuesToFiles(maps** main_conf,maps** in){
431  map* tmpPath=getMapFromMaps(*main_conf,"main","tmpPath");
432  map* tmpUrl=getMapFromMaps(*main_conf,"main","tmpUrl");
433  map* tmpSid=getMapFromMaps(*main_conf,"lenv","usid");
434  maps* inputs=*in;
435  int length=0;
436  while(inputs!=NULL){
437    if(getMap(inputs->content,"mimeType")!=NULL &&
438       getMap(inputs->content,"cache_file")==NULL){
439      map* cMap=inputs->content;
440      if(getMap(cMap,"length")!=NULL){
441        map* tmpLength=getMap(cMap,"length");
442        int len=atoi(tmpLength->value);
443        int k=0;
444        for(k=0;k<len;k++){
445          map* cMimeType=getMapArray(cMap,"mimeType",k);
446          map* cValue=getMapArray(cMap,"value",k);
447          map* cSize=getMapArray(cMap,"size",k);
448          char file_ext[32];
449          getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
450          char* val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
451          sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,k,file_ext);
452          length=0;
453          if(cSize!=NULL){
454            length=atoi(cSize->value);
455          }else
456            length=strlen(cValue->value);
457          writeFile(val,cValue->value,length);
458          setMapArray(cMap,"cache_file",k,val);
459          free(val);
460          val=(char*)malloc((strlen(tmpUrl->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
461          sprintf(val,"%s/Input_%s_%s_%d.%s",tmpUrl->value,inputs->name,tmpSid->value,k,file_ext);
462          setMapArray(cMap,"cache_url",k,val);
463          setMapArray(cMap,"byValue",k,"true");
464          free(val);
465        }
466      }else{
467        int length=0;
468        map* cMimeType=getMap(cMap,"mimeType");
469        map* cValue=getMap(cMap,"value");
470        map* cSize=getMap(cMap,"size");
471        char file_ext[32];
472        getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
473        char *val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
474        sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,0,file_ext);
475        if(cSize!=NULL){
476          length=atoi(cSize->value);
477        }else
478          length=strlen(cValue->value);
479        writeFile(val,cValue->value,length);
480        addToMap(cMap,"cache_file",val);
481        free(val);
482        val=(char*)malloc((strlen(tmpUrl->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
483        sprintf(val,"%s/Input_%s_%s_%d.%s",tmpUrl->value,inputs->name,tmpSid->value,0,file_ext);
484        addToMap(cMap,"cache_url",val);
485        addToMap(cMap,"byValue",val);
486        free(val);
487      }
488    }
489    inputs=inputs->next;
490  }
491}
492
493
494/**
495 * Base64 encoding of a char*
496 *
497 * @param input the value to encode
498 * @param length the value length
499 * @return the buffer containing the base64 value
500 * @warning make sure to free the returned value
501 */
502char *base64(const char *input, int length)
503{
504  BIO *bmem, *b64;
505  BUF_MEM *bptr;
506
507  b64 = BIO_new(BIO_f_base64());
508  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
509  bmem = BIO_new(BIO_s_mem());
510  b64 = BIO_push(b64, bmem);
511  BIO_write(b64, input, length);
512  BIO_flush(b64);
513  BIO_get_mem_ptr(b64, &bptr);
514
515  char *buff = (char *)malloc((bptr->length+1)*sizeof(char));
516  memcpy(buff, bptr->data, bptr->length);
517  buff[bptr->length] = 0;
518
519  BIO_free_all(b64);
520
521  return buff;
522}
523
524/**
525 * Base64 decoding of a char*
526 *
527 * @param input the value to decode
528 * @param length the value length
529 * @param red the value length
530 * @return the buffer containing the base64 value
531 * @warning make sure to free the returned value
532 */
533char *base64d(const char *input, int length,int* red)
534{
535  BIO *b64, *bmem;
536
537  char *buffer = (char *)malloc(length);
538  if(buffer){
539    memset(buffer, 0, length);
540    b64 = BIO_new(BIO_f_base64());
541    if(b64){
542      bmem = BIO_new_mem_buf((unsigned char*)input,length);
543      bmem = BIO_push(b64, bmem);
544      *red=BIO_read(bmem, buffer, length);
545      buffer[length-1]=0;
546      BIO_free_all(bmem);
547    }
548  }
549  return buffer;
550}
551
552/**
553 * Read Base64 value and split it value by lines of 64 char.
554 *
555 * @param in the map containing the value to split
556 */
557void readBase64(map **in){
558  char *res = NULL;
559  char *curs = (*in)->value;
560  int i = 0;
561  for (i = 0; i <= strlen ((*in)->value) / 64;
562       i++)
563    {
564      if (res == NULL)
565        res =
566          (char *) malloc (65 * sizeof (char));
567      else
568        res =
569          (char *) realloc (res,
570                            (((i + 1) * 65) +
571                             i) * sizeof (char));
572      int csize = i * 65;
573      strncpy (res + csize, curs, 64);
574      if (i == strlen ((*in)->value) / 64)
575        strcat (res, "\n\0");
576      else
577        {
578          strncpy (res + (((i + 1) * 64) + i),
579                   "\n\0", 2);
580          curs += 64;
581        }
582    }
583  free ((*in)->value);
584  (*in)->value = zStrdup (res);
585  free (res);
586}
587
588
589/**
590 * Add the default values defined in the zcfg to a maps.
591 *
592 * @param out the maps containing the inputs or outputs given in the initial
593 *  HTTP request
594 * @param in the description of all inputs or outputs available for a service
595 * @param m the maps containing the settings of the main.cfg file
596 * @param type 0 for inputs and 1 for outputs
597 * @param err the map to store potential missing mandatory input parameters or
598 *  wrong output names depending on the type.
599 * @return "" if no error was detected, the name of last input or output causing
600 *  an error.
601 */
602char* addDefaultValues(maps** out,elements* in,maps* m,int type,map** err){
603  static char EMPTY[] = "";
604  map *res=*err;
605  elements* tmpInputs=in;
606  elements* tmpInputss=NULL;
607  maps* out1=*out;
608  maps* out1s=NULL;
609  char *result=NULL;
610  int nb=0;
611  int inb=0;
612 loopOnInputs:
613  if(type==1){
614    while(out1!=NULL){
615      if(getElements(in,out1->name)==NULL){
616        if(res==NULL){
617          res=createMap("value",out1->name);
618        }else{
619          setMapArray(res,"value",nb,out1->name);
620        }
621        nb++;
622        result=out1->name;
623      }
624      inb++;
625      out1=out1->next;
626    }
627    if(res!=NULL){
628      fflush(stderr);
629      *err=res;
630      return result;
631    }
632    if(out1==NULL && inb>=1)
633      out1=*out;
634  }
635  while(tmpInputs!=NULL){
636    maps *tmpMaps=getMaps(out1,tmpInputs->name);
637    if(tmpMaps==NULL){
638      maps* tmpMaps2=createMaps(tmpInputs->name);
639      if(type==0){
640        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
641        if(tmpMapMinO!=NULL){
642          if(atoi(tmpMapMinO->value)>=1){
643            freeMaps(&tmpMaps2);
644            free(tmpMaps2);
645            if(res==NULL){
646              res=createMap("value",tmpInputs->name);
647            }else{
648              setMapArray(res,"value",nb,tmpInputs->name);
649            }
650            nb++;
651            result=tmpInputs->name;
652          }
653          else{
654            if(tmpMaps2->content==NULL)
655              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
656            else
657              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
658          }
659        }
660        if(res==NULL){
661          map* tmpMaxO0=getMap(tmpInputs->content,"useMapserver");
662          if(tmpMaxO0!=NULL){
663            if(tmpMaps2->content==NULL)
664              tmpMaps2->content=createMap("useMapserver",tmpMaxO0->value);
665            else
666              addToMap(tmpMaps2->content,"useMapserver",tmpMaxO0->value);
667          }
668          map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
669          if(tmpMaxO!=NULL){
670            if(tmpMaps2->content==NULL)
671              tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
672            else
673              addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
674          }
675          map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
676          if(tmpMaxMB!=NULL){
677            if(tmpMaps2->content==NULL)
678              tmpMaps2->content=createMap("maximumMegabytes",tmpMaxMB->value);
679            else
680              addToMap(tmpMaps2->content,"maximumMegabytes",tmpMaxMB->value);
681          }
682        }
683      }
684     
685      if(res==NULL){
686        iotype* tmpIoType=tmpInputs->defaults;
687        if(tmpIoType!=NULL){
688          map* tmpm=tmpIoType->content;
689          while(tmpm!=NULL){
690            if(tmpMaps2->content==NULL)
691              tmpMaps2->content=createMap(tmpm->name,tmpm->value);
692            else{
693              addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
694            }
695            tmpm=tmpm->next;
696          }
697        }
698        if(tmpMaps2->content==NULL){
699          tmpMaps2->content=createMap("inRequest","false");
700          dumpMaps(tmpMaps2);
701        }
702        else
703          addToMap(tmpMaps2->content,"inRequest","false");
704        if(type==0){
705          map *tmpMap=getMap(tmpMaps2->content,"value");
706          if(tmpMap==NULL)
707            addToMap(tmpMaps2->content,"value","NULL");
708        }
709        elements* tmpElements=getElements(in,tmpMaps2->name);
710        if(tmpElements!=NULL && tmpElements->child!=NULL){
711          char *res=addDefaultValues(&tmpMaps2->child,tmpElements->child,m,type,err);
712          if(strlen(res)>0){
713            return res;
714          }
715        }
716
717        if(out1==NULL){
718          *out=dupMaps(&tmpMaps2);
719          out1=*out;
720        }
721        else
722          addMapsToMaps(&out1,tmpMaps2);
723        freeMap(&tmpMaps2->content);
724        free(tmpMaps2->content);
725        tmpMaps2->content=NULL;
726        freeMaps(&tmpMaps2);
727        free(tmpMaps2);
728        tmpMaps2=NULL;
729      }
730    }
731    else /*toto*/{ 
732      iotype* tmpIoType=NULL;
733      if(tmpMaps->content!=NULL){
734        tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
735                                       tmpMaps->content);
736        if(type==0) {
737          /**
738           * In case of an Input maps, then add the minOccurs and maxOccurs to the
739           * content map.
740           */
741          const char* keys[4]={
742            "minOccurs",
743            "maxOccurs",
744            "maximumMegabytes",
745            "useMapserver"
746          };
747          int i=0;
748          for(i=0;i<4;i++){
749            map* tmpMap1=getMap(tmpInputs->content,keys[i]);
750            if(tmpMap1!=NULL){
751              addToMap(tmpMaps->content,keys[i],tmpMap1->value);
752            }
753          }
754          /**
755           * Parsing BoundingBoxData, fill the following map and then add it to
756           * the content map of the Input maps:
757           * lowerCorner, upperCorner, srs and dimensions
758           * cf. parseBoundingBox
759           */
760          if(tmpInputs->format!=NULL && strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
761            maps* tmpI=getMaps(*out,tmpInputs->name);
762            if(tmpI!=NULL){
763              map* tmpV=getMap(tmpI->content,"value");
764              if(tmpV!=NULL){
765                char *tmpVS=zStrdup(tmpV->value);
766                map* tmp=parseBoundingBox(tmpVS);
767                free(tmpVS);
768                map* tmpC=tmp;
769                while(tmpC!=NULL){
770                  addToMap(tmpMaps->content,tmpC->name,tmpC->value);
771                  tmpC=tmpC->next;
772                }
773                freeMap(&tmp);
774                free(tmp);
775              }
776            }
777          }
778        }
779      }else{
780        if(tmpInputs!=NULL){
781          tmpIoType=tmpInputs->defaults;
782        }
783      }
784
785      if(tmpIoType!=NULL){
786        map* tmpContent=tmpIoType->content;
787        map* cval=NULL;
788        int hasPassed=-1;
789        while(tmpContent!=NULL){
790          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
791#ifdef DEBUG
792            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
793#endif
794            if(tmpMaps->content==NULL)
795              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
796            else
797              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
798           
799            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
800              map* length=getMap(tmpMaps->content,"length");
801              int i;
802              char *tcn=zStrdup(tmpContent->name);
803              for(i=1;i<atoi(length->value);i++){
804#ifdef DEBUG
805                dumpMap(tmpMaps->content);
806                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
807#endif
808                int len=strlen((char*) tcn);
809                char *tmp1=(char *)malloc((len+10)*sizeof(char));
810                sprintf(tmp1,"%s_%d",tcn,i);
811#ifdef DEBUG
812                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
813#endif
814                addToMap(tmpMaps->content,tmp1,tmpContent->value);
815                free(tmp1);
816                hasPassed=1;
817              }
818              free(tcn);
819            }
820          }
821          tmpContent=tmpContent->next;
822        }
823#ifdef USE_MS
824        /**
825         * check for useMapServer presence
826         */
827        if(tmpIoType!=NULL){
828          map* tmpCheck=getMap(tmpIoType->content,"useMapserver");
829          if(tmpCheck!=NULL && strncasecmp(tmpCheck->value,"true",4)==0){
830            // Get the default value
831            addToMap(tmpMaps->content,"useMapserver","true");
832            tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
833            tmpCheck=getMap(tmpMaps->content,"mimeType");
834            addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
835            map* cursor=tmpIoType->content;
836            while(cursor!=NULL){
837              addToMap(tmpMaps->content,cursor->name,cursor->value);
838              cursor=cursor->next;
839            }
840         
841            cursor=tmpInputs->content;
842            while(cursor!=NULL){
843              if(strcasecmp(cursor->name,"Title")==0 ||
844                 strcasecmp(cursor->name,"Abstract")==0)
845                addToMap(tmpMaps->content,cursor->name,cursor->value);
846              cursor=cursor->next;
847            }
848          }
849        }
850#endif
851      }
852      if(tmpMaps->content==NULL)
853        tmpMaps->content=createMap("inRequest","true");
854      else
855        addToMap(tmpMaps->content,"inRequest","true");
856      elements* tmpElements=getElements(in,tmpMaps->name);
857      if(/*tmpMaps->child!=NULL && */tmpElements!=NULL && tmpElements->child!=NULL){
858        char *res=addDefaultValues(&tmpMaps->child,tmpElements->child,m,type,err);
859        if(strlen(res)>0){
860          return res;
861        }
862      }
863    }
864    if(tmpInputs->child!=NULL){
865      tmpInputss=tmpInputs->next;
866      tmpInputs=tmpInputs->child;
867      if(tmpMaps!=NULL){
868        out1=tmpMaps->child;
869        out1s=tmpMaps;
870      }
871    }
872    tmpInputs=tmpInputs->next;
873  }
874  if(tmpInputss!=NULL){
875    out1=out1s;
876    tmpInputs=tmpInputss;
877    tmpInputss=NULL;
878    out1s=NULL;
879    goto loopOnInputs;
880  }
881  if(res!=NULL){
882    *err=res;
883    return result;
884  }
885  return EMPTY;
886}
887
888/**
889 * Access the last error message returned by the OS when trying to dynamically
890 * load a shared library.
891 *
892 * @return the last error message
893 * @warning The character string returned from getLastErrorMessage resides
894 * in a static buffer. The application should not write to this
895 * buffer or attempt to free() it.
896 */ 
897char* getLastErrorMessage() {                                             
898#ifdef WIN32
899  LPVOID lpMsgBuf;
900  DWORD errCode = GetLastError();
901  static char msg[ERROR_MSG_MAX_LENGTH];
902  size_t i;
903 
904  DWORD length = FormatMessage(
905                               FORMAT_MESSAGE_ALLOCATE_BUFFER | 
906                               FORMAT_MESSAGE_FROM_SYSTEM |
907                               FORMAT_MESSAGE_IGNORE_INSERTS,
908                               NULL,
909                               errCode,
910                               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
911                               (LPTSTR) &lpMsgBuf,
912                               0, NULL );       
913 
914#ifdef UNICODE         
915  wcstombs_s( &i, msg, ERROR_MSG_MAX_LENGTH,
916              (wchar_t*) lpMsgBuf, _TRUNCATE );
917#else
918  strcpy_s( msg, ERROR_MSG_MAX_LENGTH,
919            (char *) lpMsgBuf );               
920#endif 
921  LocalFree(lpMsgBuf);
922
923  return msg;
924#else
925  return dlerror();
926#endif
927}
928
929#include <dirent.h>
930#ifndef RELY_ON_DB
931/**
932 * Read the Result file (.res).
933 *
934 * @param conf the maps containing the setting of the main.cfg file
935 * @param pid the service identifier (usid key from the [lenv] section)
936 */
937void readFinalRes(maps* conf,char* pid,map* statusInfo){
938  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
939  char* fbkpid =
940    (char *)
941    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
942  sprintf (fbkpid, "%s/%s.res", r_inputs->value, pid);
943  struct stat file_status;
944  int istat = stat (fbkpid, &file_status);
945  if (istat == 0 && file_status.st_size > 0)
946    {
947      maps *res = (maps *) malloc (MAPS_SIZE);
948      conf_read (fbkpid, res);
949      res->child=NULL;
950      map* status=getMapFromMaps(res,"status","status");
951      addToMap(statusInfo,"Status",status->value);
952      freeMaps(&res);
953      free(res);
954    }
955  else
956    addToMap(statusInfo,"Status","Failed"); 
957  free(fbkpid);
958}
959
960/**
961 * Check if a service is running.
962 *
963 * @param conf the maps containing the setting of the main.cfg file
964 * @param pid the unique service identifier (usid from the lenv section)
965 * @return 1 in case the service is still running, 0 otherwise
966 */
967int isRunning(maps* conf,char* pid){
968  int res=0;
969  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
970  char* fbkpid =
971    (char *)
972    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
973  sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid);
974  FILE* f0 = fopen (fbkpid, "r");
975  if(f0!=NULL){
976    fclose(f0);
977    res=1;
978  }
979  free(fbkpid);
980  return res;
981}
982#else
983#include "sqlapi.h"
984#endif
985
986/**
987 * Run GetStatus requests.
988 *
989 * @param conf the maps containing the setting of the main.cfg file
990 * @param pid the service identifier (usid key from the [lenv] section)
991 * @param req the request (GetStatus / GetResult)
992 */
993void runGetStatus(maps* conf,char* pid,char* req){
994  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
995  char *sid=getStatusId(conf,pid);
996  if(sid==NULL){
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    map* statusInfo=createMap("JobID",pid);
1001    if(isRunning(conf,pid)>0){
1002      if(strncasecmp(req,"GetResult",strlen(req))==0){
1003        errorException (conf, _("The result for the requested JobID has not yet been generated. The service is currently running."),
1004                        "ResultNotReady", pid);
1005        return;
1006      }
1007      else
1008        if(strncasecmp(req,"GetStatus",strlen(req))==0){
1009          addToMap(statusInfo,"Status","Running");
1010          char* tmpStr=_getStatus(conf,pid);
1011          if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
1012            char *tmpStr1=zStrdup(tmpStr);
1013            char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
1014            free(tmpStr);
1015            tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
1016            addToMap(statusInfo,"PercentCompleted",tmpStr1);
1017            addToMap(statusInfo,"Message",tmpStr0);
1018            free(tmpStr0);
1019            free(tmpStr1);
1020          }
1021        }
1022    }
1023    else{
1024      if(strncasecmp(req,"GetResult",strlen(req))==0){
1025        char* result=_getStatusFile(conf,pid);
1026        if(result!=NULL){
1027          char *encoding=getEncoding(conf);
1028          printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1029          printf("%s",result);
1030          fflush(stdout);
1031          free(sid);
1032          freeMap(&statusInfo);
1033          free(statusInfo);
1034          free(result);
1035          return;
1036        }else{
1037          errorException (conf, _("The result for the requested JobID has not yet been generated. The service ends but it still needs to produce the outputs."),
1038                          "ResultNotReady", pid);
1039          freeMap(&statusInfo);
1040          free(statusInfo);
1041          return;
1042        }
1043      }else
1044        if(strncasecmp(req,"GetStatus",strlen(req))==0){
1045          readFinalRes(conf,pid,statusInfo);
1046          char* tmpStr=_getStatus(conf,pid);
1047          if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
1048            char *tmpStr1=zStrdup(tmpStr);
1049            char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
1050            free(tmpStr);
1051            tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
1052            addToMap(statusInfo,"PercentCompleted",tmpStr1);
1053            addToMap(statusInfo,"Message",tmpStr0);
1054            free(tmpStr0);
1055            free(tmpStr1);
1056          }
1057        }
1058    }
1059    free(sid);
1060    printStatusInfo(conf,statusInfo,req);
1061    freeMap(&statusInfo);
1062    free(statusInfo);
1063  }
1064  return;
1065}
1066
1067/**
1068 * Run Dismiss requests.
1069 *
1070 * @param conf the maps containing the setting of the main.cfg file
1071 * @param pid the service identifier (usid key from the [lenv] section)
1072 */
1073void runDismiss(maps* conf,char* pid){
1074  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
1075  char *sid=getStatusId(conf,pid);
1076  if(sid==NULL){
1077    errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
1078                    "NoSuchJob", pid);
1079  }else{
1080    // We should send the Dismiss request to the target host if it differs
1081    char* fbkpid =
1082      (char *)
1083      malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
1084    sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid);
1085    FILE* f0 = fopen (fbkpid, "r");
1086    if(f0!=NULL){
1087      long flen;
1088      char *fcontent;
1089      fseek (f0, 0, SEEK_END);
1090      flen = ftell (f0);
1091      fseek (f0, 0, SEEK_SET);
1092      fcontent = (char *) malloc ((flen + 1) * sizeof (char));
1093      fread(fcontent,flen,1,f0);
1094      fcontent[flen]=0;
1095      fclose(f0);
1096#ifndef WIN32
1097      kill(atoi(fcontent),SIGKILL);
1098#else
1099      HANDLE myZooProcess=OpenProcess(PROCESS_ALL_ACCESS,false,atoi(fcontent));
1100      TerminateProcess(myZooProcess,1);
1101      CloseHandle(myZooProcess);
1102#endif
1103      free(fcontent);
1104    }
1105    free(fbkpid);
1106    struct dirent *dp;
1107    DIR *dirp = opendir(r_inputs->value);
1108    char fileName[1024];
1109    int hasFile=-1;
1110    if(dirp!=NULL){
1111      while ((dp = readdir(dirp)) != NULL){
1112#ifdef DEBUG
1113        fprintf(stderr,"File : %s searched : %s\n",dp->d_name,tmp);
1114#endif
1115        if(strstr(dp->d_name,pid)!=0){
1116          sprintf(fileName,"%s/%s",r_inputs->value,dp->d_name);
1117          if(zUnlink(fileName)!=0){
1118            errorException (conf, 
1119                            _("The job cannot be removed, a file cannot be removed"),
1120                            "NoApplicableCode", NULL);
1121            return;
1122          }
1123        }
1124      }
1125    }
1126#ifdef RELY_ON_DB
1127    removeService(conf,pid);
1128#endif
1129    /* No need to call 7_1 when an execution is dismissed.
1130      fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
1131      invokeCallback(conf,NULL,NULL,7,1);
1132      fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
1133    */
1134    map* statusInfo=createMap("JobID",pid);
1135    addToMap(statusInfo,"Status","Dismissed");
1136    printStatusInfo(conf,statusInfo, (char*) "Dismiss");
1137    free(statusInfo);
1138  }
1139  return;
1140}
1141
1142extern int getServiceFromFile (maps *, const char *, service **);
1143
1144/**
1145 * Parse the service file using getServiceFromFile or use getServiceFromYAML
1146 * if YAML support was activated.
1147 *
1148 * @param conf the conf maps containing the main.cfg settings
1149 * @param file the file name to parse
1150 * @param service the service to update witht the file content
1151 * @param name the service name
1152 * @return true if the file can be parsed or false
1153 * @see getServiceFromFile, getServiceFromYAML
1154 */
1155int readServiceFile (maps * conf, char *file, service ** service, char *name){
1156  int t = getServiceFromFile (conf, file, service);
1157#ifdef YAML
1158  if (t < 0){
1159    t = getServiceFromYAML (conf, file, service, name);
1160  }
1161#endif
1162  return t;
1163}
1164
1165/**
1166 * Create the profile registry.
1167 *
1168 * The profile registry is optional (created only if the registry key is
1169 * available in the [main] section of the main.cfg file) and can be used to
1170 * store the profiles hierarchy. The registry is a directory which should
1171 * contain the following sub-directories:
1172 *  * concept: direcotry containing .html files describing concept
1173 *  * generic: directory containing .zcfg files for wps:GenericProcess
1174 *  * implementation: directory containing .zcfg files for wps:Process
1175 *
1176 * @param m the conf maps containing the main.cfg settings
1177 * @param r the registry to update
1178 * @param reg_dir the resgitry
1179 * @return 0 if the resgitry is null or was correctly updated, -1 on failure
1180 */
1181int createRegistry (maps* m,registry ** r, char *reg_dir)
1182{
1183  char registryKeys[3][15]={
1184    "concept",
1185    "generic",
1186    "implementation"
1187  };
1188  int scount = 0,i=0;
1189  if (reg_dir == NULL)
1190    return 0;
1191  for(i=0;i<3;i++){
1192    char * tmpName =
1193      (char *) malloc ((strlen (reg_dir) + strlen (registryKeys[i]) + 2) *
1194                       sizeof (char));
1195    sprintf (tmpName, "%s/%s", reg_dir, registryKeys[i]);
1196   
1197    DIR *dirp1 = opendir (tmpName);
1198    if(dirp1==NULL){
1199      setMapInMaps(m,"lenv","message",_("Unable to open the registry directory."));
1200      setMapInMaps(m,"lenv","type","InternalError");
1201      return -1;
1202    }
1203    struct dirent *dp1;
1204    while ((dp1 = readdir (dirp1)) != NULL){
1205      char* extn = strstr(dp1->d_name, ".zcfg");
1206      if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
1207        {
1208          int t;
1209          char *tmps1=
1210            (char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) *
1211                             sizeof (char));
1212          sprintf (tmps1, "%s/%s", tmpName, dp1->d_name);
1213          char *tmpsn = zStrdup (dp1->d_name);
1214          tmpsn[strlen (tmpsn) - 5] = 0;
1215          service* s1 = (service *) malloc (SERVICE_SIZE);
1216          if (s1 == NULL)
1217            {
1218              setMapInMaps(m,"lenv","message",_("Unable to allocate memory."));
1219              setMapInMaps(m,"lenv","type","InternalError");
1220              return -2;
1221            }
1222          t = readServiceFile (m, tmps1, &s1, tmpsn);
1223          free (tmpsn);
1224          if (t < 0)
1225            {
1226              map *tmp00 = getMapFromMaps (m, "lenv", "message");
1227              char tmp01[1024];
1228              if (tmp00 != NULL)
1229                sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
1230                         dp1->d_name, tmp00->value);
1231              else
1232                sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
1233                         dp1->d_name);
1234              setMapInMaps(m,"lenv","message",tmp01);
1235              setMapInMaps(m,"lenv","type","InternalError");
1236              return -1;
1237            }
1238          if(strncasecmp(registryKeys[i],"implementation",14)==0){
1239            inheritance(*r,&s1);
1240          }
1241          addServiceToRegistry(r,registryKeys[i],s1);
1242          freeService (&s1);
1243          free (s1);
1244          scount++;
1245        }
1246    }
1247    (void) closedir (dirp1);
1248  }
1249  return 0;
1250}
1251
1252#ifdef WIN32
1253/**
1254 * Create a KVP request for executing background task.
1255 * TODO: use the XML request in case of input POST request.
1256 *
1257 * @param m the maps containing the parameters from the main.cfg file
1258 * @param length the total length of the KVP parameters
1259 * @param type
1260 */
1261char* getMapsAsKVP(maps* m,int length,int type){
1262  char *dataInputsKVP=(char*) malloc(length*sizeof(char));
1263  char *dataInputsKVPi=NULL;
1264  maps* curs=m;
1265  int i=0;
1266  while(curs!=NULL){
1267    map *inRequest=getMap(curs->content,"inRequest");
1268    map *hasLength=getMap(curs->content,"length");
1269    if((inRequest!=NULL && strncasecmp(inRequest->value,"true",4)==0) ||
1270       inRequest==NULL){
1271      if(i==0)
1272        if(type==0){
1273          sprintf(dataInputsKVP,"%s=",curs->name);
1274          if(hasLength!=NULL){
1275            dataInputsKVPi=(char*)malloc((strlen(curs->name)+2)*sizeof(char));
1276            sprintf(dataInputsKVPi,"%s=",curs->name);
1277          }
1278        }
1279        else
1280          sprintf(dataInputsKVP,"%s",curs->name);
1281      else{
1282        char *temp=zStrdup(dataInputsKVP);
1283        if(type==0)
1284          sprintf(dataInputsKVP,"%s;%s=",temp,curs->name);
1285        else
1286          sprintf(dataInputsKVP,"%s;%s",temp,curs->name);
1287      }
1288      map* icurs=curs->content;
1289      if(type==0){
1290        char *temp=zStrdup(dataInputsKVP);
1291        if(getMap(curs->content,"xlink:href")!=NULL)
1292          sprintf(dataInputsKVP,"%sReference",temp);
1293        else{
1294          if(hasLength!=NULL){
1295            int j;
1296            for(j=0;j<atoi(hasLength->value);j++){
1297              map* tmp0=getMapArray(curs->content,"value",j);
1298              if(j==0)
1299                free(temp);
1300              temp=zStrdup(dataInputsKVP);
1301              if(j==0)
1302                sprintf(dataInputsKVP,"%s%s",temp,tmp0->value);
1303              else
1304                sprintf(dataInputsKVP,"%s;%s%s",temp,dataInputsKVPi,tmp0->value);
1305            }
1306          }
1307          else
1308            sprintf(dataInputsKVP,"%s%s",temp,icurs->value);
1309        }
1310        free(temp);
1311      }
1312      while(icurs!=NULL){
1313        if(strncasecmp(icurs->name,"value",5)!=0 &&
1314           strncasecmp(icurs->name,"mimeType_",9)!=0 &&
1315           strncasecmp(icurs->name,"dataType_",9)!=0 &&
1316           strncasecmp(icurs->name,"size",4)!=0 &&
1317           strncasecmp(icurs->name,"length",4)!=0 &&
1318           strncasecmp(icurs->name,"isArray",7)!=0 &&
1319           strcasecmp(icurs->name,"Reference")!=0 &&
1320           strcasecmp(icurs->name,"minOccurs")!=0 &&
1321           strcasecmp(icurs->name,"maxOccurs")!=0 &&
1322           strncasecmp(icurs->name,"fmimeType",9)!=0 &&
1323           strcasecmp(icurs->name,"inRequest")!=0){
1324          char *itemp=zStrdup(dataInputsKVP);
1325          if(strcasecmp(icurs->name,"xlink:href")!=0)
1326            sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,icurs->value);
1327          else
1328            sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,url_encode(icurs->value));
1329          free(itemp);
1330        }
1331        icurs=icurs->next;
1332      }
1333    }
1334    curs=curs->next;
1335    i++;
1336  }
1337  return dataInputsKVP;
1338}
1339#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