Config.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021   Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 #include <eyedbconfig.h>
00025 
00026 #define BUILTIN_VARS
00027 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #ifdef HAVE_UNISTD_H
00032 #include <unistd.h>
00033 #endif
00034 #ifdef HAVE_SYS_TYPES_H
00035 #include <sys/types.h>
00036 #endif
00037 #ifdef HAVE_PWD_H
00038 #include <pwd.h>
00039 #endif
00040 
00041 #include <eyedb/eyedb.h>
00042 #include "eyedblib/strutils.h"
00043 #include "lib/compile_builtin.h"
00044 
00045 #define MAXFILES 16
00046 
00047 namespace eyedb {
00048 
00049   ClientConfig *ClientConfig::instance = 0;
00050   std::string ClientConfig::config_file;
00051 
00052   ServerConfig *ServerConfig::instance = 0;
00053   std::string ServerConfig::config_file;
00054 
00055   static bool initialized = false;
00056 
00057   /*
00058    * Config file parser
00059    */
00060 
00061   static int fd_w;
00062   static FILE *fd;
00063   static int *pline;
00064   static const char *pfile;
00065 
00066   static FILE *fd_sp[MAXFILES];
00067   static int line[MAXFILES];
00068   static char *file_sp[MAXFILES];
00069 
00070   static const char *
00071   uppercase(const char *s)
00072   {
00073     static char buf[128];
00074     char c, *p;
00075     p = buf;
00076 
00077     while (c = *s++)
00078       *p++ = c + (c >= 'a' && c <= 'z' ? ('A' - 'a') : 0);
00079 
00080     *p = 0;
00081     return buf;
00082   }
00083 
00084   static int
00085   skip_spaces()
00086   {
00087     for (;;) {
00088       char c = fgetc(fd);
00089       if (c == EOF)
00090         return 0;
00091 
00092       if (c != ' ' && c != '\t' && c != '\n') {
00093         ungetc(c, fd);
00094         break;
00095       }
00096 
00097       if (c == '\n')
00098         (*pline)++;
00099     }
00100 
00101     return 1;
00102   }
00103   
00104   static int
00105   skip_comments()
00106   {
00107     char c = fgetc(fd);
00108     if (c == '#')
00109       for (;;) {
00110         c = fgetc(fd);
00111         if (c == EOF)
00112           return 0;
00113         
00114         if (c == '\n') {
00115           ungetc(c, fd);
00116           break;
00117         }
00118       }
00119     else
00120       ungetc(c, fd);
00121 
00122     return 1;
00123   }
00124 
00125   static const char assign[] = "=";
00126   static const char term[] = ";";
00127 
00128   static int
00129   check_spe(int &is_spe)
00130   {
00131     char c;
00132 
00133     is_spe = 0;
00134     c = fgetc(fd);
00135     if (c == EOF)
00136       return 0;
00137 
00138     if (c == ';') {
00139       is_spe = 1;
00140       return 1;
00141     }
00142     else if (c == '=') {
00143       is_spe = 2;
00144       return 1;
00145     }
00146 
00147     ungetc(c, fd);
00148     return 1;
00149   }
00150 
00151   static inline const char *
00152   line_str()
00153   {
00154     static std::string str;
00155     if (!pline || !pfile)
00156       return "";
00157 
00158     str = std::string("file \"" ) + pfile + "\" near line " + str_convert((long)*pline) + ": ";
00159     return str.c_str();
00160   }
00161 
00162   static void
00163   error(const char *fmt, const char *x1 = 0, const char *x2 = 0, const char *x3 = 0)
00164   {
00165 #if 1
00166     if (Exception::getMode() == Exception::ExceptionMode) {
00167       (void)Exception::make(IDB_ERROR, fmt, x1, x2, x3);
00168       return;
00169     }
00170 
00171     fprintf(stderr, "eyedb configuration: ");
00172     fprintf(stderr, fmt, x1, x2, x3);
00173     fprintf(stderr, "\n");
00174     exit(1);
00175 #else
00176     if (initialized) {
00177       Exception::Mode mode = Exception::setMode(Exception::ExceptionMode);
00178       (void)Exception::make(IDB_ERROR, fmt, x1, x2, x3);
00179       Exception::setMode(mode);
00180       return;
00181     }
00182 
00183     fprintf(stderr, fmt, x1, x2, x3);
00184     fprintf(stderr, "\n");
00185     exit(1);
00186 #endif
00187   }
00188 
00189   static void
00190   syntax_error(const char *msg)
00191   {
00192     error((line_str() + std::string("syntax error: ") + msg).c_str());
00193   }
00194 
00195   static void
00196   syntax_error(const std::string &s)
00197   {
00198     syntax_error(s.c_str());
00199   }
00200 
00201   // Returns true if file is found
00202   // false if file not found and quietFileNotFoundError == true
00203   // generates an exception if file not found and quietFileNotFoundError == false
00204   static bool
00205   push_file(const char *file, bool quietFileNotFoundError)
00206   {
00207     FILE *try_fd;
00208     std::string sfile;
00209 
00210     if (strlen(file) > 2 && file[0] == '/' && file[1] == '/') {
00211       file += 2;
00212       sfile =  std::string( eyedblib::CompileBuiltin::getSysconfdir()) + "/eyedb/" + file;
00213     }
00214     else 
00215       sfile = file;
00216 
00217     try_fd = fopen(sfile.c_str(), "r");
00218     if (!try_fd) {
00219       if (quietFileNotFoundError)
00220         return false;
00221       else
00222         error("%scannot open file '%s' for reading",
00223               line_str(), sfile.c_str());
00224     }
00225 
00226     fd = try_fd;
00227 
00228     pline = &line[fd_w];
00229     fd_sp[fd_w] = fd;
00230     file_sp[fd_w] = strdup(file);
00231     pfile = file_sp[fd_w];
00232     *pline = 1;
00233     fd_w++;
00234 
00235     return true;
00236   }
00237 
00238   static const char *
00239   nexttoken_realize(Config *config)
00240   {
00241     static char tok[512];
00242     char c;
00243 
00244     if (!skip_spaces())
00245       return 0;
00246 
00247     int is_spe;
00248 
00249     if (!check_spe(is_spe))
00250       return 0;
00251     if (is_spe == 1)
00252       return term;
00253     if (is_spe == 2)
00254       return assign;
00255 
00256     char *p = tok;
00257     int force = 0;
00258     int hasvar = 0;
00259     int backslash = 0;
00260     char svar[128];
00261     char *var = 0;
00262 
00263     for (;;) {
00264       if (!force && !skip_comments())
00265         return 0;
00266 
00267       c = fgetc(fd);
00268       if (c == EOF)
00269         return 0;
00270 
00271       if (c == '%') {
00272         if (!var) {
00273           var = svar;
00274           continue;
00275         }
00276 
00277         *var = 0;
00278         *p = 0;
00279 
00280         if (!*svar)
00281           strcat(tok, "%");
00282         else {
00283           const char *val = config->getValue(svar);
00284           if (!val)
00285             error("%sunknown configuration variable '%s'", line_str(), svar);
00286           strcat(tok, val);
00287         }
00288 
00289         p = tok + strlen(tok);
00290         var = 0;
00291         hasvar = 1;
00292         continue;
00293       }
00294 
00295       if (var) {
00296         if (var - svar >= sizeof(svar)) {
00297           svar[sizeof(svar)-1] = 0;
00298           error("%sconfiguration variable too long: '%s' "
00299                 "(maximum size is %s)", line_str(), svar,
00300                 str_convert((long)sizeof(svar)-1).c_str());
00301         }
00302 
00303         *var++ = c;
00304         continue;
00305       }
00306 
00307       if (c == '"' && !force) {
00308         force = 1;
00309         continue;
00310       }
00311 
00312       if (force && c == '\\') {
00313         backslash = 1;
00314         continue;
00315       }
00316 
00317       if (c == '\n') {
00318         (*pline)++;
00319         if (!force)
00320           break;
00321       }
00322       else if (!force) {
00323         if (c == ' ' || c == '\t')
00324           break;
00325         else if (c == ';' || c == '=') {
00326           ungetc(c, fd);
00327           break;
00328         }
00329       }
00330       else {
00331         if (backslash) {
00332           if (c == 'n')
00333             c = '\n';
00334           else if (c == 'a')
00335             c = '\a';
00336           else if (c == 'b')
00337             c = '\b';
00338           else if (c == 'f')
00339             c = '\f';
00340           else if (c == 'r')
00341             c = '\r';
00342           else if (c == 't')
00343             c = '\t';
00344           else if (c == 'v')
00345             c = '\v';
00346           else if (c == '\\')
00347             c = '\\';
00348 
00349           backslash = 0;
00350         }
00351         else if (c == '"')
00352           break;
00353       }
00354 
00355       *p++ = c;
00356     }
00357 
00358     *p = 0;
00359 
00360     return (p != tok || force || hasvar) ? tok : nexttoken_realize(config);
00361   }
00362 
00363   static const char *
00364   nexttoken(Config *config)
00365   {
00366     const char *p = nexttoken_realize(config);
00367 
00368     if (!p) {
00369       if (fd_w > 0 && --fd_w > 0)
00370         {
00371           fd = fd_sp[fd_w-1];
00372           pline = &line[fd_w-1];
00373           pfile = file_sp[fd_w-1];
00374           return nexttoken(config);
00375         }
00376 
00377       return 0;
00378     }
00379 
00380     if (!strcmp(p, "include") || !strcmp(p, "@include")) {
00381       bool quiet = !strcmp(p, "@include");
00382 
00383       const char *file = nexttoken_realize(config);
00384       if (!file) {
00385         syntax_error("file name expected after include");
00386         return 0;
00387       }
00388 
00389       push_file(file, quiet);
00390 
00391       return nexttoken(config);
00392     }
00393 
00394     return p;
00395   }
00396 
00397   bool Config::add(const char *file, bool quietFileNotFoundError)
00398   {
00399     if (!push_file(file, quietFileNotFoundError))
00400       return false;
00401 
00402     int state = 0;
00403     char *name = 0, *value = 0;
00404 
00405     bool last = false;
00406 
00407     while (!last) {
00408       const char *p = nexttoken(this);
00409 
00410       if (!p) {
00411         p = "\n";
00412         last = true;
00413       }
00414 
00415       switch(state) {
00416       case 0:
00417         if (!strcmp(p, term))
00418           break;
00419         if (!strcmp(p, assign))
00420           syntax_error(std::string("unexpected '") + p + "'");
00421         name = strdup(p);
00422         state = 1;
00423         break;
00424 
00425       case 1:
00426         if (strcmp(p, assign))
00427           syntax_error(std::string("'") + assign + "' expected, got '" + p + "'");
00428         state = 2;
00429         break;
00430 
00431       case 2:
00432         if (!strcmp(p, assign) || !strcmp(p, term))
00433           syntax_error(std::string("unexpected '") + p + "'");
00434         value = strdup(p);
00435         state = 3;
00436         break;
00437 
00438       case 3:
00439         if (strcmp(p, term))
00440           syntax_error(std::string("'") + term + "' expected, got '" + p + "'");
00441         setValue( name, value);
00442         free(name);
00443         free(value);
00444         name = 0;
00445         value = 0;
00446         state = 0;
00447         break;
00448       }
00449     }
00450 
00451     return true;
00452   }
00453 
00454 
00455   /*
00456    * Config and Config::Item constructors, destructor and operator=
00457    */
00458 
00459   Config::Config()
00460     : list(), var_map(0)
00461   {
00462   }
00463 
00464   /*
00465   Config::Config(const char *file, const VarMap &_var_map)
00466   {
00467     var_map = new VarMap(_var_map);
00468     add(file);
00469   }
00470   */
00471 
00472   Config::Config(const std::string &name) :
00473     name(name)
00474   {
00475     var_map = 0;
00476   }
00477 
00478   Config::Config(const std::string &name, const VarMap &_var_map) :
00479     name(name)
00480   {
00481     var_map = new VarMap(_var_map);
00482   }
00483 
00484   Config::Config(const Config &config)
00485   {
00486     *this = config;
00487   }
00488 
00489   void
00490   Config::garbage()
00491   {
00492     LinkedListCursor c(list);
00493     Item *item;
00494 
00495     while (c.getNext((void *&)item))
00496       delete item;
00497 
00498     list.empty();
00499   }
00500 
00501   Config& Config::operator=(const Config &config)
00502   {
00503     garbage();
00504 
00505     LinkedListCursor c(config.list);
00506     Item *item;
00507     while(c.getNext((void *&)item)) {
00508       list.insertObjectFirst(new Item(*item));
00509     }
00510 
00511     var_map = config.var_map ? new VarMap(*config.var_map) : 0;
00512     return *this;
00513   }
00514 
00515   Config::~Config()
00516   {
00517     garbage();
00518   }
00519 
00520   Config::Item& Config::Item::operator=(const Item &item)
00521   {
00522     if (this == &item)
00523       return *this;
00524 
00525     free(name);
00526     free(value);
00527     name = strdup(item.name);
00528     value = strdup(item.value);
00529     return *this;
00530   }
00531 
00532   Config::Item::Item()
00533   {
00534     name = 0;
00535     value = 0;
00536   }
00537 
00538   Config::Item::Item(const char *_name, const char *_value)
00539   {
00540     name = strdup(_name);
00541     value = strdup(_value);
00542   }
00543 
00544   Config::Item::Item(const Item &item)
00545   {
00546     name = strdup(item.name);
00547     value = strdup(item.value);
00548   }
00549 
00550   Config::Item::~Item()
00551   {
00552     free(name);
00553     free(value);
00554   }
00555 
00556 
00557   /*
00558    * Config operator<<
00559    */
00560 
00561   std::ostream& operator<<( std::ostream& os, const Config& config)
00562   {
00563     LinkedListCursor c(config.list);
00564     Config::Item *item;
00565 
00566     while (c.getNext((void *&)item)) {
00567       os << "name= " << item->name << " value= " << item->value << std::endl;
00568     }
00569 
00570     return os;
00571   }
00572 
00573 
00574   /*
00575    * Config static _release method
00576    */
00577 
00578   void
00579   Config::_release()
00580   {
00581     ClientConfig::_release();
00582     ServerConfig::_release();
00583   }
00584 
00585   void ClientConfig::_release()
00586   {
00587     delete instance;
00588     instance = 0;
00589   }
00590 
00591   void ServerConfig::_release()
00592   {
00593     delete instance;
00594     instance = 0;
00595   }
00596 
00597   /*
00598    * Config variable set and get
00599    */
00600 
00601   void
00602   Config::checkIsIn(const char *name)
00603   {
00604     if (!var_map)
00605       return;
00606 
00607     if (*name == '$')
00608       return;
00609 
00610     if (var_map->find(name) != var_map->end())
00611       return;
00612 
00613     VarMap::const_iterator begin = var_map->begin();
00614     VarMap::const_iterator end = var_map->end();
00615     std::string msg = "known variables are: ";
00616     for (int n = 0; begin != end; n++) {
00617       if (n)
00618         msg += ", ";
00619       msg += (*begin).first;
00620       ++begin;
00621     }
00622     
00623     error("unknown variable '%s' found in %s configuration file.\n%s",
00624           name, getName().c_str(), msg.c_str());
00625   }
00626 
00627   void 
00628   Config::setValue(const char *name, const char *value)
00629   {
00630     checkIsIn(name);
00631 
00632     Item *item = new Item(name, value);
00633     list.insertObjectFirst(item);
00634   }
00635 
00636   static char *copySTDString(const std::string &value)
00637   {
00638     static const int VALUE_BUFFER_CNT = 128;
00639     static unsigned int n = 0;
00640     static char *buf[VALUE_BUFFER_CNT];
00641 
00642     if (n == VALUE_BUFFER_CNT)
00643       n = 0;
00644 
00645     if (!buf[n] || strlen(buf[n]) < value.length()) {
00646       delete [] buf[n];
00647       buf[n] = new char[value.length()+1];
00648     }
00649 
00650     strcpy(buf[n], value.c_str());
00651     return buf[n++];
00652   }
00653 
00654   bool Config::isBuiltinVar(const char *name)
00655   {
00656     return *name == '@';
00657   }
00658 
00659   bool Config::isUserVar(const char *name)
00660   {
00661     return *name == '$';
00662   }
00663 
00664   const char *Config::getValue(const char *name) const
00665   {
00666     if (!isBuiltinVar(name) && !isUserVar(name)) {
00667       const char *s = getenv((std::string("EYEDB") + uppercase(name)).c_str());
00668       if (s)
00669         return s;
00670     }
00671 
00672     LinkedListCursor c(list);
00673     Item *item;
00674 
00675     while (c.getNext((void *&)item))
00676       if (!strcasecmp(item->name, name)) {
00677         if (!strchr(item->value, '%')) {
00678           return item->value;
00679         }
00680 
00681         std::string value;
00682 
00683         char *s = item->value;
00684         char *var;
00685         bool state = false;
00686 
00687         while (char c = *s++) {
00688           if (c == '%') {
00689             if (state) {
00690               char svar[128];
00691               unsigned int len = s - var - 1;
00692               if (len >= sizeof(svar)) {
00693                 error("%sconfiguration variable too long: '%s' "
00694                       "(maximum size is %s)", line_str(), svar,
00695                       str_convert((long)sizeof(svar)-1).c_str());
00696               }
00697 
00698               strncpy(svar, var, len);
00699               svar[len] = 0;
00700               const char *val = getValue(svar);
00701               if (!val)
00702                 error("%sunknown configuration variable '%s'", line_str(), svar);
00703               value += val;
00704             }
00705             else {
00706               var = s;
00707             }
00708             state = !state;
00709           }
00710           else if (!state) {
00711             char tok[4];
00712             sprintf(tok, "%c", c);
00713             value += tok;
00714           }
00715         }
00716 
00717         return copySTDString(value);
00718       }
00719 
00720     return (const char *)0;
00721   }
00722 
00723   Config::Item *Config::getValues(unsigned int &item_cnt, bool expand_vars) const
00724   {
00725     item_cnt = list.getCount();
00726 
00727     if (!item_cnt)
00728       return (Item *)0;
00729 
00730     Item *items = new Item[list.getCount()];
00731 
00732     Item *item;
00733     LinkedListCursor c(list);
00734 
00735     unsigned int n;
00736     for (n = 0; c.getNext((void *&)item); ) {
00737       int _not = 0;
00738       for (int i = 0; i < n; i++)
00739         if (!strcmp(items[i].name, item->name)) {
00740           _not = 1;
00741           break;
00742         }
00743 
00744       if (!_not) {
00745         items[n] = *item;
00746         if (expand_vars) {
00747           items[n].value = strdup(getValue(item->name));
00748         }
00749         n++;
00750       }
00751     }
00752 
00753     Item *ritems = new Item[n];
00754     for (unsigned int i = 0; i < n; i++) {
00755       ritems[i] = items[n-i-1];
00756     }
00757 
00758     delete [] items;
00759     item_cnt = n;
00760     return ritems;
00761   }
00762 
00763 
00764   /*
00765    * Client and server config management
00766    */
00767 
00768   static const std::string tcp_port = "6240";
00769 
00770   void
00771   ClientConfig::setDefaults()
00772   {
00773     std::string pipedir = eyedblib::CompileBuiltin::getPipedir();
00774 
00775     // Port
00776     setValue( "port", (pipedir + "/eyedbd").c_str());
00777 
00778     // TCP Port
00779     setValue( "tcp_port", tcp_port.c_str());
00780 
00781     // Hostname
00782     setValue( "host", "localhost");
00783 
00784     // User
00785     setValue( "user", "@");
00786 
00787     // EYEDBDBM Database
00788     setValue( "dbm", "default");
00789   }
00790 
00791   void
00792   ServerConfig::setDefaults()
00793   {
00794     std::string bindir = eyedblib::CompileBuiltin::getBindir();
00795     std::string sbindir = eyedblib::CompileBuiltin::getSbindir();
00796     std::string libdir = eyedblib::CompileBuiltin::getLibdir();
00797     std::string databasedir = eyedblib::CompileBuiltin::getDatabasedir();
00798     std::string pipedir = eyedblib::CompileBuiltin::getPipedir();
00799     std::string tmpdir = eyedblib::CompileBuiltin::getTmpdir();
00800     std::string sysconfdir = eyedblib::CompileBuiltin::getSysconfdir();
00801 
00802 #ifdef BUILTIN_VARS
00803     setValue("@bindir", bindir.c_str());;
00804     setValue("@sbindir", sbindir.c_str());;
00805     setValue("@libdir", libdir.c_str());;
00806     setValue("@databasedir", databasedir.c_str());;
00807     setValue("@pipedir", pipedir.c_str());;
00808     setValue("@tmpdir", tmpdir.c_str());;
00809     setValue("@sysconfdir", sysconfdir.c_str());;
00810 
00811     // Bases directory
00812     setValue( "databasedir", "%@databasedir%");
00813 
00814     // tmpdir
00815     setValue( "tmpdir", "%@tmpdir%");
00816 
00817     // sopath
00818     setValue( "sopath", "%@libdir%/eyedb");
00819 
00820     // Default EYEDBDBM Databases
00821     setValue( "default_dbm", (databasedir + "/dbmdb.dbs").c_str());
00822 
00823     // Granted EYEDBDBM Databases
00824     //setValue( "granted_dbm", (localstatedir + "/lib/eyedb/db/dbmdb.dbs").c_str());
00825     // EV : 22/01/06
00826     // when variable expansion will be done in getValue(), granted_dbm will be:
00827     //setValue( "granted_dbm", "%default_dbm%");
00828 
00829     // Server Parameters
00830     setValue( "maximum_memory_size", "0");
00831     setValue( "access_file", "%@sysconfdir%/eyedb/Access");
00832 #ifdef HAVE_EYEDBSMD
00833     setValue( "smdport", "%@pipedir%/eyedbsmd");
00834 #endif
00835     setValue( "default_file_group", "");
00836     setValue( "default_file_mask", "0600");
00837 
00838     // Server Parameters
00839     setValue( "listen", ("localhost:" + tcp_port + ",%@pipedir%/eyedbd").c_str());
00840 
00841     // OQL path
00842     setValue( "oqlpath", "%@libdir%/eyedb/oql");
00843 #else
00844     // Bases directory
00845     setValue( "databasedir", databasedir.c_str());
00846 
00847     // tmpdir
00848     setValue( "tmpdir", tmpdir.c_str());
00849 
00850     // sopath
00851     setValue( "sopath", (libdir + "/eyedb").c_str());
00852 
00853     // Default EYEDBDBM Databases
00854     setValue( "default_dbm", (databasedir + "/dbmdb.dbs").c_str());
00855 
00856     // Granted EYEDBDBM Databases
00857     //setValue( "granted_dbm", (localstatedir + "/lib/eyedb/db/dbmdb.dbs").c_str());
00858     // EV : 22/01/06
00859     // when variable expansion will be done in getValue(), granted_dbm will be:
00860     //setValue( "granted_dbm", "%default_dbm%");
00861 
00862     // Server Parameters
00863     setValue( "maximum_memory_size", "0");
00864     setValue( "access_file", (sysconfdir + "/eyedb/Access").c_str());
00865 #ifdef HAVE_EYEDBSMD
00866     setValue( "smdport", (pipedir + "/eyedbsmd").c_str());
00867 #endif
00868     setValue( "default_file_group", "");
00869     setValue( "default_file_mask", "0600");
00870 
00871     // Server Parameters
00872     setValue( "listen", ("localhost:" + tcp_port + "," + pipedir + "/eyedbd").c_str());
00873 
00874     // OQL path
00875     setValue( "oqlpath", (libdir + "/eyedb/oql").c_str());
00876 #endif
00877   }
00878 
00879   void
00880   Config::loadConfigFile( const std::string& configFilename, const char* envVariable, const char* defaultFilename)
00881   {
00882     const char* envFileName;
00883 
00884     if (configFilename.length() != 0) {
00885       add(configFilename.c_str(), false);
00886     }
00887     else if ((envFileName = getenv(envVariable))) {
00888       add(envFileName, false);
00889     }
00890     else {
00891       struct passwd* pw = getpwuid(getuid());
00892 
00893       if (pw) {
00894         std::string homeConfigFile = std::string(pw->pw_dir) + "/.eyedb/" + defaultFilename;
00895         if (add(homeConfigFile.c_str(), true))
00896           return;
00897       }
00898 
00899       const char *confdir = getenv("EYEDBCONFDIR");
00900       if (confdir) {
00901         add((std::string(confdir) + "/" + defaultFilename).c_str(), false);
00902         return;
00903       }
00904       std::string sysConfigFile = std::string(eyedblib::CompileBuiltin::getSysconfdir()) + "/eyedb/" + defaultFilename;
00905 
00906       add(sysConfigFile.c_str(), true);
00907     }
00908   }
00909 
00910   Status
00911   ClientConfig::setConfigFile(const std::string &file)
00912   {
00913     if (instance)
00914       return Exception::make(IDB_INTERNAL_ERROR, "Cannot set client config file after configuration");
00915 
00916     config_file = file;
00917     
00918     return Success;
00919   }
00920 
00921   static Config::VarMap client_map;
00922   static Config::VarMap server_map;
00923 
00924   static struct C {
00925 
00926     C() {
00927 #ifdef BUILTIN_VARS
00928       server_map["@bindir"] = true;
00929       server_map["@sbindir"] = true;
00930       server_map["@libdir"] = true;
00931       server_map["@sysconfdir"] = true;
00932       server_map["@databasedir"] = true;
00933       server_map["@pipedir"] = true;
00934       server_map["@tmpdir"] = true;
00935 #endif
00936       client_map["port"] = true;
00937       client_map["tcp_port"] = true;
00938       client_map["host"] = true;
00939       client_map["user"] = true;
00940       client_map["passwd"] = true;
00941       client_map["dbm"] = true;
00942 
00943       server_map["databasedir"] = true;
00944       server_map["tmpdir"] = true;
00945       server_map["sopath"] = true;
00946       server_map["granted_dbm"] = true;
00947       server_map["default_dbm"] = true;
00948       server_map["access_file"] = true;
00949       server_map["maximum_memory_size"] = true;
00950       server_map["default_file_group"] = true;
00951       server_map["default_file_mask"] = true;
00952 #ifdef HAVE_EYEDBSMD
00953       server_map["smdport"] = true;
00954 #endif
00955       server_map["listen"] = true;
00956       server_map["oqlpath"] = true;
00957     }
00958   } _;
00959 
00960   ClientConfig::ClientConfig() : Config("client", client_map)
00961   {
00962   }
00963 
00964   ClientConfig* 
00965   ClientConfig::getInstance()
00966   {
00967     if (instance)
00968       return instance;
00969 
00970     instance = new ClientConfig();
00971 
00972     instance->setDefaults();
00973 
00974     instance->loadConfigFile(config_file, "EYEDBCONF", "eyedb.conf");
00975 
00976     return instance;
00977   }
00978   
00979   ServerConfig::ServerConfig() : Config("server", server_map)
00980   {
00981   }
00982 
00983   Status
00984   ServerConfig::setConfigFile(const std::string &file)
00985   {
00986     if (instance)
00987       return Exception::make(IDB_INTERNAL_ERROR, "Cannot set server config file after configuration");
00988 
00989     config_file = file;
00990     return Success;
00991   }
00992 
00993   ServerConfig* 
00994   ServerConfig::getInstance()
00995   {
00996     if (instance)
00997       return instance;
00998 
00999     instance = new ServerConfig();
01000     
01001     instance->setDefaults();
01002 
01003     instance->loadConfigFile(config_file, "EYEDBDCONF", "eyedbd.conf");
01004 
01005     return instance;
01006   }
01007 }

Generated on Mon Dec 22 18:15:53 2008 for eyedb by  doxygen 1.5.3