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 extern "C" 00019 { 00020 #include <sys/types.h> 00021 #include <sys/stat.h> 00022 #include <fcntl.h> 00023 } 00024 00025 #include <cstdlib> // atol 00026 #include <algorithm> 00027 #include <map> 00028 00029 #include <iostream> 00030 #include "QString" 00031 #include "boost/iostreams/stream.hpp" 00032 #include "boost/iostreams/device/file_descriptor.hpp" 00033 #include "boost/system/system_error.hpp" 00034 #include "boost/algorithm/string/predicate.hpp" 00035 #include "boost/algorithm/string/classification.hpp" 00036 #include "boost/filesystem/operations.hpp" 00037 #include "boost/function.hpp" 00038 #include "boost/bind.hpp" 00039 #include "boost/foreach.hpp" 00040 #include "boost/iostreams/copy.hpp" 00041 #include "Confdump/System/LinuxDumper.hpp" 00042 #include "Confdump/Result.hpp" 00043 #include "Confdump/System/Linux/MoreElements.hpp" 00044 #include "Confdump/System/Linux/Process.hpp" 00045 #include "Confdump/System/Linux/EnvironmentVariable.hpp" 00046 #include "Confdump/System/Linux/OperatingSystem.hpp" 00047 #include "Confdump/System/Linux/Socket.hpp" 00048 #include "Confdump/System/Linux/NetworkInterface.hpp" 00049 #include "Confdump/System/Linux/ConfigurationFile.hpp" 00050 #include "Confdump/System/Linux/MountEntry.hpp" 00051 #include "Confdump/System/Linux/InittabEntry.hpp" 00052 #include "Confdump/System/Linux/Uptime.hpp" 00053 #include "Confdump/System/Linux/InitScript.hpp" 00054 #include "Confdump/System/Linux/RcdScript.hpp" 00055 00056 #include <QFile> 00057 00058 using boost::shared_ptr; 00059 using std::streambuf; 00060 using std::copy; 00061 using std::back_inserter; 00062 using namespace Confdump::System::Linux; 00063 namespace fs = boost::filesystem; 00064 00065 namespace Confdump 00066 { 00067 00068 namespace System 00069 { 00070 00071 00072 struct LinuxDumper::Impl 00073 { 00074 shared_ptr<SystemContext> systemContext; 00075 //a tablehandler contain the table's name in a string and a pointer to the function to get data. 00076 typedef std::map< QString, boost::function< Result( shared_ptr<LinuxDumper> ) > > TableHandlers; 00077 TableHandlers tableHandler; 00078 }; 00079 00080 LinuxDumper::LinuxDumper() 00081 : impl_( new Impl ) 00082 { 00083 using boost::bind; 00084 impl_->tableHandler["CD_Process"] = bind( &LinuxDumper::allProcesses, _1 ); 00085 impl_->tableHandler["CD_EnvironmentVariable"] = bind( &LinuxDumper::allEnvironmentVariables, _1 ); 00086 impl_->tableHandler["CD_CurrentKernel"] = bind( &LinuxDumper::operatingSystem, _1 ); 00087 impl_->tableHandler["CD_Socket"] = bind( &LinuxDumper::allSockets, _1 ); 00088 impl_->tableHandler["CD_NetworkInterface"] = bind( &LinuxDumper::allNetworkInterfaces, _1 ); 00089 impl_->tableHandler["CD_ConfigurationFile"] = bind( &LinuxDumper::allConfigurationFiles, _1 ); 00090 impl_->tableHandler["CD_FstabMountEntry"] = bind( &LinuxDumper::allMountEntries, _1, "/etc/fstab" ); 00091 impl_->tableHandler["CD_KernelMountEntry"] = bind( &LinuxDumper::allMountEntries, _1, "/proc/mounts" ); 00092 impl_->tableHandler["CD_InittabEntry"] = bind( &LinuxDumper::allInittabEntries, _1 ); 00093 impl_->tableHandler["CD_Uptime"] = bind( &Linux::Uptime::uptime, _1 ); 00094 impl_->tableHandler["CD_InitScript"] = bind( &Linux::InitScript::allInitScripts, _1 ); 00095 impl_->tableHandler["CD_RcdScript"] = bind( &Linux::RcdScript::allRcdScripts, _1 ); 00096 impl_->tableHandler["CD_BlockDevice"] = bind( &Linux::allBlockDevices, _1 ); 00097 } 00098 00099 LinuxDumper::~LinuxDumper() 00100 { 00101 } 00102 00103 QString LinuxDumper::doComputerIdentifier() 00104 { 00105 return Linux::NetworkInterface( "eth0" ).macAddress(); 00106 } 00107 00108 LinuxDumper::SystemContext& LinuxDumper::systemContext() 00109 { 00110 if ( !impl_->systemContext ) 00111 impl_->systemContext.reset( new SystemContext( shared_from_this() ) ); 00112 00113 return *impl_->systemContext; 00114 } 00115 00116 LinuxDumper::SystemContext::SystemContext( boost::shared_ptr<LinuxDumper> driver) 00117 : driver_( driver ) 00118 { 00119 } 00120 00121 LinuxDumper::SystemContext::~SystemContext() 00122 { 00123 } 00124 00125 shared_ptr<std::streambuf> LinuxDumper::SystemContext::openRoFile( const boost::filesystem::path &path ) const 00126 { 00127 int fd = ::open( path.string().c_str(), O_RDONLY ); 00128 if (fd == -1) 00129 { 00130 using namespace boost::system; 00131 throw system_error( errno, system_category, "open " + path.string() ); 00132 } 00133 else 00134 { 00135 using namespace boost::iostreams; 00136 return shared_ptr<std::streambuf>( new stream_buffer<file_descriptor_source>( fd, true ) ); 00137 } 00138 } 00139 00140 00141 QByteArray LinuxDumper::SystemContext::slurpConfigurationFile( const boost::filesystem::path &path, QString refersToTable ) 00142 { 00143 shared_ptr<Linux::ConfigurationFile> configFile( new Linux::ConfigurationFile( driver_, path, refersToTable ) ); 00144 configurationFiles_.push_back( configFile ); 00145 return configFile->fileContents(); 00146 } 00147 00148 QByteArray LinuxDumper::SystemContext::slurpConfigurationFile( QString path, QString refersToTable ) 00149 { 00150 QByteArray path_bytes = path.toLocal8Bit(); 00151 return slurpConfigurationFile( fs::path( path_bytes ), refersToTable ); 00152 } 00153 00154 Result LinuxDumper::SystemContext::allConfigurationFiles() const 00155 { 00156 return configurationFiles_; 00157 } 00158 00159 00160 Result LinuxDumper::allProcesses() 00161 { 00162 using namespace boost::algorithm; 00163 using namespace boost::filesystem; 00164 00165 Result result; 00166 00167 for ( directory_iterator iter( "/proc" ); iter != directory_iterator(); ++iter ) 00168 { 00169 if ( is_directory( iter->status() ) && all( iter->filename(), is_digit() ) ) 00170 { 00171 uint pid = atol( iter->filename().c_str() ); 00172 shared_ptr<Linux::Process> proc( new Linux::Process( shared_from_this(), pid ) ); 00173 result.push_back( proc ); 00174 } 00175 } 00176 00177 return result; 00178 } 00179 00180 Result LinuxDumper::allEnvironmentVariables() const 00181 { 00182 Result result; 00183 std::vector< shared_ptr< EnvironmentVariable > > rows( EnvironmentVariable::allSystemInstances( shared_from_this() ) ); 00184 copy( rows.begin(), rows.end(), back_inserter( result ) ); 00185 return result; 00186 } 00187 00188 Result LinuxDumper::operatingSystem() const 00189 { 00190 Result result; 00191 shared_ptr<OperatingSystem> current( new OperatingSystem( shared_from_this() ) ); 00192 result.push_back( current ); 00193 return result; 00194 } 00195 00196 QStringList LinuxDumper::doListTables() 00197 { 00198 QStringList tables; 00199 for ( Impl::TableHandlers::const_iterator handler = impl_->tableHandler.begin(); 00200 handler != impl_->tableHandler.end(); ++handler ) 00201 { 00202 tables.push_back( handler->first ); 00203 } 00204 00205 return tables; 00206 } 00207 00208 Result LinuxDumper::allSockets() 00209 { 00210 Result result; 00211 std::vector< shared_ptr< Socket > > rows( Socket::allSystemInstances( shared_from_this(), "tcp" ) ); 00212 copy( rows.begin(), rows.end(), back_inserter( result ) ); 00213 return result; 00214 } 00215 00216 Result LinuxDumper::allNetworkInterfaces() const 00217 { 00218 Result result; 00219 shared_ptr<Linux::NetworkInterface> proc( new Linux::NetworkInterface( "eth0" ) ); 00220 result.push_back( proc ); 00221 return result; 00222 } 00223 Result LinuxDumper::allConfigurationFiles() 00224 { 00225 return systemContext().allConfigurationFiles(); 00226 } 00227 00228 Result LinuxDumper::allMountEntries( const boost::filesystem::path &fstab_path ) 00229 { 00230 Result result; 00231 std::vector< shared_ptr< MountEntry > > rows( MountEntry::allMountEntriesFrom( shared_from_this(), fstab_path ) ); 00232 copy( rows.begin(), rows.end(), back_inserter( result ) ); 00233 return result; 00234 } 00235 00236 Result LinuxDumper::allInittabEntries() 00237 { 00238 Result result; 00239 std::vector< shared_ptr< InittabEntry > > rows( InittabEntry::allInittabEntries( shared_from_this() ) ); 00240 copy( rows.begin(), rows.end(), back_inserter( result ) ); 00241 return result; 00242 } 00243 00244 Result LinuxDumper::doQueryTable( QString table ) 00245 { 00246 Impl::TableHandlers::const_iterator handler = impl_->tableHandler.find( table ); 00247 if ( handler == impl_->tableHandler.end() ) 00248 throw NoSuchTable( QString( "No such table: %1" ).arg( table ), table ); 00249 00250 return handler->second( shared_from_this() ); 00251 } 00252 00253 } 00254 } 00255