Modalias.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
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" );  // bnc#824110: huge tree for systems with large RAM
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             // read modalias line from file
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     } // namespace
00090 
00092     //
00093     //  CLASS NAME : Modalias::Impl
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        * Check if a device on the system matches a modalias PATTERN.
00115        *
00116        * Returns NULL if no matching device is found, and the modalias
00117        * of the first matching device otherwise. (More than one device
00118        * may match a given pattern.)
00119        *
00120        * On a system that has the following device,
00121        *
00122        *   pci:v00008086d0000265Asv00008086sd00004556bc0Csc03i00
00123        *
00124        * modalias_matches("pci:v00008086d0000265Asv*sd*bc*sc*i*") will
00125        * return a non-NULL value.
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     //  CLASS NAME : Modalias
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   } // namespace target
00193 } // namespace zypp
00195 

Generated on Tue May 5 14:43:20 2015 for libzypp by  doxygen 1.5.6