libzypp  17.23.8
Modalias.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 extern "C"
13 {
14 #include <fnmatch.h>
15 }
16 
17 #include <iostream>
18 #include <fstream>
19 #include <vector>
20 
21 #undef ZYPP_BASE_LOGGER_LOGGROUP
22 #define ZYPP_BASE_LOGGER_LOGGROUP "MODALIAS"
23 
24 #include <zypp/base/LogTools.h>
25 #include <zypp/base/IOStream.h>
26 #include <zypp/base/InputStream.h>
27 #include <zypp/AutoDispose.h>
28 #include <zypp/PathInfo.h>
29 
31 
32 using std::endl;
33 
35 namespace zypp
36 {
38  namespace target
39  {
41  namespace
42  {
44  inline bool isBlackListed( const Pathname & dir_r, const char * file_r )
45  {
46 #define PATH_IS( D, F ) ( ::strcmp( file_r, F ) == 0 && ::strcmp( dir_r.c_str(), D ) == 0 )
47  switch ( file_r[0] )
48  {
49  case 'm':
50  return PATH_IS( "/sys/devices/system", "memory" ); // bnc#824110: huge tree for systems with large RAM
51  break;
52  }
53  return false;
54 #undef PATH_IS
55  }
56 
57  void foreach_file_recursive( const Pathname & dir_r, std::set<std::string> & arg_r )
58  {
59  AutoDispose<DIR *> dir( ::opendir( dir_r.c_str() ), ::closedir );
60  if ( ! dir )
61  return;
62 
63  struct dirent * dirent = NULL;
64  while ( (dirent = ::readdir(dir)) != NULL )
65  {
66  if ( dirent->d_name[0] == '.' )
67  continue;
68 
69  if ( isBlackListed( dir_r, dirent->d_name ) )
70  continue;
71 
72  Pathname path; // lazy init as needed
73  unsigned char d_type = dirent->d_type;
74  if ( d_type == DT_UNKNOWN )
75  {
76  path = dir_r/dirent->d_name;
77  PathInfo pi( path, PathInfo::LSTAT );
78  if ( pi.isDir() )
79  d_type = DT_DIR;
80  else if ( pi.isFile() )
81  d_type = DT_REG;
82  }
83 
84  if ( d_type == DT_DIR )
85  {
86  if ( path.empty() )
87  path = dir_r/dirent->d_name;
88  foreach_file_recursive( path, arg_r );
89  }
90  else if ( d_type == DT_REG && ::strcmp( dirent->d_name, "modalias" ) == 0 )
91  {
92  if ( path.empty() )
93  path = dir_r/dirent->d_name;
94  // read modalias line from file
95  std::ifstream str( path.c_str() );
96  std::string line( iostr::getline( str ) );
97  if ( ! line.empty() )
98  arg_r.insert( line );
99  }
100  }
101  }
102 
104  void foreach_file_recursive( const Pathname & dir_r, Modalias::ModaliasList & arg_r )
105  {
106  std::set<std::string> arg; // we want the aliases to be unified (the public API uses a vector)
107  foreach_file_recursive( dir_r, arg );
108  arg_r.insert( arg_r.end(), arg.begin(), arg.end() );
109  }
110  } // namespace
112 
114  //
115  // CLASS NAME : Modalias::Impl
116  //
119  {
122  {
123  const char * dir = getenv("ZYPP_MODALIAS_SYSFS");
124  if ( dir )
125  {
126  PathInfo pi( dir );
127  if ( pi.isFile() )
128  {
129  // Debug/testcases:
130  // find /sys/ -type f -name modalias -print0 | xargs -0 cat >/tmp/modaliases
131  // ZYPP_MODALIAS_SYSFS=/tmp/modaliases
132  DBG << "Using $ZYPP_MODALIAS_SYSFS modalias file: " << dir << endl;
134  [&]( int num_r, std::string line_r )->bool
135  {
136  this->_modaliases.push_back( line_r );
137  return true;
138  } );
139  return;
140  }
141  DBG << "Using $ZYPP_MODALIAS_SYSFS: " << dir << endl;
142  }
143  else
144  {
145  dir = "/sys";
146  DBG << "Using /sys directory." << endl;
147  }
148 
149  foreach_file_recursive( dir, _modaliases );
150  }
151 
154  {}
155 
156  /*
157  * Check if a device on the system matches a modalias PATTERN.
158  *
159  * Returns NULL if no matching device is found, and the modalias
160  * of the first matching device otherwise. (More than one device
161  * may match a given pattern.)
162  *
163  * On a system that has the following device,
164  *
165  * pci:v00008086d0000265Asv00008086sd00004556bc0Csc03i00
166  *
167  * modalias_matches("pci:v00008086d0000265Asv*sd*bc*sc*i*") will
168  * return a non-NULL value.
169  */
170  bool query( const char * cap_r ) const
171  {
172  if ( cap_r && *cap_r )
173  {
174  for_( it, _modaliases.begin(), _modaliases.end() )
175  {
176  if ( fnmatch( cap_r, (*it).c_str(), 0 ) == 0 )
177  return true;
178  }
179  }
180  return false;
181  }
182 
183  public:
185 
186  public:
188  static shared_ptr<Impl> nullimpl()
189  {
190  static shared_ptr<Impl> _nullimpl( new Impl );
191  return _nullimpl;
192  }
193 
194  };
196 
201  inline std::ostream & operator<<( std::ostream & str, const Modalias::Impl & obj )
202  {
203  return dumpRange( str << "Modaliases: (" << obj._modaliases.size() << ") ", obj._modaliases.begin(), obj._modaliases.end() );
204  }
205 
207  //
208  // CLASS NAME : Modalias
209  //
211 
213  : _pimpl( Impl::nullimpl() )
214  {}
215 
217  {}
218 
220  {
221  static Modalias _singleton;
222  return _singleton;
223  }
224 
225  bool Modalias::query( const char * cap_r ) const
226  { return _pimpl->query( cap_r ); }
227 
229  { return _pimpl->_modaliases; }
230 
232  { _pimpl->_modaliases.swap( newlist_r ); }
233 
234  std::ostream & operator<<( std::ostream & str, const Modalias & obj )
235  { return str << *obj._pimpl; }
236 
237  } // namespace target
239 } // namespace zypp
241 
zypp::filesystem::readdir
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition: PathInfo.cc:584
zypp::target::Modalias::Impl::Impl
Impl()
Ctor.
Definition: Modalias.cc:121
zypp::filesystem::PathInfo::path
const Pathname & path() const
Return current Pathname.
Definition: PathInfo.h:246
PathInfo.h
Modalias.h
zypp::target::Modalias::Impl::query
bool query(const char *cap_r) const
Definition: Modalias.cc:170
zypp::dumpRange
std::ostream & dumpRange(std::ostream &str, TIterator begin, TIterator end, const std::string &intro="{", const std::string &pfx="\n ", const std::string &sep="\n ", const std::string &sfx="\n", const std::string &extro="}")
Print range defined by iterators (multiline style).
Definition: LogTools.h:91
PATH_IS
#define PATH_IS(D, F)
zypp::target::Modalias::Impl
Modalias implementation.
Definition: Modalias.cc:118
zypp::filesystem::PathInfo::LSTAT
Definition: PathInfo.h:226
IOStream.h
zypp::iostr::getline
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:32
zypp::target::Modalias::Modalias
Modalias()
Singleton ctor.
Definition: Modalias.cc:212
LogTools.h
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
zypp::target::operator<<
std::ostream & operator<<(std::ostream &str, const CommitPackageCache &obj)
Definition: CommitPackageCache.cc:155
zypp::iostr::forEachLine
int forEachLine(std::istream &str_r, function< bool(int, std::string)> consume_r)
Simple lineparser: Call functor consume_r for each line.
Definition: IOStream.cc:99
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition: PathInfo.h:289
zypp::InputStream
Helper to create and pass std::istream.
Definition: InputStream.h:56
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
AutoDispose.h
zypp::target::Modalias::query
bool query(IdString cap_r) const
Checks if a device on the system matches a modalias pattern.
Definition: Modalias.h:69
zypp::target::Modalias::_pimpl
RW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: Modalias.h:88
zypp::target::Modalias::Impl::operator<<
std::ostream & operator<<(std::ostream &str, const Modalias::Impl &obj)
Definition: Modalias.cc:201
for_
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
zypp::target::Modalias::ModaliasList
std::vector< std::string > ModaliasList
Definition: Modalias.h:41
DBG
#define DBG
Definition: Logger.h:78
zypp::target::Modalias::Impl::nullimpl
static shared_ptr< Impl > nullimpl()
Offer default Impl.
Definition: Modalias.cc:188
InputStream.h
str
String related utilities and Regular expression matching.
zypp::target::Modalias::Impl::~Impl
~Impl()
Dtor.
Definition: Modalias.cc:153
zypp::target::Modalias
Hardware abstaction layer singleton.
Definition: Modalias.h:35
zypp::target::Modalias::~Modalias
~Modalias()
Dtor.
Definition: Modalias.cc:216
zypp::target::Modalias::Impl::_modaliases
ModaliasList _modaliases
Definition: Modalias.cc:184
zypp::target::Modalias::modaliasList
const ModaliasList & modaliasList() const
List of modaliases found on system.
Definition: Modalias.cc:228
zypp::target::Modalias::instance
static Modalias & instance()
Singleton access.
Definition: Modalias.cc:219