libzypp  17.3.1
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 
58  void foreach_file_recursive( const Pathname & dir_r, Modalias::ModaliasList & arg )
59  {
60  AutoDispose<DIR *> dir( ::opendir( dir_r.c_str() ), ::closedir );
61  if ( ! dir )
62  return;
63 
64  struct dirent * dirent = NULL;
65  while ( (dirent = ::readdir(dir)) != NULL )
66  {
67  if ( dirent->d_name[0] == '.' )
68  continue;
69 
70  if ( isBlackListed( dir_r, dirent->d_name ) )
71  continue;
72 
73  PathInfo pi( dir_r / dirent->d_name, PathInfo::LSTAT );
74 
75  if ( pi.isDir() )
76  {
77  foreach_file_recursive( pi.path(), arg );
78  }
79  else if ( pi.isFile() && ::strcmp( dirent->d_name, "modalias" ) == 0 )
80  {
81  // read modalias line from file
82  std::ifstream str( pi.path().c_str() );
83  std::string line( iostr::getline( str ) );
84  if ( ! line.empty() )
85  arg.push_back( line );
86  }
87  }
88  }
89  } // namespace
91 
93  //
94  // CLASS NAME : Modalias::Impl
95  //
98  {
101  {
102  const char * dir = getenv("ZYPP_MODALIAS_SYSFS");
103  if ( dir )
104  {
105  PathInfo pi( dir );
106  if ( pi.isFile() )
107  {
108  // Debug/testcases:
109  // find /sys/ -type f -name modalias -print0 | xargs -0 cat >/tmp/modaliases
110  // ZYPP_MODALIAS_SYSFS=/tmp/modaliases
111  DBG << "Using $ZYPP_MODALIAS_SYSFS modalias file: " << dir << endl;
113  [&]( int num_r, std::string line_r )->bool
114  {
115  this->_modaliases.push_back( line_r );
116  return true;
117  } );
118  return;
119  }
120  DBG << "Using $ZYPP_MODALIAS_SYSFS: " << dir << endl;
121  }
122  else
123  {
124  dir = "/sys";
125  DBG << "Using /sys directory." << endl;
126  }
127 
128  foreach_file_recursive( dir, _modaliases );
129  }
130 
133  {}
134 
135  /*
136  * Check if a device on the system matches a modalias PATTERN.
137  *
138  * Returns NULL if no matching device is found, and the modalias
139  * of the first matching device otherwise. (More than one device
140  * may match a given pattern.)
141  *
142  * On a system that has the following device,
143  *
144  * pci:v00008086d0000265Asv00008086sd00004556bc0Csc03i00
145  *
146  * modalias_matches("pci:v00008086d0000265Asv*sd*bc*sc*i*") will
147  * return a non-NULL value.
148  */
149  bool query( const char * cap_r ) const
150  {
151  if ( cap_r && *cap_r )
152  {
153  for_( it, _modaliases.begin(), _modaliases.end() )
154  {
155  if ( fnmatch( cap_r, (*it).c_str(), 0 ) == 0 )
156  return true;
157  }
158  }
159  return false;
160  }
161 
162  public:
164 
165  public:
167  static shared_ptr<Impl> nullimpl()
168  {
169  static shared_ptr<Impl> _nullimpl( new Impl );
170  return _nullimpl;
171  }
172 
173  };
175 
180  inline std::ostream & operator<<( std::ostream & str, const Modalias::Impl & obj )
181  {
182  return dumpRange( str << "Modaliases: (" << obj._modaliases.size() << ") ", obj._modaliases.begin(), obj._modaliases.end() );
183  }
184 
186  //
187  // CLASS NAME : Modalias
188  //
190 
192  : _pimpl( Impl::nullimpl() )
193  {}
194 
196  {}
197 
199  {
200  static Modalias _singleton;
201  return _singleton;
202  }
203 
204  bool Modalias::query( const char * cap_r ) const
205  { return _pimpl->query( cap_r ); }
206 
208  { return _pimpl->_modaliases; }
209 
211  { _pimpl->_modaliases.swap( newlist_r ); }
212 
213  std::ostream & operator<<( std::ostream & str, const Modalias & obj )
214  { return str << *obj._pimpl; }
215 
216  } // namespace target
218 } // namespace zypp
220 
const ModaliasList & modaliasList() const
List of modaliases found on system.
Definition: Modalias.cc:207
const Pathname & path() const
Return current Pathname.
Definition: PathInfo.h:246
Modalias()
Singleton ctor.
Definition: Modalias.cc:191
RW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: Modalias.h:88
bool query(const char *cap_r) const
Definition: Modalias.cc:149
std::ostream & dumpRange(std::ostream &str, TIterator begin, TIterator end, const std::string &intro="{", const std::string &pfx="\ ", const std::string &sep="\ ", const std::string &sfx="\, const std::string &extro="}")
Print range defined by iterators (multiline style).
Definition: LogTools.h:91
String related utilities and Regular expression matching.
Helper to create and pass std::istream.
Definition: InputStream.h:56
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:33
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:100
bool query(IdString cap_r) const
Checks if a device on the system matches a modalias pattern.
Definition: Modalias.h:69
std::vector< std::string > ModaliasList
Definition: Modalias.h:41
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition: PathInfo.cc:589
static Modalias & instance()
Singleton access.
Definition: Modalias.cc:198
static shared_ptr< Impl > nullimpl()
Offer default Impl.
Definition: Modalias.cc:167
std::ostream & operator<<(std::ostream &str, const Modalias::Impl &obj)
Definition: Modalias.cc:180
friend std::ostream & operator<<(std::ostream &str, const Modalias &obj)
Definition: Modalias.cc:213
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
Modalias implementation.
Definition: Modalias.cc:97
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
Hardware abstaction layer singleton.
Definition: Modalias.h:35
#define DBG
Definition: Logger.h:63
#define PATH_IS(D, F)