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

Last change on this file since 673 was 657, checked in by djay, 9 years ago

Add missing include directive.

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