Confdump Agent  1.4.0
LinuxDumper.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends