Modalias.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 extern "C"
00013 {
00014 #include <sys/types.h>
00015 #include <sys/stat.h>
00016 #include <fcntl.h>
00017 #include <unistd.h>
00018 #include <dirent.h>
00019 #include <fnmatch.h>
00020 }
00021 #include <cstdlib>
00022 #include <cstdio>
00023 #include <cstring>
00024 #include <cerrno>
00025
00026 #include <iostream>
00027
00028 #undef ZYPP_BASE_LOGGER_LOGGROUP
00029 #define ZYPP_BASE_LOGGER_LOGGROUP "MODALIAS"
00030 #include "zypp/base/Logger.h"
00031
00032 #include "zypp/target/modalias/Modalias.h"
00033 #include "zypp/PathInfo.h"
00034
00035
00036 using std::endl;
00037 using std::string;
00038
00039
00041 namespace zypp
00042 {
00043
00044 namespace target
00045 {
00046
00047 struct modalias_list {
00048 char *modalias;
00049 struct modalias_list *next;
00050 };
00051
00053 namespace
00054 {
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 int
00065 foreach_file_recursive(const char *path_rec, int (*func)(const char *, const char *, void *),
00066 void *arg)
00067 {
00068 DIR *dir;
00069 struct dirent *dirent;
00070 char path_tmp[PATH_MAX];
00071 int ret = 0;
00072
00073 if (!(dir = opendir(path_rec)))
00074 return -1;
00075 while ((dirent = readdir(dir)) != NULL) {
00076
00077 if (strcmp(dirent->d_name, ".") == 0 ||
00078 strcmp(dirent->d_name, "..") == 0)
00079 continue;
00080 snprintf(path_tmp, sizeof(path_tmp), "%s/%s", path_rec, dirent->d_name);
00081
00082 PathInfo path(path_tmp, PathInfo::LSTAT);
00083
00084 if (path.isLink ()) {
00085 continue;
00086 }
00087 if (path.isDir ()){
00088 (void) foreach_file_recursive(path_tmp, func, arg);
00089 }else if (path.isFile ()){
00090 if ((ret = func(path_rec, dirent->d_name, arg)) != 0)
00091 break;
00092 }else{
00093 continue;
00094 }
00095 }
00096 if (closedir(dir) != 0)
00097 return -1;
00098 return ret;
00099 }
00100
00101
00102
00103
00104
00105 int
00106 read_modalias(const char *dir, const char *file, void *arg)
00107 {
00108 char path[PATH_MAX];
00109 int fd;
00110 ssize_t len;
00111 char modalias[PATH_MAX];
00112 struct modalias_list **list = (struct modalias_list **)arg, *entry;
00113
00114 if (strcmp(file, "modalias") != 0){
00115 return 0;
00116 }
00117 snprintf(path, sizeof(path), "%s/%s", dir, file);
00118 if ((fd = open(path, O_RDONLY)) == -1)
00119 return 0;
00120 len = read(fd, modalias, sizeof(modalias) - 1);
00121 if (len < 0)
00122 goto out;
00123 while (len > 0 && modalias[len - 1] == '\n')
00124 len--;
00125 modalias[len] = 0;
00126
00127 if ((entry = (struct modalias_list *)malloc(sizeof(*entry))) == NULL)
00128 goto out;
00129 if ((entry->modalias = strdup(modalias)) == NULL) {
00130 free(entry);
00131 goto out;
00132 }
00133 entry->next = *list;
00134 *list = entry;
00135 XXX << "system modalias: " << entry->modalias << endl;
00136
00137 out:
00138 (void) close(fd);
00139 return 0;
00140 }
00141
00143 }
00145
00147
00148
00149
00151 struct Modalias::Impl
00152 {
00153 struct modalias_list *_modaliases;
00154
00156 Impl()
00157 : _modaliases(0)
00158 {
00159 const char *dir;
00160 char path[PATH_MAX];
00161
00162 dir = getenv("ZYPP_MODALIAS_SYSFS");
00163 if (!dir)
00164 dir = "/sys";
00165 DBG << "Using /sys directory : " << dir << endl;
00166
00167 snprintf(path, sizeof(path), "%s", dir);
00168 foreach_file_recursive( path, read_modalias, &_modaliases );
00169
00170 }
00171
00173 ~Impl()
00174 {
00175 while (_modaliases != NULL) {
00176 struct modalias_list *l = _modaliases;
00177 _modaliases = _modaliases->next;
00178 free(l->modalias);
00179 free(l);
00180 }
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 bool query( const char * cap_r ) const
00198 {
00199 if ( cap_r )
00200 {
00201 struct modalias_list *l;
00202 for (l = _modaliases; l; l = l->next) {
00203 if ( fnmatch( cap_r, l->modalias, 0 ) == 0 )
00204 return true;
00205 }
00206 }
00207 return false;
00208 }
00209
00210 public:
00212 static shared_ptr<Impl> nullimpl()
00213 {
00214 static shared_ptr<Impl> _nullimpl( new Impl );
00215 return _nullimpl;
00216 }
00217
00218 };
00219
00221
00226 inline std::ostream & operator<<( std::ostream & str, const Modalias::Impl & obj )
00227 {
00228 return str << "Modalias::Impl";
00229 }
00230
00232
00233
00234
00236
00238
00239
00240
00241
00242 Modalias::Modalias()
00243 : _pimpl( Impl::nullimpl() )
00244 {}
00245
00247
00248
00249
00250
00251 Modalias::~Modalias()
00252 {}
00253
00255
00256
00257
00258
00259 Modalias & Modalias::instance()
00260 {
00261 static Modalias _singleton;
00262 return _singleton;
00263 }
00264
00266
00268
00269 bool Modalias::query( const char * cap_r ) const
00270 { return _pimpl->query( cap_r ); }
00271
00272
00273
00274
00275
00276
00277 std::ostream & operator<<( std::ostream & str, const Modalias & obj )
00278 {
00279 return str << *obj._pimpl;
00280 }
00281
00283 }
00286 }
00288