Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

conftable.c

Go to the documentation of this file.
00001 /***************************************************************************
00002                                  conftable.c
00003                              -------------------
00004     begin                : Sun Nov 4 2001
00005     copyright            : (C) 2001-2002 by Christian Hoenig & Gunter Ohrner
00006     email                : pdepp@CustomCDROM.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00023 #include "common.h"
00024 
00025 #include <errno.h>
00026 #include <limits.h>
00027 // logger.h includes stdio.h for us. Even more importantly it includes stdarg.h
00028 // BEFORE including stdio.h which avoids tons of warnings on Solaris... :-(
00029 #include <sys/types.h>
00030 #include <regex.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <time.h>
00034 #include <unistd.h>
00035 
00036 #include "logger.h"
00037 
00038 #include "conftable.h"
00039 
00040 #include "keypvalplist.h"
00041 #include "misc.h"
00042 #include "xmalloc.h"
00043 
00045 KeypValpList list;
00046 
00047 //inits the Conftable
00048 int initConftable()
00049 {
00050   list = kpvpListInit();
00051   return 0;
00052 }
00053 
00054 //terminates the Conftable and frees the allocatet memory
00055 int terminateConftable()
00056 {
00057   kpvpListFirst(list);
00058   while(!kpvpListIsTail(list))
00059   {
00060     //free content
00061     pd_free(kpvpListGetPayload(list).key);
00062     pd_free(kpvpListGetPayload(list).val);
00063     //free list
00064     kpvpListDelete(list);
00065   }
00066   kpvpListTerminate(list);
00067   return 0;
00068 }
00069 
00070 //Sets a value to a key.
00071 //If the key doesn't exist, it will be created
00072 int setEntry(const int priority, char *const pkey, char *const pvalue)
00073 {
00074   char* value, * key;
00075 
00076   //first make a copy of the char*'s, we don't wonna work on the originals
00077   int buf_size =  strlen(pkey)+1;
00078    key = (char*)pd_malloc(buf_size);
00079    strncpy(key, pkey, buf_size);
00080   buf_size =  strlen(pvalue)+1;
00081    value = (char*)pd_malloc(buf_size);
00082    strncpy(value, pvalue, buf_size);
00083 
00084   kpvpListFirst(list);
00085   while(!kpvpListIsTail(list))
00086   {
00087     if (strcmp(kpvpListGetPayload(list).key, key) == 0)
00088       break;
00089     kpvpListNext(list);
00090   }
00091 
00092   if (kpvpListIsTail(list))
00093   {
00094     //add new element
00095     struct KeyValuePair kvp;
00096     kvp.key = key;
00097     kvp.val = value;
00098 
00099     kpvpListAppend(list, kvp);
00100   }
00101   else
00102   {
00103     //overwrite old one, if priority allows
00104     if (priority == PRIO_CMDLINE || priority == PRIO_PRGCALL)
00105     {
00106       struct KeyValuePair kvp;
00107       kvp.key = key;
00108       kvp.val = value;
00109       
00110       pd_free(kpvpListGetPayload(list).key);
00111       pd_free(kpvpListGetPayload(list).val);
00112       
00113       kpvpListSetPayload(list, kvp);
00114     }
00115     else
00116     {
00117       pd_free(key);
00118       pd_free(value);
00119     }
00120   }
00121   return 0;
00122 }
00123 
00125 int setEntryL(const int priority, char *const key, const long value)
00126 {
00127   const int size = 128;
00128   char ch_value[size];
00129   
00130   if (snprintf(ch_value,size, "%ld",value) < 0)
00131     return - 1;
00132   else
00133     setEntry(priority, key, ch_value);
00134   return 0;
00135 }
00136 
00137 
00138 //Returns the value to a key.
00139 //if key doesn't exist, 'null' is returned.
00140 const char* getEntry(const char *const key)
00141 {
00142   kpvpListFirst(list);
00143   while(!kpvpListIsTail(list))
00144   {
00145     if (strcmp(kpvpListGetPayload(list).key, key) == 0)
00146       break;
00147     kpvpListNext(list);
00148   }
00149 
00150   return kpvpListIsTail(list) ? NULL : kpvpListGetPayload(list).val;
00151 }
00152 
00153 //returns a value to a given key or \c defl_data of the key cannot be found
00154 const char* getEntryDefl(const char *const key, const char *const defl_data)
00155 {
00156   const char* data = getEntry(key);
00157   return (data != NULL) ? data : defl_data;
00158 }
00159 
00160 //returns the value of key as long.
00161 //If key doesn't exist or a range error has occured, it returns 0 and sets ERRNO to ERANGE
00162 long getEntryL(const char *const key)
00163 {
00164   long val;
00165   const char* tmp = getEntry(key);
00166   errno = 0;
00167   if (tmp != NULL)
00168     val = strtol(tmp,NULL,10);
00169   else
00170   {
00171     errno = ERANGE;
00172     return 0;
00173   }
00174     
00175 
00176   return ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE) ? 0 : val;
00177 }
00178 
00179 //returns a value to a given key or \c defl_data of the key cannot be found
00180 long int getEntryDeflL(const char *const key, long int defl_data)
00181 {
00182   long int data = getEntryL(key);
00183   return (errno == ERANGE) ? defl_data : data;
00184   
00185   
00186 }
00187 
00188 //Returns the value of key as int.
00189 //If key doesn't exist or a range error has occured, it returns 0 and sets ERRNO to ERANGE
00190 int getEntryI(const char *const key)
00191 {
00192   long val = getEntryL(key);
00193 
00194   if ((val == 0 && errno == ERANGE) || val < INT_MIN || val > INT_MAX)
00195   {
00196     errno = ERANGE;
00197     return  0;
00198   }
00199   else
00200     return (int) val;
00201 }
00202 
00203 //returns a value to a given key or \c defl_data of the key cannot be found
00204 int getEntryDeflI(const char *const key, int defl_data)
00205 {
00206   int data = getEntryI(key);
00207   return (errno == ERANGE) ? defl_data : data;
00208 }
00209 
00210 //returns a value to a given key or \c defl_data of the key cannot be found
00211 unsigned int getEntryDeflUI(const char *const key, unsigned int defl_data)
00212 {
00213   int data = getEntryI(key);
00214   return (data <= 0 || errno == ERANGE) ? defl_data : data;
00215 }
00216 
00217 
00218 //read the configfile
00219 int readConfigFile()
00220 {
00221   const char* cfg_file_name = getEntryDefl(CONFENTRY_KEY_CONFIGFILE,
00222                                            STD_CONFENTRY_VAL_CONFIGFILE);
00223   char* line;
00224   FILE* cfg_file;
00225   regex_t* cfg_regex = (regex_t*)pd_malloc(sizeof(regex_t));
00226   int regex_ret;
00227 
00228   cfg_file = fopen(cfg_file_name, "r");
00229   if (cfg_file == NULL)
00230   {
00231     logerr(CONF_TABLE, WARNING, errno, "could not open config file \"%s\"", cfg_file_name);
00232     pd_free(cfg_regex);
00233     return -1;
00234   }
00235 
00236   regex_ret = regcomp(cfg_regex,
00237                                 "^[[:blank:]]*([[:alnum:]._-]+)[[:space:]]*="
00238                                 "[[:blank:]]*([[:alnum:][:punct:]]+|\".+\")"
00239                                 "[[:blank:]]*(#.*)?$",
00240   REG_ICASE | REG_EXTENDED);
00241 
00242 #ifndef NDEBUG
00243 //  #define LEN 1024
00244 //  line = (char*)pd_malloc(LEN);
00245 //  regerror(regex_ret, cfg_regex, line, LEN);
00246 //
00247 //  log(PDEPP_CORE, CRITICAL, line);
00248 //
00249 //  pd_free(line);
00250 #endif
00251 
00252   //cycle thru the lines and parse each
00253   while ((line = getLine(cfg_file)))
00254   {
00255     regmatch_t sub_exps[3];
00256     if (regexec(cfg_regex, line, 3, sub_exps, 0) == 0)
00257     {
00258       char* key_start, * key_end, * val_start, * val_end;
00259 
00260       if (sub_exps[1].rm_so > -1 && sub_exps[2].rm_so > -1)
00261       {
00262         key_start = line + sub_exps[1].rm_so;
00263         key_end   = line + sub_exps[1].rm_eo;
00264         val_start = line + sub_exps[2].rm_so;
00265         val_end   = line + sub_exps[2].rm_eo;
00266 
00267         // if we find "..."
00268         if (*(val_start) == '\"' && *(val_end-1) == '\"')
00269         {
00270           val_start++;
00271           val_end--;
00272         }
00273 
00274         *key_end = '\0';
00275         *val_end = '\0';
00276 
00277 #ifndef NDEBUG
00278 //        // Tell me what you've found!
00279 //        logger(CONF_TABLE, CRITICAL, "read key '%s' with value '%s'",
00280 //                                  key_start, val_start);
00281 #endif
00282 
00283         setEntry(PRIO_CFGFILE, key_start, val_start);
00284       }
00285     }
00286     pd_free(line);
00287     if (feof(cfg_file))
00288       break;
00289   }
00290 
00291   regfree(cfg_regex);
00292   pd_free(cfg_regex);
00293   fclose(cfg_file);
00294   return 0;
00295 }

Generated on Fri Jan 25 22:40:30 2002 for PDepp Webserver by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001