00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
00202
00203
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
00457
00458
00459 Config::Config()
00460 : list(), var_map(0)
00461 {
00462 }
00463
00464
00465
00466
00467
00468
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
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
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
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, bool expand_vars) 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
00673 LinkedListCursor c(list);
00674 Item *item;
00675
00676 while (c.getNext((void *&)item))
00677 if (!strcasecmp(item->name, name)) {
00678 if (!expand_vars) {
00679 return item->value;
00680 }
00681
00682 if (!strchr(item->value, '%')) {
00683 return item->value;
00684 }
00685
00686 std::string value;
00687
00688 char *s = item->value;
00689 char *var;
00690 bool state = false;
00691
00692 while (char c = *s++) {
00693 if (c == '%') {
00694 if (state) {
00695 char svar[128];
00696 unsigned int len = s - var - 1;
00697 if (len >= sizeof(svar)) {
00698 error("%sconfiguration variable too long: '%s' "
00699 "(maximum size is %s)", line_str(), svar,
00700 str_convert((long)sizeof(svar)-1).c_str());
00701 }
00702
00703 strncpy(svar, var, len);
00704 svar[len] = 0;
00705 const char *val = getValue(svar);
00706 if (!val)
00707 error("%sunknown configuration variable '%s'", line_str(), svar);
00708 value += val;
00709 }
00710 else {
00711 var = s;
00712 }
00713 state = !state;
00714 }
00715 else if (!state) {
00716 char tok[4];
00717 sprintf(tok, "%c", c);
00718 value += tok;
00719 }
00720 }
00721
00722 return copySTDString(value);
00723 }
00724
00725 return (const char *)0;
00726 }
00727
00728 Config::Item *Config::getValues(unsigned int &item_cnt, bool expand_vars) const
00729 {
00730 item_cnt = list.getCount();
00731
00732 if (!item_cnt)
00733 return (Item *)0;
00734
00735 Item *items = new Item[list.getCount()];
00736
00737 Item *item;
00738 LinkedListCursor c(list);
00739
00740 unsigned int n;
00741 for (n = 0; c.getNext((void *&)item); ) {
00742 int _not = 0;
00743 for (int i = 0; i < n; i++)
00744 if (!strcmp(items[i].name, item->name)) {
00745 _not = 1;
00746 break;
00747 }
00748
00749 if (!_not) {
00750 items[n] = *item;
00751 items[n].value = strdup(getValue(item->name, expand_vars));
00752 n++;
00753 }
00754 }
00755
00756 Item *ritems = new Item[n];
00757 for (unsigned int i = 0; i < n; i++) {
00758 ritems[i] = items[n-i-1];
00759 }
00760
00761 delete [] items;
00762 item_cnt = n;
00763 return ritems;
00764 }
00765
00766
00767
00768
00769
00770
00771 static const std::string tcp_port = "6240";
00772
00773 void
00774 ClientConfig::setDefaults()
00775 {
00776 std::string pipedir = eyedblib::CompileBuiltin::getPipedir();
00777
00778
00779 setValue( "port", (pipedir + "/eyedbd").c_str());
00780
00781
00782 setValue( "tcp_port", tcp_port.c_str());
00783
00784
00785 setValue( "host", "localhost");
00786
00787
00788 setValue( "user", "@");
00789
00790
00791 setValue( "dbm", "default");
00792 }
00793
00794 void
00795 ServerConfig::setDefaults()
00796 {
00797 std::string bindir = eyedblib::CompileBuiltin::getBindir();
00798 std::string sbindir = eyedblib::CompileBuiltin::getSbindir();
00799 std::string libdir = eyedblib::CompileBuiltin::getLibdir();
00800 std::string databasedir = eyedblib::CompileBuiltin::getDatabasedir();
00801 std::string pipedir = eyedblib::CompileBuiltin::getPipedir();
00802 std::string tmpdir = eyedblib::CompileBuiltin::getTmpdir();
00803 std::string sysconfdir = eyedblib::CompileBuiltin::getSysconfdir();
00804
00805 #ifdef BUILTIN_VARS
00806 setValue("@bindir", bindir.c_str());;
00807 setValue("@sbindir", sbindir.c_str());;
00808 setValue("@libdir", libdir.c_str());;
00809 setValue("@databasedir", databasedir.c_str());;
00810 setValue("@pipedir", pipedir.c_str());;
00811 setValue("@tmpdir", tmpdir.c_str());;
00812 setValue("@sysconfdir", sysconfdir.c_str());;
00813
00814
00815 setValue( "databasedir", "%@databasedir%");
00816
00817
00818 setValue( "tmpdir", "%@tmpdir%");
00819
00820
00821 setValue( "sopath", "%@libdir%/eyedb");
00822
00823
00824 setValue( "default_dbm", (databasedir + "/dbmdb.dbs").c_str());
00825
00826
00827
00828
00829
00830
00831
00832
00833 setValue( "maximum_memory_size", "0");
00834 setValue( "access_file", "%@sysconfdir%/eyedb/Access");
00835 #ifdef HAVE_EYEDBSMD
00836 setValue( "smdport", "%@pipedir%/eyedbsmd");
00837 #endif
00838 setValue( "default_file_group", "");
00839 setValue( "default_file_mask", "0600");
00840
00841
00842 setValue( "listen", ("localhost:" + tcp_port + ",%@pipedir%/eyedbd").c_str());
00843
00844
00845 setValue( "oqlpath", "%@libdir%/eyedb/oql");
00846 #else
00847
00848 setValue( "databasedir", databasedir.c_str());
00849
00850
00851 setValue( "tmpdir", tmpdir.c_str());
00852
00853
00854 setValue( "sopath", (libdir + "/eyedb").c_str());
00855
00856
00857 setValue( "default_dbm", (databasedir + "/dbmdb.dbs").c_str());
00858
00859
00860
00861
00862
00863
00864
00865
00866 setValue( "maximum_memory_size", "0");
00867 setValue( "access_file", (sysconfdir + "/eyedb/Access").c_str());
00868 #ifdef HAVE_EYEDBSMD
00869 setValue( "smdport", (pipedir + "/eyedbsmd").c_str());
00870 #endif
00871 setValue( "default_file_group", "");
00872 setValue( "default_file_mask", "0600");
00873
00874
00875 setValue( "listen", ("localhost:" + tcp_port + "," + pipedir + "/eyedbd").c_str());
00876
00877
00878 setValue( "oqlpath", (libdir + "/eyedb/oql").c_str());
00879 #endif
00880 }
00881
00882 void
00883 Config::loadConfigFile( const std::string& configFilename, const char* envVariable, const char* defaultFilename)
00884 {
00885 const char* envFileName;
00886
00887 if (configFilename.length() != 0) {
00888 add(configFilename.c_str(), false);
00889 }
00890 else if ((envFileName = getenv(envVariable))) {
00891 add(envFileName, false);
00892 }
00893 else {
00894 struct passwd* pw = getpwuid(getuid());
00895
00896 if (pw) {
00897 std::string homeConfigFile = std::string(pw->pw_dir) + "/.eyedb/" + defaultFilename;
00898 if (add(homeConfigFile.c_str(), true))
00899 return;
00900 }
00901
00902 const char *confdir = getenv("EYEDBCONFDIR");
00903 if (confdir) {
00904 add((std::string(confdir) + "/" + defaultFilename).c_str(), false);
00905 return;
00906 }
00907 std::string sysConfigFile = std::string(eyedblib::CompileBuiltin::getSysconfdir()) + "/eyedb/" + defaultFilename;
00908
00909 add(sysConfigFile.c_str(), true);
00910 }
00911 }
00912
00913 Status
00914 ClientConfig::setConfigFile(const std::string &file)
00915 {
00916 if (instance)
00917 return Exception::make(IDB_INTERNAL_ERROR, "Cannot set client config file after configuration");
00918
00919 config_file = file;
00920
00921 return Success;
00922 }
00923
00924 static Config::VarMap client_map;
00925 static Config::VarMap server_map;
00926
00927 static struct C {
00928
00929 C() {
00930 #ifdef BUILTIN_VARS
00931 server_map["@bindir"] = true;
00932 server_map["@sbindir"] = true;
00933 server_map["@libdir"] = true;
00934 server_map["@sysconfdir"] = true;
00935 server_map["@databasedir"] = true;
00936 server_map["@pipedir"] = true;
00937 server_map["@tmpdir"] = true;
00938 #endif
00939 client_map["port"] = true;
00940 client_map["tcp_port"] = true;
00941 client_map["host"] = true;
00942 client_map["user"] = true;
00943 client_map["passwd"] = true;
00944 client_map["dbm"] = true;
00945
00946 server_map["databasedir"] = true;
00947 server_map["tmpdir"] = true;
00948 server_map["sopath"] = true;
00949 server_map["granted_dbm"] = true;
00950 server_map["default_dbm"] = true;
00951 server_map["access_file"] = true;
00952 server_map["maximum_memory_size"] = true;
00953 server_map["default_file_group"] = true;
00954 server_map["default_file_mask"] = true;
00955 #ifdef HAVE_EYEDBSMD
00956 server_map["smdport"] = true;
00957 #endif
00958 server_map["listen"] = true;
00959 server_map["oqlpath"] = true;
00960 }
00961 } _;
00962
00963 ClientConfig::ClientConfig() : Config("client", client_map)
00964 {
00965 }
00966
00967 ClientConfig*
00968 ClientConfig::getInstance()
00969 {
00970 if (instance)
00971 return instance;
00972
00973 instance = new ClientConfig();
00974
00975 instance->setDefaults();
00976
00977 instance->loadConfigFile(config_file, "EYEDBCONF", "eyedb.conf");
00978
00979 return instance;
00980 }
00981
00982 ServerConfig::ServerConfig() : Config("server", server_map)
00983 {
00984 }
00985
00986 Status
00987 ServerConfig::setConfigFile(const std::string &file)
00988 {
00989 if (instance)
00990 return Exception::make(IDB_INTERNAL_ERROR, "Cannot set server config file after configuration");
00991
00992 config_file = file;
00993 return Success;
00994 }
00995
00996 ServerConfig*
00997 ServerConfig::getInstance()
00998 {
00999 if (instance)
01000 return instance;
01001
01002 instance = new ServerConfig();
01003
01004 instance->setDefaults();
01005
01006 instance->loadConfigFile(config_file, "EYEDBDCONF", "eyedbd.conf");
01007
01008 return instance;
01009 }
01010 }