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

Last change on this file since 936 was 921, checked in by djay, 6 years ago

Fix issue building with gcc 7.3.0

  • Property svn:keywords set to Id
File size: 36.8 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  map *res=*err;
604  elements* tmpInputs=in;
605  elements* tmpInputss=NULL;
606  maps* out1=*out;
607  maps* out1s=NULL;
608  char *result=NULL;
609  int nb=0;
610  int inb=0;
611 loopOnInputs:
612  if(type==1){
613    while(out1!=NULL){
614      if(getElements(in,out1->name)==NULL){
615        if(res==NULL){
616          res=createMap("value",out1->name);
617        }else{
618          setMapArray(res,"value",nb,out1->name);
619        }
620        nb++;
621        result=out1->name;
622      }
623      inb++;
624      out1=out1->next;
625    }
626    if(res!=NULL){
627      fflush(stderr);
628      *err=res;
629      return result;
630    }
631    if(out1==NULL && inb>=1)
632      out1=*out;
633  }
634  while(tmpInputs!=NULL){
635    maps *tmpMaps=getMaps(out1,tmpInputs->name);
636    if(tmpMaps==NULL){
637      maps* tmpMaps2=createMaps(tmpInputs->name);
638      if(type==0){
639        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
640        if(tmpMapMinO!=NULL){
641          if(atoi(tmpMapMinO->value)>=1){
642            freeMaps(&tmpMaps2);
643            free(tmpMaps2);
644            if(res==NULL){
645              res=createMap("value",tmpInputs->name);
646            }else{
647              setMapArray(res,"value",nb,tmpInputs->name);
648            }
649            nb++;
650            result=tmpInputs->name;
651          }
652          else{
653            if(tmpMaps2->content==NULL)
654              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
655            else
656              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
657          }
658        }
659        if(res==NULL){
660          map* tmpMaxO0=getMap(tmpInputs->content,"useMapserver");
661          if(tmpMaxO0!=NULL){
662            if(tmpMaps2->content==NULL)
663              tmpMaps2->content=createMap("useMapserver",tmpMaxO0->value);
664            else
665              addToMap(tmpMaps2->content,"useMapserver",tmpMaxO0->value);
666          }
667          map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
668          if(tmpMaxO!=NULL){
669            if(tmpMaps2->content==NULL)
670              tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
671            else
672              addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
673          }
674          map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
675          if(tmpMaxMB!=NULL){
676            if(tmpMaps2->content==NULL)
677              tmpMaps2->content=createMap("maximumMegabytes",tmpMaxMB->value);
678            else
679              addToMap(tmpMaps2->content,"maximumMegabytes",tmpMaxMB->value);
680          }
681        }
682      }
683     
684      if(res==NULL){
685        iotype* tmpIoType=tmpInputs->defaults;
686        if(tmpIoType!=NULL){
687          map* tmpm=tmpIoType->content;
688          while(tmpm!=NULL){
689            if(tmpMaps2->content==NULL)
690              tmpMaps2->content=createMap(tmpm->name,tmpm->value);
691            else{
692              addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
693            }
694            tmpm=tmpm->next;
695          }
696        }
697        if(tmpMaps2->content==NULL){
698          tmpMaps2->content=createMap("inRequest","false");
699          dumpMaps(tmpMaps2);
700        }
701        else
702          addToMap(tmpMaps2->content,"inRequest","false");
703        if(type==0){
704          map *tmpMap=getMap(tmpMaps2->content,"value");
705          if(tmpMap==NULL)
706            addToMap(tmpMaps2->content,"value","NULL");
707        }
708        elements* tmpElements=getElements(in,tmpMaps2->name);
709        if(tmpElements!=NULL && tmpElements->child!=NULL){
710          char *res=addDefaultValues(&tmpMaps2->child,tmpElements->child,m,type,err);
711          if(strlen(res)>0){
712            return res;
713          }
714        }
715
716        if(out1==NULL){
717          *out=dupMaps(&tmpMaps2);
718          out1=*out;
719        }
720        else
721          addMapsToMaps(&out1,tmpMaps2);
722        freeMap(&tmpMaps2->content);
723        free(tmpMaps2->content);
724        tmpMaps2->content=NULL;
725        freeMaps(&tmpMaps2);
726        free(tmpMaps2);
727        tmpMaps2=NULL;
728      }
729    }
730    else /*toto*/{ 
731      iotype* tmpIoType=NULL;
732      if(tmpMaps->content!=NULL){
733        tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
734                                       tmpMaps->content);
735        if(type==0) {
736          /**
737           * In case of an Input maps, then add the minOccurs and maxOccurs to the
738           * content map.
739           */
740          const char* keys[4]={
741            "minOccurs",
742            "maxOccurs",
743            "maximumMegabytes",
744            "useMapserver"
745          };
746          int i=0;
747          for(i=0;i<4;i++){
748            map* tmpMap1=getMap(tmpInputs->content,keys[i]);
749            if(tmpMap1!=NULL){
750              addToMap(tmpMaps->content,keys[i],tmpMap1->value);
751            }
752          }
753          /**
754           * Parsing BoundingBoxData, fill the following map and then add it to
755           * the content map of the Input maps:
756           * lowerCorner, upperCorner, srs and dimensions
757           * cf. parseBoundingBox
758           */
759          if(tmpInputs->format!=NULL && strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
760            maps* tmpI=getMaps(*out,tmpInputs->name);
761            if(tmpI!=NULL){
762              map* tmpV=getMap(tmpI->content,"value");
763              if(tmpV!=NULL){
764                char *tmpVS=zStrdup(tmpV->value);
765                map* tmp=parseBoundingBox(tmpVS);
766                free(tmpVS);
767                map* tmpC=tmp;
768                while(tmpC!=NULL){
769                  addToMap(tmpMaps->content,tmpC->name,tmpC->value);
770                  tmpC=tmpC->next;
771                }
772                freeMap(&tmp);
773                free(tmp);
774              }
775            }
776          }
777        }
778      }else{
779        if(tmpInputs!=NULL){
780          tmpIoType=tmpInputs->defaults;
781        }
782      }
783
784      if(tmpIoType!=NULL){
785        map* tmpContent=tmpIoType->content;
786        map* cval=NULL;
787        int hasPassed=-1;
788        while(tmpContent!=NULL){
789          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
790#ifdef DEBUG
791            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
792#endif
793            if(tmpMaps->content==NULL)
794              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
795            else
796              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
797           
798            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
799              map* length=getMap(tmpMaps->content,"length");
800              int i;
801              char *tcn=zStrdup(tmpContent->name);
802              for(i=1;i<atoi(length->value);i++){
803#ifdef DEBUG
804                dumpMap(tmpMaps->content);
805                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
806#endif
807                int len=strlen((char*) tcn);
808                char *tmp1=(char *)malloc((len+10)*sizeof(char));
809                sprintf(tmp1,"%s_%d",tcn,i);
810#ifdef DEBUG
811                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
812#endif
813                addToMap(tmpMaps->content,tmp1,tmpContent->value);
814                free(tmp1);
815                hasPassed=1;
816              }
817              free(tcn);
818            }
819          }
820          tmpContent=tmpContent->next;
821        }
822#ifdef USE_MS
823        /**
824         * check for useMapServer presence
825         */
826        if(tmpIoType!=NULL){
827          map* tmpCheck=getMap(tmpIoType->content,"useMapserver");
828          if(tmpCheck!=NULL && strncasecmp(tmpCheck->value,"true",4)==0){
829            // Get the default value
830            addToMap(tmpMaps->content,"useMapserver","true");
831            tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
832            tmpCheck=getMap(tmpMaps->content,"mimeType");
833            addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
834            map* cursor=tmpIoType->content;
835            while(cursor!=NULL){
836              addToMap(tmpMaps->content,cursor->name,cursor->value);
837              cursor=cursor->next;
838            }
839         
840            cursor=tmpInputs->content;
841            while(cursor!=NULL){
842              if(strcasecmp(cursor->name,"Title")==0 ||
843                 strcasecmp(cursor->name,"Abstract")==0)
844                addToMap(tmpMaps->content,cursor->name,cursor->value);
845              cursor=cursor->next;
846            }
847          }
848        }
849#endif
850      }
851      if(tmpMaps->content==NULL)
852        tmpMaps->content=createMap("inRequest","true");
853      else
854        addToMap(tmpMaps->content,"inRequest","true");
855      elements* tmpElements=getElements(in,tmpMaps->name);
856      if(/*tmpMaps->child!=NULL && */tmpElements!=NULL && tmpElements->child!=NULL){
857        char *res=addDefaultValues(&tmpMaps->child,tmpElements->child,m,type,err);
858        if(strlen(res)>0){
859          return res;
860        }
861      }
862    }
863    if(tmpInputs->child!=NULL){
864      tmpInputss=tmpInputs->next;
865      tmpInputs=tmpInputs->child;
866      if(tmpMaps!=NULL){
867        out1=tmpMaps->child;
868        out1s=tmpMaps;
869      }
870    }
871    tmpInputs=tmpInputs->next;
872  }
873  if(tmpInputss!=NULL){
874    out1=out1s;
875    tmpInputs=tmpInputss;
876    tmpInputss=NULL;
877    out1s=NULL;
878    goto loopOnInputs;
879  }
880  if(res!=NULL){
881    *err=res;
882    return result;
883  }
884  return "";
885}
886
887/**
888 * Access the last error message returned by the OS when trying to dynamically
889 * load a shared library.
890 *
891 * @return the last error message
892 * @warning The character string returned from getLastErrorMessage resides
893 * in a static buffer. The application should not write to this
894 * buffer or attempt to free() it.
895 */ 
896char* getLastErrorMessage() {                                             
897#ifdef WIN32
898  LPVOID lpMsgBuf;
899  DWORD errCode = GetLastError();
900  static char msg[ERROR_MSG_MAX_LENGTH];
901  size_t i;
902 
903  DWORD length = FormatMessage(
904                               FORMAT_MESSAGE_ALLOCATE_BUFFER | 
905                               FORMAT_MESSAGE_FROM_SYSTEM |
906                               FORMAT_MESSAGE_IGNORE_INSERTS,
907                               NULL,
908                               errCode,
909                               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
910                               (LPTSTR) &lpMsgBuf,
911                               0, NULL );       
912 
913#ifdef UNICODE         
914  wcstombs_s( &i, msg, ERROR_MSG_MAX_LENGTH,
915              (wchar_t*) lpMsgBuf, _TRUNCATE );
916#else
917  strcpy_s( msg, ERROR_MSG_MAX_LENGTH,
918            (char *) lpMsgBuf );               
919#endif 
920  LocalFree(lpMsgBuf);
921
922  return msg;
923#else
924  return dlerror();
925#endif
926}
927
928#include <dirent.h>
929#ifndef RELY_ON_DB
930/**
931 * Read the Result file (.res).
932 *
933 * @param conf the maps containing the setting of the main.cfg file
934 * @param pid the service identifier (usid key from the [lenv] section)
935 */
936void readFinalRes(maps* conf,char* pid,map* statusInfo){
937  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
938  char* fbkpid =
939    (char *)
940    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
941  sprintf (fbkpid, "%s/%s.res", r_inputs->value, pid);
942  struct stat file_status;
943  int istat = stat (fbkpid, &file_status);
944  if (istat == 0 && file_status.st_size > 0)
945    {
946      maps *res = (maps *) malloc (MAPS_SIZE);
947      conf_read (fbkpid, res);
948      res->child=NULL;
949      map* status=getMapFromMaps(res,"status","status");
950      addToMap(statusInfo,"Status",status->value);
951      freeMaps(&res);
952      free(res);
953    }
954  else
955    addToMap(statusInfo,"Status","Failed"); 
956  free(fbkpid);
957}
958
959/**
960 * Check if a service is running.
961 *
962 * @param conf the maps containing the setting of the main.cfg file
963 * @param pid the unique service identifier (usid from the lenv section)
964 * @return 1 in case the service is still running, 0 otherwise
965 */
966int isRunning(maps* conf,char* pid){
967  int res=0;
968  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
969  char* fbkpid =
970    (char *)
971    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
972  sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid); 
973  FILE* f0 = fopen (fbkpid, "r");
974  if(f0!=NULL){
975    fclose(f0);
976    res=1;
977  }
978  free(fbkpid);
979  return res;
980}
981#else
982#include "sqlapi.h"
983#endif
984
985/**
986 * Run GetStatus requests.
987 *
988 * @param conf the maps containing the setting of the main.cfg file
989 * @param pid the service identifier (usid key from the [lenv] section)
990 * @param req the request (GetStatus / GetResult)
991 */
992void runGetStatus(maps* conf,char* pid,char* req){
993  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
994  char *sid=getStatusId(conf,pid);
995  if(sid==NULL){
996    errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
997                    "NoSuchJob", pid);
998  }else{
999    map* statusInfo=createMap("JobID",pid);
1000    if(isRunning(conf,pid)>0){         
1001      if(strncasecmp(req,"GetResult",strlen(req))==0){
1002        errorException (conf, _("The result for the requested JobID has not yet been generated. The service is currently running."),
1003                        "ResultNotReady", pid);
1004        return;
1005      }
1006      else
1007        if(strncasecmp(req,"GetStatus",strlen(req))==0){
1008          addToMap(statusInfo,"Status","Running");
1009          char* tmpStr=_getStatus(conf,pid);
1010          if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
1011            char *tmpStr1=zStrdup(tmpStr);
1012            char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
1013            free(tmpStr);
1014            tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
1015            addToMap(statusInfo,"PercentCompleted",tmpStr1);
1016            addToMap(statusInfo,"Message",tmpStr0);
1017            free(tmpStr0);
1018            free(tmpStr1);
1019          }
1020        }
1021    }
1022    else{
1023      if(strncasecmp(req,"GetResult",strlen(req))==0){
1024        char* result=_getStatusFile(conf,pid);
1025        if(result!=NULL){
1026          char *encoding=getEncoding(conf);
1027          printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1028          printf("%s",result);
1029          fflush(stdout);
1030          free(sid);
1031          freeMap(&statusInfo);
1032          free(statusInfo);
1033          free(result);
1034          return;
1035        }else{
1036          errorException (conf, _("The result for the requested JobID has not yet been generated. The service ends but it still needs to produce the outputs."),
1037                          "ResultNotReady", pid);
1038          freeMap(&statusInfo);
1039          free(statusInfo);
1040          return;
1041        }
1042      }else
1043        if(strncasecmp(req,"GetStatus",strlen(req))==0){
1044          readFinalRes(conf,pid,statusInfo);
1045          char* tmpStr=_getStatus(conf,pid);
1046          if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
1047            char *tmpStr1=zStrdup(tmpStr);
1048            char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
1049            free(tmpStr);
1050            tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
1051            addToMap(statusInfo,"PercentCompleted",tmpStr1);
1052            addToMap(statusInfo,"Message",tmpStr0);
1053            free(tmpStr0);
1054            free(tmpStr1);
1055          }
1056        }
1057    }
1058    free(sid);
1059    printStatusInfo(conf,statusInfo,req);
1060    freeMap(&statusInfo);
1061    free(statusInfo);
1062  }
1063  return;
1064}
1065
1066/**
1067 * Run Dismiss requests.
1068 *
1069 * @param conf the maps containing the setting of the main.cfg file
1070 * @param pid the service identifier (usid key from the [lenv] section)
1071 */
1072void runDismiss(maps* conf,char* pid){
1073  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
1074  char *sid=getStatusId(conf,pid);
1075  if(sid==NULL){
1076    errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
1077                    "NoSuchJob", pid);
1078  }else{
1079    // We should send the Dismiss request to the target host if it differs
1080    char* fbkpid =
1081      (char *)
1082      malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
1083    sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid);
1084    FILE* f0 = fopen (fbkpid, "r");
1085    if(f0!=NULL){
1086      long flen;
1087      char *fcontent;
1088      fseek (f0, 0, SEEK_END);
1089      flen = ftell (f0);
1090      fseek (f0, 0, SEEK_SET);
1091      fcontent = (char *) malloc ((flen + 1) * sizeof (char));
1092      fread(fcontent,flen,1,f0);
1093      fcontent[flen]=0;
1094      fclose(f0);
1095#ifndef WIN32
1096      kill(atoi(fcontent),SIGKILL);
1097#else
1098      HANDLE myZooProcess=OpenProcess(PROCESS_ALL_ACCESS,false,atoi(fcontent));
1099      TerminateProcess(myZooProcess,1);
1100      CloseHandle(myZooProcess);
1101#endif
1102      free(fcontent);
1103    }
1104    free(fbkpid);
1105    struct dirent *dp;
1106    DIR *dirp = opendir(r_inputs->value);
1107    char fileName[1024];
1108    int hasFile=-1;
1109    if(dirp!=NULL){
1110      while ((dp = readdir(dirp)) != NULL){
1111#ifdef DEBUG
1112        fprintf(stderr,"File : %s searched : %s\n",dp->d_name,tmp);
1113#endif
1114        if(strstr(dp->d_name,pid)!=0){
1115          sprintf(fileName,"%s/%s",r_inputs->value,dp->d_name);
1116          if(zUnlink(fileName)!=0){
1117            errorException (conf, 
1118                            _("The job cannot be removed, a file cannot be removed"),
1119                            "NoApplicableCode", NULL);
1120            return;
1121          }
1122        }
1123      }
1124    }
1125#ifdef RELY_ON_DB
1126    removeService(conf,pid);
1127#endif
1128    /* No need to call 7_1 when an execution is dismissed.
1129      fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
1130      invokeCallback(conf,NULL,NULL,7,1);
1131      fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
1132    */
1133    map* statusInfo=createMap("JobID",pid);
1134    addToMap(statusInfo,"Status","Dismissed");
1135    printStatusInfo(conf,statusInfo,"Dismiss");
1136    free(statusInfo);
1137  }
1138  return;
1139}
1140
1141extern int getServiceFromFile (maps *, const char *, service **);
1142
1143/**
1144 * Parse the service file using getServiceFromFile or use getServiceFromYAML
1145 * if YAML support was activated.
1146 *
1147 * @param conf the conf maps containing the main.cfg settings
1148 * @param file the file name to parse
1149 * @param service the service to update witht the file content
1150 * @param name the service name
1151 * @return true if the file can be parsed or false
1152 * @see getServiceFromFile, getServiceFromYAML
1153 */
1154int readServiceFile (maps * conf, char *file, service ** service, char *name){
1155  int t = getServiceFromFile (conf, file, service);
1156#ifdef YAML
1157  if (t < 0){
1158    t = getServiceFromYAML (conf, file, service, name);
1159  }
1160#endif
1161  return t;
1162}
1163
1164/**
1165 * Create the profile registry.
1166 *
1167 * The profile registry is optional (created only if the registry key is
1168 * available in the [main] section of the main.cfg file) and can be used to
1169 * store the profiles hierarchy. The registry is a directory which should
1170 * contain the following sub-directories:
1171 *  * concept: direcotry containing .html files describing concept
1172 *  * generic: directory containing .zcfg files for wps:GenericProcess
1173 *  * implementation: directory containing .zcfg files for wps:Process
1174 *
1175 * @param m the conf maps containing the main.cfg settings
1176 * @param r the registry to update
1177 * @param reg_dir the resgitry
1178 * @return 0 if the resgitry is null or was correctly updated, -1 on failure
1179 */
1180int createRegistry (maps* m,registry ** r, char *reg_dir)
1181{
1182  char registryKeys[3][15]={
1183    "concept",
1184    "generic",
1185    "implementation"
1186  };
1187  int scount = 0,i=0;
1188  if (reg_dir == NULL)
1189    return 0;
1190  for(i=0;i<3;i++){
1191    char * tmpName =
1192      (char *) malloc ((strlen (reg_dir) + strlen (registryKeys[i]) + 2) *
1193                       sizeof (char));
1194    sprintf (tmpName, "%s/%s", reg_dir, registryKeys[i]);
1195   
1196    DIR *dirp1 = opendir (tmpName);
1197    if(dirp1==NULL){
1198      setMapInMaps(m,"lenv","message",_("Unable to open the registry directory."));
1199      setMapInMaps(m,"lenv","type","InternalError");
1200      return -1;
1201    }
1202    struct dirent *dp1;
1203    while ((dp1 = readdir (dirp1)) != NULL){
1204      char* extn = strstr(dp1->d_name, ".zcfg");
1205      if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
1206        {
1207          int t;
1208          char *tmps1=
1209            (char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) *
1210                             sizeof (char));
1211          sprintf (tmps1, "%s/%s", tmpName, dp1->d_name);
1212          char *tmpsn = zStrdup (dp1->d_name);
1213          tmpsn[strlen (tmpsn) - 5] = 0;
1214          service* s1 = (service *) malloc (SERVICE_SIZE);
1215          if (s1 == NULL)
1216            {
1217              setMapInMaps(m,"lenv","message",_("Unable to allocate memory."));
1218              setMapInMaps(m,"lenv","type","InternalError");
1219              return -2;
1220            }
1221          t = readServiceFile (m, tmps1, &s1, tmpsn);
1222          free (tmpsn);
1223          if (t < 0)
1224            {
1225              map *tmp00 = getMapFromMaps (m, "lenv", "message");
1226              char tmp01[1024];
1227              if (tmp00 != NULL)
1228                sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
1229                         dp1->d_name, tmp00->value);
1230              else
1231                sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
1232                         dp1->d_name);
1233              setMapInMaps(m,"lenv","message",tmp01);
1234              setMapInMaps(m,"lenv","type","InternalError");
1235              return -1;
1236            }
1237          if(strncasecmp(registryKeys[i],"implementation",14)==0){
1238            inheritance(*r,&s1);
1239          }
1240          addServiceToRegistry(r,registryKeys[i],s1);
1241          freeService (&s1);
1242          free (s1);
1243          scount++;
1244        }
1245    }
1246    (void) closedir (dirp1);
1247  }
1248  return 0;
1249}
1250
1251#ifdef WIN32
1252/**
1253 * Create a KVP request for executing background task.
1254 * TODO: use the XML request in case of input POST request.
1255 *
1256 * @param m the maps containing the parameters from the main.cfg file
1257 * @param length the total length of the KVP parameters
1258 * @param type
1259 */
1260char* getMapsAsKVP(maps* m,int length,int type){
1261  char *dataInputsKVP=(char*) malloc(length*sizeof(char));
1262  char *dataInputsKVPi=NULL;
1263  maps* curs=m;
1264  int i=0;
1265  while(curs!=NULL){
1266    map *inRequest=getMap(curs->content,"inRequest");
1267    map *hasLength=getMap(curs->content,"length");
1268    if((inRequest!=NULL && strncasecmp(inRequest->value,"true",4)==0) ||
1269       inRequest==NULL){
1270      if(i==0)
1271        if(type==0){
1272          sprintf(dataInputsKVP,"%s=",curs->name);
1273          if(hasLength!=NULL){
1274            dataInputsKVPi=(char*)malloc((strlen(curs->name)+2)*sizeof(char));
1275            sprintf(dataInputsKVPi,"%s=",curs->name);
1276          }
1277        }
1278        else
1279          sprintf(dataInputsKVP,"%s",curs->name);
1280      else{
1281        char *temp=zStrdup(dataInputsKVP);
1282        if(type==0)
1283          sprintf(dataInputsKVP,"%s;%s=",temp,curs->name);
1284        else
1285          sprintf(dataInputsKVP,"%s;%s",temp,curs->name);
1286      }
1287      map* icurs=curs->content;
1288      if(type==0){
1289        char *temp=zStrdup(dataInputsKVP);
1290        if(getMap(curs->content,"xlink:href")!=NULL)
1291          sprintf(dataInputsKVP,"%sReference",temp);
1292        else{
1293          if(hasLength!=NULL){
1294            int j;
1295            for(j=0;j<atoi(hasLength->value);j++){
1296              map* tmp0=getMapArray(curs->content,"value",j);
1297              if(j==0)
1298                free(temp);
1299              temp=zStrdup(dataInputsKVP);
1300              if(j==0)
1301                sprintf(dataInputsKVP,"%s%s",temp,tmp0->value);
1302              else
1303                sprintf(dataInputsKVP,"%s;%s%s",temp,dataInputsKVPi,tmp0->value);
1304            }
1305          }
1306          else
1307            sprintf(dataInputsKVP,"%s%s",temp,icurs->value);
1308        }
1309        free(temp);
1310      }
1311      while(icurs!=NULL){
1312        if(strncasecmp(icurs->name,"value",5)!=0 &&
1313           strncasecmp(icurs->name,"mimeType_",9)!=0 &&
1314           strncasecmp(icurs->name,"dataType_",9)!=0 &&
1315           strncasecmp(icurs->name,"size",4)!=0 &&
1316           strncasecmp(icurs->name,"length",4)!=0 &&
1317           strncasecmp(icurs->name,"isArray",7)!=0 &&
1318           strcasecmp(icurs->name,"Reference")!=0 &&
1319           strcasecmp(icurs->name,"minOccurs")!=0 &&
1320           strcasecmp(icurs->name,"maxOccurs")!=0 &&
1321           strncasecmp(icurs->name,"fmimeType",9)!=0 &&
1322           strcasecmp(icurs->name,"inRequest")!=0){
1323          char *itemp=zStrdup(dataInputsKVP);
1324          if(strcasecmp(icurs->name,"xlink:href")!=0)
1325            sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,icurs->value);
1326          else
1327            sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,url_encode(icurs->value));
1328          free(itemp);
1329        }
1330        icurs=icurs->next;
1331      }
1332    }
1333    curs=curs->next;
1334    i++;
1335  }
1336  return dataInputsKVP;
1337}
1338#endif
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png