Confdump Agent
1.4.0
|
00001 /* 00002 * Confdump-Agent - Dump static and runtime system configuration 00003 * Copyright (C) 2009-2012 Straton IT, SAS 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 version 3 as 00007 * published by the Free Software Foundation. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include <iostream> 00019 #include <vector> 00020 00021 #include "QFile" 00022 #include "QTextStream" 00023 00024 #include "boost/foreach.hpp" 00025 #include "boost/bind.hpp" 00026 #include "boost/program_options.hpp" 00027 #include "boost/program_options/cmdline.hpp" 00028 namespace po = boost::program_options; 00029 namespace pos = boost::program_options::command_line_style; 00030 00031 #include "Confdump/Options.hpp" 00032 #include "Confdump/RuntimeError.hpp" 00033 #include "Confdump/DumperFactory.hpp" 00034 00035 using std::vector; 00036 using std::string; 00037 using boost::bind; 00038 00039 namespace Confdump 00040 { 00041 00042 Options::Options( int argc, char **argv, std::ostream &out ) 00043 { 00044 po::options_description gettingHelp( tr( "Getting help" ).toLocal8Bit().constData() ); 00045 gettingHelp.add_options() 00046 ( "help,h", tr( "This information", "--help" ).toLocal8Bit().constData() ) 00047 ( "help-tables", 00048 tr( "displays a list of tables that can be queried and exits" 00049 " (can be combined with --output-file)" ).toLocal8Bit().constData() ) 00050 ; 00051 00052 po::options_description select( tr( "Configuration selection" ).toLocal8Bit().constData() ); 00053 select.add_options() 00054 ( "table", po::value< vector<string> >()->notifier( bind( &Options::setTables, this, _1 ) ), 00055 tr( "tables to query (can be specified multiple times); format: [dumper.]table" ).toLocal8Bit().constData() ) 00056 ( "tables-from", po::value< string >()->notifier( bind( &Options::readTablesFrom, this, _1 ) ), 00057 tr( "read a list of tables to query from this file" ).toLocal8Bit().constData() ) 00058 ; 00059 00060 po::options_description dumpers( tr( "Extra dumpers" ).toLocal8Bit().constData() ); 00061 dumpers.add_options() 00062 ( "add-dumper", po::value< vector<string> >()->notifier( bind( &Options::setDumpers, this, _1 ) ), 00063 tr( "instanciate a new Dumper with a given alias (can be specified mutiple times); " 00064 "format: alias=Dumper" ).toLocal8Bit().constData() ) 00065 ( "dumper-arg", po::value< vector<string> >()->notifier( bind( &Options::setDumperArgs, this, _1 ) ), 00066 tr( "set an option on an instanciated Dumper (can be specified mutiple times); " 00067 "format: alias.option=value" ).toLocal8Bit().constData() ) 00068 ; 00069 00070 po::options_description output( tr( "Output" ).toLocal8Bit().constData() ); 00071 output.add_options() 00072 /*( "verbose,v", po::value< string >()->notifier( bind( &Options::setVerbosity, this, _1 ) ) 00073 ->default_value( "info" )->implicit_value( "debug" ), 00074 tr( "sets verbosity to one of: trace, debug, info, warn, error" ).toLocal8Bit().constData() )*/ 00075 ( "output-format", po::value< string >()->notifier( bind( &Options::setOutputFormat, this, _1 ) ) 00076 ->default_value( "text" ), 00077 tr( "sets output format to one of: text, xml" ).toLocal8Bit().constData() ) 00078 ( "output-file", po::value< string >()->notifier( bind( &Options::setOutputFile, this, _1 ) ), 00079 tr( "output to a file instead of standard output" ).toLocal8Bit().constData() ) 00080 ; 00081 00082 po::options_description allOptions( tr( 00083 "\n" 00084 CONFDUMP_VERSION " - Dump static and runtime system configuration\n" 00085 "Copyright (C) 2009-2012 Straton IT, SAS\n" 00086 "More information at http://confdump.sf.net/\n" 00087 "\n" 00088 "This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n" 00089 "are welcome to redistribute it under the terms of the GPL version 3.\n" 00090 "\n" 00091 "Command-line options and arguments", "options description" ).toLocal8Bit().constData() ); 00092 allOptions.add( gettingHelp ).add( select ).add( dumpers ).add( output ); 00093 00094 pos::style_t style = static_cast<pos::style_t> ( 00095 pos::allow_long | // --foo 00096 pos::long_allow_next | // --foo bar 00097 pos::allow_short | // -f 00098 pos::allow_dash_for_short | // -f 00099 pos::short_allow_next | // -f bar 00100 pos::allow_sticky ); // -fF same as -f -F 00101 00102 po::variables_map vm; 00103 po::store( po::parse_command_line( argc, argv, allOptions, style ), vm ); 00104 po::notify( vm ); 00105 00106 if ( vm.count( "help" ) ) 00107 { 00108 operatingMode_ = HelpMode; 00109 out << allOptions << std::endl; 00110 #if CD_WIN32 00111 out << "WMI dumper options:\n"; 00112 out << " namespace (sets the WMI namespace to query, defaults to ROOT\\CIMv2)\n"; 00113 out << "\n"; 00114 out << "Win32 dumper options: (none)\n"; 00115 #elif CD_UNIX 00116 //out << "Linux dumper options: none\n"; 00117 #endif 00118 out << std::endl; 00119 } 00120 else if ( vm.count( "help-tables" ) ) 00121 { 00122 operatingMode_ = HelpTablesMode; 00123 } 00124 else 00125 { 00126 operatingMode_ = NormalMode; 00127 } 00128 } 00129 00130 Options::~Options() 00131 { 00132 } 00133 00134 void Options::setVerbosity( const std::string &value ) 00135 { 00136 QString level( QString::fromLocal8Bit( value.c_str() ).toLower() ); 00137 if ( level == "trace" ) 00138 logLevel_ = Trace; 00139 else if ( level == "debug" ) 00140 logLevel_ = Debug; 00141 else if ( level == "info" || level == "information" ) 00142 logLevel_ = Info; 00143 else if ( level == "warn" || level == "warning" ) 00144 logLevel_ = Warning; 00145 else if ( level == "error" ) 00146 logLevel_ = Error; 00147 else 00148 throw RuntimeError( tr( "Unknown verbosity level: '%1'" ).arg( level ) ); 00149 } 00150 00151 void Options::setOutputFormat( const std::string &value ) 00152 { 00153 QString format( QString::fromLocal8Bit( value.c_str() ).toLower() ); 00154 if ( format == "text" ) 00155 outputFormat_ = TextFormat; 00156 else if ( format == "xml" ) 00157 outputFormat_ = XmlFormat; 00158 else 00159 throw RuntimeError( tr( "Unknown output format: '%1'" ).arg( format ) ); 00160 } 00161 00162 void Options::setOutputFile( const std::string &value ) 00163 { 00164 outputFile_ = QString::fromLocal8Bit( value.c_str() ); 00165 } 00166 00167 namespace 00168 { 00169 00170 Options::TableList::value_type parseTable( QString qualifiedTable ) 00171 { 00172 if ( qualifiedTable.count( '.' ) == 1 ) 00173 { 00174 QString alias = qualifiedTable.section( '.', 0, 0 ); 00175 QString table = qualifiedTable.section( '.', -1, -1 ); 00176 return std::make_pair( alias, table ); 00177 } 00178 else 00179 { 00180 return std::make_pair( "main", qualifiedTable ); 00181 } 00182 } 00183 00184 } 00185 00186 void Options::setTables( const std::vector< std::string > &raw_tables ) 00187 { 00188 TableList tables; 00189 BOOST_FOREACH( const std::string &raw_table, raw_tables ) 00190 { 00191 QString qualifiedTable = QString::fromLocal8Bit( raw_table.c_str() ); 00192 tables << parseTable( qualifiedTable ); 00193 } 00194 tables_ = tables; 00195 } 00196 00197 void Options::setDumpers( const std::vector< std::string > &raw_dumpers ) 00198 { 00199 BOOST_FOREACH( const std::string &raw_dumper, raw_dumpers ) 00200 { 00201 QString dumper = QString::fromLocal8Bit( raw_dumper.c_str() ); 00202 QString alias = dumper.section( '=', 0, 0 ).toLower(); 00203 QString implementation = dumper.section( '=', 1, -1 ).toLower(); 00204 if ( alias.isEmpty() || implementation.isEmpty() ) 00205 throw RuntimeError( "Invalid --add-dumper argument (must be alias=Dumper)" ); 00206 dumperAliases_[alias] = implementation; 00207 } 00208 } 00209 00210 void Options::setDumperArgs( const std::vector< std::string > &raw_args ) 00211 { 00212 BOOST_FOREACH( const std::string &raw_arg, raw_args ) 00213 { 00214 QString arg = QString::fromLocal8Bit( raw_arg.c_str() ); // alias.key=value 00215 QString qualifiedKey = arg.section( '=', 0, 0 ).toLower(); // alias.key 00216 std::pair<QString, QString> key = parseTable( qualifiedKey ); 00217 QString value = arg.section( '=', 1, -1 ); 00218 if ( key.first.isEmpty() || key.second.isEmpty() || value.isEmpty() ) 00219 throw RuntimeError( "Invalid --dumper-arg argument (must be alias.key=value)" ); 00220 dumperArguments_[key.first][key.second] = value; 00221 } 00222 } 00223 00224 std::map< QString, DumperSpecification > Options::dumperSpecifications() const 00225 { 00226 // Merge dumperAliases_ + dumperArguments_ 00227 std::map< QString, DumperSpecification > specifications; 00228 00229 BOOST_FOREACH( DumperAliases::value_type dumper, dumperAliases_ ) 00230 { 00231 DumperSpecification spec; 00232 QString alias = dumper.first; 00233 spec.name = dumper.second; 00234 spec.parameters = dumperArguments_[alias]; 00235 specifications[alias] = spec; 00236 } 00237 00238 // Check for unused arguments 00239 BOOST_FOREACH( DumperArguments::value_type args, dumperArguments_ ) 00240 { 00241 QString alias = args.first; 00242 if ( specifications.find( alias ) == specifications.end() ) 00243 throw RuntimeError( "Undefined alias used in --dumper-arg: " + alias ); 00244 } 00245 00246 return specifications; 00247 } 00248 00249 void Options::readTablesFrom( const std::string &fileName8b ) 00250 { 00251 QString fileName( QString::fromLocal8Bit( fileName8b.c_str() ) ); 00252 QFile file( fileName ); 00253 if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) 00254 throw RuntimeError( "Couldn't open "+fileName+" for reading: "+file.error() ); 00255 00256 QTextStream in( &file ); 00257 while ( !in.atEnd() ) 00258 { 00259 QString line = in.readLine(); 00260 if ( !line.isEmpty() && line[0] != '#' ) 00261 tables_ << parseTable( line ); 00262 } 00263 } 00264 00265 Options::TableList Options::tables() const 00266 { 00267 return tables_; 00268 } 00269 00270 }