Modalias.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 extern "C"
00013 {
00014 #include <fnmatch.h>
00015 }
00016
00017 #include <iostream>
00018 #include <fstream>
00019 #include <vector>
00020
00021 #undef ZYPP_BASE_LOGGER_LOGGROUP
00022 #define ZYPP_BASE_LOGGER_LOGGROUP "MODALIAS"
00023
00024 #include "zypp/base/LogTools.h"
00025 #include "zypp/base/IOStream.h"
00026 #include "zypp/AutoDispose.h"
00027 #include "zypp/PathInfo.h"
00028
00029 #include "zypp/target/modalias/Modalias.h"
00030
00031 using std::endl;
00032
00034 namespace zypp
00035 {
00037 namespace target
00038 {
00040 namespace
00041 {
00043 inline bool isBlackListed( const Pathname & dir_r, const char * file_r )
00044 {
00045 #define PATH_IS( D, F ) ( ::strcmp( file_r, F ) == 0 && ::strcmp( dir_r.c_str(), D ) == 0 )
00046 switch ( file_r[0] )
00047 {
00048 case 'm':
00049 return PATH_IS( "/sys/devices/system", "memory" );
00050 break;
00051 }
00052 return false;
00053 #undef PATH_IS
00054 }
00055
00057 void foreach_file_recursive( const Pathname & dir_r, Modalias::ModaliasList & arg )
00058 {
00059 AutoDispose<DIR *> dir( ::opendir( dir_r.c_str() ), ::closedir );
00060 if ( ! dir )
00061 return;
00062
00063 struct dirent * dirent = NULL;
00064 while ( (dirent = ::readdir(dir)) != NULL )
00065 {
00066 if ( dirent->d_name[0] == '.' )
00067 continue;
00068
00069 if ( isBlackListed( dir_r, dirent->d_name ) )
00070 continue;
00071
00072 PathInfo pi( dir_r / dirent->d_name, PathInfo::LSTAT );
00073
00074 if ( pi.isDir() )
00075 {
00076 foreach_file_recursive( pi.path(), arg );
00077 }
00078 else if ( pi.isFile() && ::strcmp( dirent->d_name, "modalias" ) == 0 )
00079 {
00080
00081 std::ifstream str( pi.path().c_str() );
00082 std::string line( iostr::getline( str ) );
00083 if ( ! line.empty() )
00084 arg.push_back( line );
00085 }
00086 }
00087 }
00088 }
00090
00092
00093
00094
00096 struct Modalias::Impl
00097 {
00099 Impl()
00100 {
00101 const char * dir = getenv("ZYPP_MODALIAS_SYSFS");
00102 if ( !dir )
00103 dir = "/sys";
00104 DBG << "Using /sys directory : " << dir << endl;
00105
00106 foreach_file_recursive( dir, _modaliases );
00107 }
00108
00110 ~Impl()
00111 {}
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 bool query( const char * cap_r ) const
00128 {
00129 if ( cap_r && *cap_r )
00130 {
00131 for_( it, _modaliases.begin(), _modaliases.end() )
00132 {
00133 if ( fnmatch( cap_r, (*it).c_str(), 0 ) == 0 )
00134 return true;
00135 }
00136 }
00137 return false;
00138 }
00139
00140 public:
00141 ModaliasList _modaliases;
00142
00143 public:
00145 static shared_ptr<Impl> nullimpl()
00146 {
00147 static shared_ptr<Impl> _nullimpl( new Impl );
00148 return _nullimpl;
00149 }
00150
00151 };
00153
00158 inline std::ostream & operator<<( std::ostream & str, const Modalias::Impl & obj )
00159 {
00160 return dumpRange( str << "Modaliases: (" << obj._modaliases.size() << ") ", obj._modaliases.begin(), obj._modaliases.end() );
00161 }
00162
00164
00165
00166
00168
00169 Modalias::Modalias()
00170 : _pimpl( Impl::nullimpl() )
00171 {}
00172
00173 Modalias::~Modalias()
00174 {}
00175
00176 Modalias & Modalias::instance()
00177 {
00178 static Modalias _singleton;
00179 return _singleton;
00180 }
00181
00182 bool Modalias::query( const char * cap_r ) const
00183 { return _pimpl->query( cap_r ); }
00184
00185 const Modalias::ModaliasList & Modalias::modaliasList() const
00186 { return _pimpl->_modaliases; }
00187
00188 std::ostream & operator<<( std::ostream & str, const Modalias & obj )
00189 { return str << *obj._pimpl; }
00190
00191 }
00193 }
00195