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

Last change on this file since 656 was 654, checked in by djay, 9 years ago

Initial support for WPS 2.0.0 including the Dismiss extension.

  • Property svn:keywords set to Id
File size: 26.7 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 "mimetypes.h"
29#ifndef WIN32
30#include <dlfcn.h>
31#endif
32#include <uuid/uuid.h>
33
34/**
35 * Detect WPS version used (1.0.0 or 2.0.0).
36 *
37 * @param version number as char* (1.0.0 or 2.0.0)
38 * @return 0 in case of version 1.0.0, 1 for 2.0.0, -1 in other case
39 */
40int getVersionId(const char* version){
41  int schemaId=0;
42  for(;schemaId<2;schemaId++){
43    if(strncasecmp(version,schemas[schemaId][0],5)==0)
44      return schemaId;
45  }
46  return -1;
47}
48
49/**
50 * Generate a UUID.
51 * ref: https://www.ietf.org/rfc/rfc4122.txt / 4.2
52 *
53 * @return a new char* containing the UUID, make sure to free the returned
54 *  ressource once used.
55 */
56char *get_uuid(){
57  char *res=(char*)malloc(37*sizeof(char));
58  uuid_t uuid;
59  uuid_generate_time(uuid);
60  char rest[128];
61  uuid_unparse(uuid,rest);
62  sprintf(res,"%s", rest);
63  return res;
64}
65
66/**
67 * Extract the service identifier from the full service identifier
68 * ie:
69 *  - Full service name: OTB.BandMath
70 *  - Service name: BandMath
71 *
72 * @param conf the maps containing the settings of the main.cfg file
73 * @param conf_dir the full path to the ZOO-Kernel directory
74 * @param identifier the full service name (potentialy including a prefix, ie:
75 *  Prefix.MyService)
76 * @param buffer the resulting service identifier (without any prefix)
77 */
78void parseIdentifier(maps* conf,char* conf_dir,char *identifier,char* buffer){
79  setMapInMaps(conf,"lenv","oIdentifier",identifier);
80  char *lid=zStrdup(identifier);
81  char *saveptr1;
82  char *tmps1=strtok_r(lid,".",&saveptr1);
83  int level=0;
84  char key[25];
85  char levels[18];
86  while(tmps1!=NULL){
87    char *test=zStrdup(tmps1);
88    char* tmps2=(char*)malloc((strlen(test)+2)*sizeof(char));
89    sprintf(key,"sprefix_%d",level);
90    sprintf(tmps2,"%s.",test);
91    sprintf(levels,"%d",level);
92    setMapInMaps(conf,"lenv","level",levels);
93    setMapInMaps(conf,"lenv",key,tmps2);
94    free(tmps2);
95    free(test);
96    level++;
97    tmps1=strtok_r(NULL,".",&saveptr1);
98  }
99  int i=0;
100  sprintf(buffer,"%s",conf_dir);
101  for(i=0;i<level;i++){
102    char *tmp0=zStrdup(buffer);
103    sprintf(key,"sprefix_%d",i);
104    map* tmp00=getMapFromMaps(conf,"lenv",key);
105    if(tmp00!=NULL)
106      sprintf(buffer,"%s/%s",tmp0,tmp00->value);
107    free(tmp0);
108    buffer[strlen(buffer)-1]=0;
109    if(i+1<level){ 
110      #ifdef IGNORE_METAPATH
111        map* tmpMap = createMap("metapath", "");
112      #else 
113        map* tmpMap=getMapFromMaps(conf,"lenv","metapath");
114      #endif     
115      if(tmpMap==NULL || strlen(tmpMap->value)==0){
116        char *tmp01=zStrdup(tmp00->value);
117        tmp01[strlen(tmp01)-1]=0;
118        setMapInMaps(conf,"lenv","metapath",tmp01);
119        free(tmp01);
120        tmp01=NULL;
121      }
122      else{
123        if(tmp00!=NULL && tmpMap!=NULL){
124          char *tmp00s=zStrdup(tmp00->value);
125          tmp00s[strlen(tmp00s)-1]=0;
126          char *value=(char*)malloc((strlen(tmp00s)+strlen(tmpMap->value)+2)*sizeof(char));
127          sprintf(value,"%s/%s",tmpMap->value,tmp00s);
128          setMapInMaps(conf,"lenv","metapath",value);
129          free(value);
130          free(tmp00s);
131          value=NULL;
132        }
133      }
134    }else{
135      char *tmp01=zStrdup(tmp00->value);
136      tmp01[strlen(tmp01)-1]=0;
137      setMapInMaps(conf,"lenv","Identifier",tmp01);
138      free(tmp01);
139    }
140  }
141  char *tmp0=zStrdup(buffer);
142  sprintf(buffer,"%s.zcfg",tmp0);
143  free(tmp0);
144  free(lid);
145}
146
147/**
148 * Converts a hex character to its integer value
149 *
150 * @param ch the char to convert
151 * @return the converted char
152 */
153char from_hex(char ch) {
154  return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
155}
156
157/**
158 * Converts an integer value to its hec character
159 *
160 * @param code the char to convert
161 * @return the converted char
162 */
163char to_hex(char code) {
164  static char hex[] = "0123456789abcdef";
165  return hex[code & 15];
166}
167
168/**
169 * URLEncode an url
170 *
171 * @param str the url to encode
172 * @return a url-encoded version of str
173 * @warning be sure to free() the returned string after use
174 */
175char *url_encode(char *str) {
176  char *pstr = str, *buf = (char*) malloc(strlen(str) * 3 + 1), *pbuf = buf;
177  while (*pstr) {
178    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
179      *pbuf++ = *pstr;
180    else if (*pstr == ' ') 
181      *pbuf++ = '+';
182    else 
183      *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
184    pstr++;
185  }
186  *pbuf = '\0';
187  return buf;
188}
189
190/**
191 * Decode an URLEncoded url
192 *
193 * @param str the URLEncoded url to decode
194 * @return a url-decoded version of str
195 * @warning be sure to free() the returned string after use
196 */
197char *url_decode(char *str) {
198  char *pstr = str, *buf = (char*) malloc(strlen(str) + 1), *pbuf = buf;
199  while (*pstr) {
200    if (*pstr == '%') {
201      if (pstr[1] && pstr[2]) {
202        *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
203        pstr += 2;
204      }
205    } else if (*pstr == '+') { 
206      *pbuf++ = ' ';
207    } else {
208      *pbuf++ = *pstr;
209    }
210    pstr++;
211  }
212  *pbuf = '\0';
213  return buf;
214}
215
216/**
217 * Verify if a given language is listed in the lang list defined in the [main]
218 * section of the main.cfg file.
219 *
220 * @param conf the map containing the settings from the main.cfg file
221 * @param str the specific language
222 * @return 1 if the specific language is listed, -1 in other case.
223 */
224int isValidLang(maps* conf,const char *str){
225  map *tmpMap=getMapFromMaps(conf,"main","lang");
226  char *tmp=zStrdup(tmpMap->value);
227  char *pToken,*saveptr;
228  pToken=strtok_r(tmp,",",&saveptr);
229  int res=-1;
230  char *pToken1,*saveptr1;
231  pToken1=strtok_r(tmp,",",&saveptr1);
232  while(pToken1!=NULL){
233    while(pToken!=NULL){
234      if(strcasecmp(pToken1,pToken)==0){
235        res=1;
236        break;
237      }
238      pToken=strtok_r(NULL,",",&saveptr);
239    }
240    pToken1=strtok_r(NULL,",",&saveptr1);
241  }
242  free(tmp);
243  return res;
244}
245
246
247/**
248 * Access the value of the encoding key in a maps
249 *
250 * @param m the maps to search for the encoding key
251 * @return the value of the encoding key in a maps if encoding key exists,
252 *  "UTF-8" in other case.
253 */
254char* getEncoding(maps* m){
255  if(m!=NULL){
256    map* tmp=getMap(m->content,"encoding");
257    if(tmp!=NULL){
258      return tmp->value;
259    }
260    else
261      return (char*)"UTF-8";
262  }
263  else
264    return (char*)"UTF-8"; 
265}
266
267/**
268 * Access the value of the version key in a maps
269 *
270 * @param m the maps to search for the version key
271 * @return the value of the version key in a maps if encoding key exists,
272 *  "1.0.0" in other case.
273 */
274char* getVersion(maps* m){
275  if(m!=NULL){
276    map* tmp=getMap(m->content,"version");
277    if(tmp!=NULL){
278      return tmp->value;
279    }
280    else
281      return (char*)"1.0.0";
282  }
283  else
284    return (char*)"1.0.0";
285}
286
287/**
288 * Read a file generated by a service.
289 *
290 * @param m the conf maps
291 * @param content the output item
292 * @param filename the file to read
293 */
294void readGeneratedFile(maps* m,map* content,char* filename){
295  FILE * file=fopen(filename,"rb");
296  if(file==NULL){
297    fprintf(stderr,"Failed to open file %s for reading purpose.\n",filename);
298    setMapInMaps(m,"lenv","message","Unable to read produced file. Please try again later");
299    return ;
300  }
301  fseek(file, 0, SEEK_END);
302  long count = ftell(file);
303  rewind(file);
304  struct stat file_status; 
305  stat(filename, &file_status);
306  map* tmpMap1=getMap(content,"value");
307  if(tmpMap1==NULL){
308    addToMap(content,"value","");
309    tmpMap1=getMap(content,"value");
310  }
311  free(tmpMap1->value);
312  tmpMap1->value=(char*) malloc((count+1)*sizeof(char)); 
313  fread(tmpMap1->value,1,count,file);
314  tmpMap1->value[count]=0;
315  fclose(file);
316  char rsize[1000];
317  sprintf(rsize,"%ld",count);
318  addToMap(content,"size",rsize);
319}
320
321
322/**
323 * Write a file from value and length
324 *
325 * @param fname the file name
326 * @param val the value
327 * @param length the value length
328 */
329int writeFile(char* fname,char* val,int length){
330  FILE* of=fopen(fname,"wb");
331  if(of==NULL){
332    return -1;
333  }
334  size_t ret=fwrite(val,sizeof(char),length,of);
335  if(ret<length){
336    fprintf(stderr,"Write error occured!\n");
337    fclose(of);
338    return -1;
339  }
340  fclose(of);
341  return 1;
342}
343
344/**
345 * Dump all values in a maps as files
346 *
347 * @param main_conf the maps containing the settings of the main.cfg file
348 * @param in the maps containing values to dump as files
349 */
350void dumpMapsValuesToFiles(maps** main_conf,maps** in){
351  map* tmpPath=getMapFromMaps(*main_conf,"main","tmpPath");
352  map* tmpSid=getMapFromMaps(*main_conf,"lenv","usid");
353  maps* inputs=*in;
354  int length=0;
355  while(inputs!=NULL){
356    if(getMap(inputs->content,"mimeType")!=NULL &&
357       getMap(inputs->content,"cache_file")==NULL){
358      map* cMap=inputs->content;
359      if(getMap(cMap,"length")!=NULL){
360        map* tmpLength=getMap(cMap,"length");
361        int len=atoi(tmpLength->value);
362        int k=0;
363        for(k=0;k<len;k++){
364          map* cMimeType=getMapArray(cMap,"mimeType",k);
365          map* cValue=getMapArray(cMap,"value",k);
366          map* cSize=getMapArray(cMap,"size",k);
367          char file_ext[32];
368          getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
369          char* val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
370          sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,k,file_ext);
371          length=0;
372          if(cSize!=NULL){
373            length=atoi(cSize->value);
374          }
375          writeFile(val,cValue->value,length);
376          setMapArray(cMap,"cache_file",k,val);
377          free(val);
378        }
379      }else{
380        int length=0;
381        map* cMimeType=getMap(cMap,"mimeType");
382        map* cValue=getMap(cMap,"value");
383        map* cSize=getMap(cMap,"size");
384        char file_ext[32];
385        getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
386        char *val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
387        sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,0,file_ext);
388        if(cSize!=NULL){
389          length=atoi(cSize->value);
390        }
391        writeFile(val,cValue->value,length);
392        addToMap(cMap,"cache_file",val);
393        free(val);
394      }
395    }
396    inputs=inputs->next;
397  }
398}
399
400
401/**
402 * Base64 encoding of a char*
403 *
404 * @param input the value to encode
405 * @param length the value length
406 * @return the buffer containing the base64 value
407 * @warning make sure to free the returned value
408 */
409char *base64(const char *input, int length)
410{
411  BIO *bmem, *b64;
412  BUF_MEM *bptr;
413
414  b64 = BIO_new(BIO_f_base64());
415  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
416  bmem = BIO_new(BIO_s_mem());
417  b64 = BIO_push(b64, bmem);
418  BIO_write(b64, input, length);
419  BIO_flush(b64);
420  BIO_get_mem_ptr(b64, &bptr);
421
422  char *buff = (char *)malloc((bptr->length+1)*sizeof(char));
423  memcpy(buff, bptr->data, bptr->length);
424  buff[bptr->length] = 0;
425
426  BIO_free_all(b64);
427
428  return buff;
429}
430
431/**
432 * Base64 decoding of a char*
433 *
434 * @param input the value to decode
435 * @param length the value length
436 * @param red the value length
437 * @return the buffer containing the base64 value
438 * @warning make sure to free the returned value
439 */
440char *base64d(const char *input, int length,int* red)
441{
442  BIO *b64, *bmem;
443
444  char *buffer = (char *)malloc(length);
445  if(buffer){
446    memset(buffer, 0, length);
447    b64 = BIO_new(BIO_f_base64());
448    if(b64){
449      bmem = BIO_new_mem_buf((unsigned char*)input,length);
450      bmem = BIO_push(b64, bmem);
451      *red=BIO_read(bmem, buffer, length);
452      buffer[length-1]=0;
453      BIO_free_all(bmem);
454    }
455  }
456  return buffer;
457}
458
459/**
460 * Read Base64 value and split it value by lines of 64 char.
461 *
462 * @param in the map containing the value to split
463 */
464void readBase64(map **in){
465  char *res = NULL;
466  char *curs = (*in)->value;
467  int i = 0;
468  for (i = 0; i <= strlen ((*in)->value) / 64;
469       i++)
470    {
471      if (res == NULL)
472        res =
473          (char *) malloc (65 * sizeof (char));
474      else
475        res =
476          (char *) realloc (res,
477                            (((i + 1) * 65) +
478                             i) * sizeof (char));
479      int csize = i * 65;
480      strncpy (res + csize, curs, 64);
481      if (i == strlen ((*in)->value) / 64)
482        strcat (res, "\n\0");
483      else
484        {
485          strncpy (res + (((i + 1) * 64) + i),
486                   "\n\0", 2);
487          curs += 64;
488        }
489    }
490  free ((*in)->value);
491  (*in)->value = zStrdup (res);
492  free (res);
493}
494
495
496/**
497 * Add the default values defined in the zcfg to a maps.
498 *
499 * @param out the maps containing the inputs or outputs given in the initial
500 *  HTTP request
501 * @param in the description of all inputs or outputs available for a service
502 * @param m the maps containing the settings of the main.cfg file
503 * @param type 0 for inputs and 1 for outputs
504 * @param err the map to store potential missing mandatory input parameters or
505 *  wrong output names depending on the type.
506 * @return "" if no error was detected, the name of last input or output causing
507 *  an error.
508 */
509char* addDefaultValues(maps** out,elements* in,maps* m,int type,map** err){
510  map *res=*err;
511  elements* tmpInputs=in;
512  maps* out1=*out;
513  char *result=NULL;
514  int nb=0;
515  if(type==1){
516    while(out1!=NULL){
517      if(getElements(in,out1->name)==NULL){
518        if(res==NULL){
519          res=createMap("value",out1->name);
520        }else{
521          setMapArray(res,"value",nb,out1->name);
522        }
523        nb++;
524        result=out1->name;
525      }
526      out1=out1->next;
527    }
528    if(res!=NULL){
529      *err=res;
530      return result;
531    }
532    out1=*out;
533  }
534  while(tmpInputs!=NULL){
535    maps *tmpMaps=getMaps(out1,tmpInputs->name);
536    if(tmpMaps==NULL){
537      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
538      tmpMaps2->name=strdup(tmpInputs->name);
539      tmpMaps2->content=NULL;
540      tmpMaps2->next=NULL;
541     
542      if(type==0){
543        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
544        if(tmpMapMinO!=NULL){
545          if(atoi(tmpMapMinO->value)>=1){
546            freeMaps(&tmpMaps2);
547            free(tmpMaps2);
548            if(res==NULL){
549              res=createMap("value",tmpInputs->name);
550            }else{
551              setMapArray(res,"value",nb,tmpInputs->name);
552            }
553            nb++;
554            result=tmpInputs->name;
555          }
556          else{
557            if(tmpMaps2->content==NULL)
558              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
559            else
560              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
561          }
562        }
563        if(res==NULL){
564          map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
565          if(tmpMaxO!=NULL){
566            if(tmpMaps2->content==NULL)
567              tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
568            else
569              addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
570          }
571          map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
572          if(tmpMaxMB!=NULL){
573            if(tmpMaps2->content==NULL)
574              tmpMaps2->content=createMap("maximumMegabytes",tmpMaxMB->value);
575            else
576              addToMap(tmpMaps2->content,"maximumMegabytes",tmpMaxMB->value);
577          }
578        }
579      }
580
581      if(res==NULL){
582        iotype* tmpIoType=tmpInputs->defaults;
583        if(tmpIoType!=NULL){
584          map* tmpm=tmpIoType->content;
585          while(tmpm!=NULL){
586            if(tmpMaps2->content==NULL)
587              tmpMaps2->content=createMap(tmpm->name,tmpm->value);
588            else
589              addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
590            tmpm=tmpm->next;
591          }
592        }
593        addToMap(tmpMaps2->content,"inRequest","false");
594        if(type==0){
595          map *tmpMap=getMap(tmpMaps2->content,"value");
596          if(tmpMap==NULL)
597            addToMap(tmpMaps2->content,"value","NULL");
598        }
599        if(out1==NULL){
600          *out=dupMaps(&tmpMaps2);
601          out1=*out;
602        }
603        else
604          addMapsToMaps(&out1,tmpMaps2);
605        freeMap(&tmpMaps2->content);
606        free(tmpMaps2->content);
607        tmpMaps2->content=NULL;
608        freeMaps(&tmpMaps2);
609        free(tmpMaps2);
610        tmpMaps2=NULL;
611      }
612    }
613    else{
614      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
615                                             tmpMaps->content);
616      if(type==0) {
617        /**
618         * In case of an Input maps, then add the minOccurs and maxOccurs to the
619         * content map.
620         */
621        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
622        if(tmpMap1!=NULL){
623          if(tmpMaps->content==NULL)
624            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
625          else
626            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
627        }
628        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
629        if(tmpMaxO!=NULL){
630          if(tmpMaps->content==NULL)
631            tmpMaps->content=createMap("maxOccurs",tmpMaxO->value);
632          else
633            addToMap(tmpMaps->content,"maxOccurs",tmpMaxO->value);
634        }
635        map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
636        if(tmpMaxMB!=NULL){
637          if(tmpMaps->content==NULL)
638            tmpMaps->content=createMap("maximumMegabytes",tmpMaxMB->value);
639          else
640            addToMap(tmpMaps->content,"maximumMegabytes",tmpMaxMB->value);
641        }
642        /**
643         * Parsing BoundingBoxData, fill the following map and then add it to
644         * the content map of the Input maps:
645         * lowerCorner, upperCorner, srs and dimensions
646         * cf. parseBoundingBox
647         */
648        if(tmpInputs->format!=NULL && strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
649          maps* tmpI=getMaps(*out,tmpInputs->name);
650          if(tmpI!=NULL){
651            map* tmpV=getMap(tmpI->content,"value");
652            if(tmpV!=NULL){
653              char *tmpVS=strdup(tmpV->value);
654              map* tmp=parseBoundingBox(tmpVS);
655              free(tmpVS);
656              map* tmpC=tmp;
657              while(tmpC!=NULL){
658                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
659                tmpC=tmpC->next;
660              }
661              freeMap(&tmp);
662              free(tmp);
663            }
664          }
665        }
666      }
667
668      if(tmpIoType!=NULL){
669        map* tmpContent=tmpIoType->content;
670        map* cval=NULL;
671        int hasPassed=-1;
672        while(tmpContent!=NULL){
673          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
674#ifdef DEBUG
675            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
676#endif
677            if(tmpMaps->content==NULL)
678              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
679            else
680              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
681           
682            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
683              map* length=getMap(tmpMaps->content,"length");
684              int i;
685              char *tcn=strdup(tmpContent->name);
686              for(i=1;i<atoi(length->value);i++){
687#ifdef DEBUG
688                dumpMap(tmpMaps->content);
689                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
690#endif
691                int len=strlen((char*) tcn);
692                char *tmp1=(char *)malloc((len+10)*sizeof(char));
693                sprintf(tmp1,"%s_%d",tcn,i);
694#ifdef DEBUG
695                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
696#endif
697                addToMap(tmpMaps->content,tmp1,tmpContent->value);
698                free(tmp1);
699                hasPassed=1;
700              }
701              free(tcn);
702            }
703          }
704          tmpContent=tmpContent->next;
705        }
706#ifdef USE_MS
707        /**
708         * check for useMapServer presence
709         */
710        map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
711        if(tmpCheck!=NULL){
712          // Get the default value
713          tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
714          tmpCheck=getMap(tmpMaps->content,"mimeType");
715          addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
716          map* cursor=tmpIoType->content;
717          while(cursor!=NULL){
718            addToMap(tmpMaps->content,cursor->name,cursor->value);
719            cursor=cursor->next;
720          }
721         
722          cursor=tmpInputs->content;
723          while(cursor!=NULL){
724            if(strcasecmp(cursor->name,"Title")==0 ||
725               strcasecmp(cursor->name,"Abstract")==0)
726              addToMap(tmpMaps->content,cursor->name,cursor->value);
727           cursor=cursor->next;
728          }
729        }
730#endif
731      }
732      if(tmpMaps->content==NULL)
733        tmpMaps->content=createMap("inRequest","true");
734      else
735        addToMap(tmpMaps->content,"inRequest","true");
736
737    }
738    tmpInputs=tmpInputs->next;
739  }
740  if(res!=NULL){
741    *err=res;
742    return result;
743  }
744  return "";
745}
746
747/**
748 * Access the last error message returned by the OS when trying to dynamically
749 * load a shared library.
750 *
751 * @return the last error message
752 * @warning The character string returned from getLastErrorMessage resides
753 * in a static buffer. The application should not write to this
754 * buffer or attempt to free() it.
755 */ 
756char* getLastErrorMessage() {                                             
757#ifdef WIN32
758  LPVOID lpMsgBuf;
759  DWORD errCode = GetLastError();
760  static char msg[ERROR_MSG_MAX_LENGTH];
761  size_t i;
762 
763  DWORD length = FormatMessage(
764                               FORMAT_MESSAGE_ALLOCATE_BUFFER | 
765                               FORMAT_MESSAGE_FROM_SYSTEM |
766                               FORMAT_MESSAGE_IGNORE_INSERTS,
767                               NULL,
768                               errCode,
769                               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
770                               (LPTSTR) &lpMsgBuf,
771                               0, NULL );       
772 
773#ifdef UNICODE         
774  wcstombs_s( &i, msg, ERROR_MSG_MAX_LENGTH,
775              (wchar_t*) lpMsgBuf, _TRUNCATE );
776#else
777  strcpy_s( msg, ERROR_MSG_MAX_LENGTH,
778            (char *) lpMsgBuf );               
779#endif 
780  LocalFree(lpMsgBuf);
781 
782  return msg;
783#else
784  return dlerror();
785#endif
786}
787
788#include <dirent.h>
789#ifndef RELY_ON_DB
790/**
791 * Read the Result file (.res).
792 *
793 * @param conf the maps containing the setting of the main.cfg file
794 * @param pid the service identifier (usid key from the [lenv] section)
795 */
796void readFinalRes(maps* conf,char* pid,map* statusInfo){
797  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
798  char* fbkpid =
799    (char *)
800    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
801  sprintf (fbkpid, "%s/%s.res", r_inputs->value, pid);
802  struct stat file_status;
803  int istat = stat (fbkpid, &file_status);
804  if (istat == 0 && file_status.st_size > 0)
805    {
806      maps *res = (maps *) malloc (MAPS_SIZE);
807      conf_read (fbkpid, res);
808      map* status=getMapFromMaps(res,"status","status");
809      addToMap(statusInfo,"Status",status->value);
810      freeMaps(&res);
811      free(res);
812    }
813  else
814    addToMap(statusInfo,"Status","Failed"); 
815  free(fbkpid);
816}
817
818/**
819 * Check if a service is running.
820 *
821 * @param conf the maps containing the setting of the main.cfg file
822 * @param pid the unique service identifier (usid from the lenv section)
823 * @return 1 in case the service is still running, 0 otherwise
824 */
825int isRunning(maps* conf,char* pid){
826  int res=0;
827  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
828  char* fbkpid =
829    (char *)
830    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
831  sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid);
832  FILE* f0 = fopen (fbkpid, "r");
833  if(f0!=NULL){
834    fclose(f0);
835    res=1;
836  }
837  free(fbkpid);
838  return res;
839}
840#else
841#include "sqlapi.h"
842#endif
843
844/**
845 * Run GetStatus requests.
846 *
847 * @param conf the maps containing the setting of the main.cfg file
848 * @param pid the service identifier (usid key from the [lenv] section)
849 * @param req the request (GetStatus / GetResult)
850 */
851void runGetStatus(maps* conf,char* pid,char* req){
852  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
853  char *sid=getStatusId(conf,pid);
854  if(sid==NULL){
855    errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
856                    "NoSuchJob", pid);
857  }else{
858    map* statusInfo=createMap("JobID",pid);
859    if(isRunning(conf,pid)>0){
860      if(strncasecmp(req,"GetResult",strlen(req))==0){
861        errorException (conf, _("The result for the requested JobID has not yet been generated. "),
862                        "ResultNotReady", pid);
863        return;
864      }
865      else
866        if(strncasecmp(req,"GetStatus",strlen(req))==0){
867          addToMap(statusInfo,"Status","Running");
868          char* tmpStr=_getStatus(conf,pid);
869          if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
870            char *tmpStr1=strdup(tmpStr);
871            char *tmpStr0=strdup(strstr(tmpStr,"|")+1);
872            free(tmpStr);
873            tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
874            addToMap(statusInfo,"PercentCompleted",tmpStr1);
875            addToMap(statusInfo,"Message",tmpStr0);
876            free(tmpStr0);
877            free(tmpStr1);
878          }
879        }
880    }
881    else{
882      if(strncasecmp(req,"GetResult",strlen(req))==0){
883        char* result=_getStatusFile(conf,pid);
884        if(result!=NULL){
885          char *encoding=getEncoding(conf);
886          fprintf(stdout,"Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
887          fprintf(stdout,"%s",result);
888          fflush(stdout);
889          freeMap(&statusInfo);
890          free(statusInfo);
891          return;
892        }else{
893          errorException (conf, _("The result for the requested JobID has not yet been generated. "),
894                          "ResultNotReady", pid);
895          freeMap(&statusInfo);
896          free(statusInfo);
897          return;
898        }
899      }else
900        if(strncasecmp(req,"GetStatus",strlen(req))==0){
901          readFinalRes(conf,pid,statusInfo);
902          char* tmpStr=_getStatus(conf,pid);
903          if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
904            char *tmpStr1=strdup(tmpStr);
905            char *tmpStr0=strdup(strstr(tmpStr,"|")+1);
906            free(tmpStr);
907            tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
908            addToMap(statusInfo,"PercentCompleted",tmpStr1);
909            addToMap(statusInfo,"Message",tmpStr0);
910            free(tmpStr0);
911            free(tmpStr1);
912          }
913        }
914    }
915    printStatusInfo(conf,statusInfo,req);
916    freeMap(&statusInfo);
917    free(statusInfo);
918  }
919  return;
920}
921
922/**
923 * Run Dismiss requests.
924 *
925 * @param conf the maps containing the setting of the main.cfg file
926 * @param pid the service identifier (usid key from the [lenv] section)
927 */
928void runDismiss(maps* conf,char* pid){
929  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
930  char *sid=getStatusId(conf,pid);
931  if(sid==NULL){
932    errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
933                    "NoSuchJob", pid);
934  }else{
935    // We should send the Dismiss request to the target host if it differs
936    char* fbkpid =
937      (char *)
938      malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
939    sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid);
940    FILE* f0 = fopen (fbkpid, "r");
941    if(f0!=NULL){
942      long flen;
943      char *fcontent;
944      fseek (f0, 0, SEEK_END);
945      flen = ftell (f0);
946      fseek (f0, 0, SEEK_SET);
947      fcontent = (char *) malloc ((flen + 1) * sizeof (char));
948      fread(fcontent,flen,1,f0);
949      fcontent[flen]=0;
950      fclose(f0);
951      kill(atoi(fcontent),SIGKILL);
952      free(fcontent);
953    }
954    free(fbkpid);
955    struct dirent *dp;
956    DIR *dirp = opendir(r_inputs->value);
957    char fileName[1024];
958    int hasFile=-1;
959    if(dirp!=NULL){
960      while ((dp = readdir(dirp)) != NULL){
961#ifdef DEBUG
962        fprintf(stderr,"File : %s searched : %s\n",dp->d_name,tmp);
963#endif
964        if(strstr(dp->d_name,pid)!=0){
965          sprintf(fileName,"%s/%s",r_inputs->value,dp->d_name);
966          if(unlink(fileName)!=0){
967            errorException (conf, _("The job cannot be removed, a file cannot be removed"),
968                            "NoApplicableCode", NULL);
969            return;
970          }
971        }
972      }
973    }
974#ifdef RELY_ON_DB
975    removeService(conf,pid);
976#endif
977    map* statusInfo=createMap("JobID",pid);
978    addToMap(statusInfo,"Status","Dismissed");
979    printStatusInfo(conf,statusInfo,"Dismiss");
980    free(statusInfo);
981  }
982  return;
983}
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