nis-util  1.0.D108
lib/configuration.cc
Go to the documentation of this file.
00001 //
00002 // nis-util - NIS Administration Utilities
00003 // Copyright (C) 2012 Peter Miller
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or (at
00008 // your option) any later version.
00009 //
00010 // This program 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 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License along
00016 // with this program. If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 
00019 #include <lib/ac/unistd.h>
00020 #include <libexplain/output.h>
00021 #include <libexplain/program_name.h>
00022 
00023 #include <lib/boolean.h>
00024 #include <lib/configuration.h>
00025 #include <lib/configuration/item/boolean.h>
00026 #include <lib/configuration/item/integer.h>
00027 #include <lib/configuration/item/string.h>
00028 #include <lib/home.h>
00029 #include <lib/input/file.h>
00030 #include <lib/input/string.h>
00031 #include <lib/libdir.h>
00032 #include <lib/path_join.h>
00033 
00034 
00035 configuration *configuration::singleton;
00036 
00037 
00038 configuration::~configuration()
00039 {
00040 }
00041 
00042 
00043 configuration::configuration()
00044 {
00045 }
00046 
00047 
00048 configuration &
00049 configuration::get_singleton(void)
00050 {
00051     if (!singleton)
00052     {
00053         singleton = new configuration();
00054         singleton->load();
00055     }
00056     return *singleton;
00057 }
00058 
00059 
00060 rcstring
00061 configuration::get_string(const rcstring &section_name,
00062     const rcstring &item_name) const
00063 {
00064     sections_t::const_iterator it = sections.find(section_name);
00065     if (it == sections.end())
00066         return rcstring();
00067     assert(it->second);
00068     return it->second->get_string_value(item_name);
00069 }
00070 
00071 
00072 bool
00073 configuration::get_bool(const rcstring &section_name, const rcstring &item_name)
00074     const
00075 {
00076     sections_t::const_iterator it = sections.find(section_name);
00077     if (it == sections.end())
00078         return false;
00079     assert(it->second);
00080     return it->second->get_bool_value(item_name);
00081 }
00082 
00083 
00084 long
00085 configuration::get_long(const rcstring &section_name, const rcstring &item_name)
00086     const
00087 {
00088     sections_t::const_iterator it = sections.find(section_name);
00089     if (it == sections.end())
00090         return 0;
00091     assert(it->second);
00092     return it->second->get_long_value(item_name);
00093 }
00094 
00095 
00096 void
00097 configuration::set(const rcstring &section_name,
00098     const configuration_item::pointer &item)
00099 {
00100     assert(section_name.empty() ||
00101         section_name == canonical_name(section_name));
00102     assert(item->get_name() == canonical_name(item->get_name()));
00103 
00104     sections_t::iterator it = sections.find(section_name);
00105     if (it == sections.end())
00106     {
00107         configuration_section::pointer sp =
00108             configuration_section::create(section_name);
00109         sections.insert(sections_t::value_type(section_name, sp));
00110         sp->set(item);
00111     }
00112     else
00113     {
00114         assert(it->second);
00115         it->second->set(item);
00116     }
00117 }
00118 
00119 
00120 static bool
00121 test_mode(void)
00122 {
00123     const char *cp = getenv("NIS_UTIL_TEST_MODE");
00124     if (!cp)
00125         return false;
00126     bool value = false;
00127     if (!boolean_from_string(cp, value))
00128     {
00129         explain_output_error_and_die
00130         (
00131             "the NIS_UTIL_TEST_MODE environment variable must "
00132                 "be either \"true\" or \"false\", not %s",
00133             rcstring(cp).quote_c().c_str()
00134         );
00135         return false;
00136     }
00137     return value;
00138 }
00139 
00140 
00141 void
00142 configuration::load(void)
00143 {
00144     //
00145     // some builtin defaults
00146     //
00147     {
00148         // This host's sysconf(_SC_NGROUPS_MAX) may be too generous for
00149         // all NIS clients.  Be conservative.  The value of 16 is a very
00150         // well known NFS implimentation limit.
00151         cfg.set_builtin_long(SECTION_GROUP, "per-user-maximum", 16);
00152 
00153         cfg.set_builtin_bool(SECTION_GLOBAL, "verbose", true);
00154         cfg.set_builtin_bool(SECTION_GLOBAL, "pedentic", true);
00155         cfg.set_builtin_bool(SECTION_GLOBAL, ITEM_WARNING, true);
00156     }
00157 
00158     if (test_mode())
00159         return;
00160 
00161     //
00162     // the $SYCONFDIR/nis-util.conf file
00163     // if it exists
00164     //
00165     {
00166         rcstring path = path_join(configured_sysconfdir(), "nis-util.conf");
00167         if (access(path.c_str(), F_OK) == 0)
00168         {
00169             level_t level = configuration_item::level_etc_nis_util_conf;
00170             input::pointer ip = input_file::create(path);
00171             parse(level, ip);
00172         }
00173     }
00174 
00175     //
00176     // the ~/.nis-util.rc file
00177     // if it exists
00178     //
00179     {
00180         rcstring path = path_join(home(), ".nis-util.rc");
00181         if (access(path.c_str(), F_OK) == 0)
00182         {
00183             level_t level = configuration_item::level_home_nis_util_rc;
00184             input::pointer ip = input_file::create(path);
00185             parse(level, ip);
00186         }
00187     }
00188 
00189     //
00190     // the NIS_UTIL evironment variable
00191     //
00192     {
00193         level_t level = configuration_item::level_nis_util_env;
00194         input::pointer ip = input_string::create_env("NIS_UTIL");
00195         parse(level, ip);
00196     }
00197 
00198     //
00199     // the util-specific environment variable
00200     //
00201     {
00202         level_t level = configuration_item::level_nis_util_prog_env;
00203         rcstring name(explain_program_name_get());
00204         name = name.upcase().identifier();
00205         input::pointer ip = input_string::create_env(name);
00206         parse(level, ip);
00207     }
00208 }
00209 
00210 
00211 void
00212 configuration::load_command_line_file(const rcstring &filename)
00213 {
00214     level_t level = configuration_item::level_command_line_file;
00215     input::pointer ip = input_file::create(filename);
00216     parse(level, ip);
00217 }
00218 
00219 
00220 void
00221 configuration::set_command_line_string(const source_location &locn,
00222     const rcstring &section_name, const rcstring &item_name,
00223     const rcstring &value)
00224 {
00225     level_t level = configuration_item::level_command_line_option;
00226     configuration_item::pointer item =
00227         configuration_item_string::create(locn, level, item_name, value);
00228     set(section_name, item);
00229 }
00230 
00231 
00232 void
00233 configuration::set_command_line_long(const source_location &locn,
00234     const rcstring &section_name, const rcstring &item_name, long value)
00235 {
00236     level_t level = configuration_item::level_command_line_option;
00237     configuration_item::pointer item =
00238         configuration_item_integer::create(locn, level, item_name, value);
00239     set(section_name, item);
00240 }
00241 
00242 
00243 void
00244 configuration::set_command_line_bool(const source_location &locn,
00245     const rcstring &section_name, const rcstring &item_name, bool value)
00246 {
00247     level_t level = configuration_item::level_command_line_option;
00248     configuration_item::pointer item =
00249         configuration_item_boolean::create(locn, level, item_name, value);
00250     set(section_name, item);
00251 }
00252 
00253 
00254 void
00255 configuration::set_command_line_bool(const source_location &locn,
00256     const rcstring &item_name, bool value)
00257 {
00258     level_t level = configuration_item::level_command_line_option;
00259     configuration_item::pointer item =
00260         configuration_item_boolean::create(locn, level, item_name, value);
00261     set(SECTION_GLOBAL, item);
00262 }
00263 
00264 
00265 static int bn;
00266 
00267 
00268 void
00269 configuration::set_builtin_string(const rcstring &section_name,
00270     const rcstring &item_name, const rcstring &value)
00271 {
00272     source_location locn("builtin", ++bn);
00273     level_t level = configuration_item::level_builtin;
00274     configuration_item::pointer item =
00275         configuration_item_string::create(locn, level, item_name, value);
00276     set(section_name, item);
00277 }
00278 
00279 
00280 void
00281 configuration::set_builtin_long(const rcstring &section_name,
00282     const rcstring &item_name, long value)
00283 {
00284     source_location locn("builtin", ++bn);
00285     level_t level = configuration_item::level_builtin;
00286     configuration_item::pointer item =
00287         configuration_item_integer::create(locn, level, item_name, value);
00288     set(section_name, item);
00289 }
00290 
00291 
00292 void
00293 configuration::set_builtin_bool(const rcstring &section_name,
00294     const rcstring &item_name, bool value)
00295 {
00296     source_location locn("builtin", ++bn);
00297     level_t level = configuration_item::level_builtin;
00298     configuration_item::pointer item =
00299         configuration_item_boolean::create(locn, level, item_name, value);
00300     set(section_name, item);
00301 }
00302 
00303 
00304 void
00305 configuration::print(void)
00306     const
00307 {
00308     for
00309     (
00310         sections_t::const_iterator it = sections.begin();
00311         it != sections.end();
00312         ++it
00313     )
00314     {
00315         it->second->print();
00316     }
00317 }
00318 
00319 
00320 // vim: set ts=8 sw=4 et :