00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013
00014 #define ZYPP_BASE_LOGGER_LOGGROUP "HAL"
00015 #include "zypp/base/Logger.h"
00016
00017 #include "zypp/target/hal/Hal.h"
00018
00019 #ifndef FAKE_HAL
00020
00021 #include <glib.h>
00022
00023 #include <dbus/dbus-glib-lowlevel.h>
00024 #include <dbus/dbus-glib.h>
00025 #include <hal/libhal.h>
00026
00027 #endif
00028
00029 using std::endl;
00030 using std::string;
00031
00033 namespace zypp
00034 {
00035
00036 namespace target
00037 {
00038
00039 namespace hal
00040 {
00041
00042 #ifndef FAKE_HAL
00043
00044
00045
00046
00048 struct Hal::Impl
00049 {
00053 DBusConnection *_connection;
00054
00058 LibHalContext *_context;
00059
00063 void
00064 report_error (const std::string & reason, DBusError & error) const
00065 {
00066 ERR << reason << ": " << string (error.name) << ": " << string(error.message);
00067 dbus_error_init(&error);
00068 return;
00069 }
00070
00072 Impl()
00073 {
00074 DBusError error;
00075 dbus_error_init (&error);
00076
00077 _connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
00078 if (_connection) {
00079 _context = libhal_ctx_new ();
00080 if (_context) {
00081 if (libhal_ctx_set_dbus_connection (_context, _connection)) {
00082 if (libhal_ctx_init (_context, &error)) {
00083 return;
00084 } else {
00085 report_error ("libhal_ctx_init", error);
00086 }
00087 } else {
00088 report_error ("libhal_ctx_set_dbus_connection", error);
00089 }
00090 libhal_ctx_free (_context);
00091 _context = NULL;
00092 } else {
00093 report_error ("libhal_ctx_new: Can't create libhal context", error);
00094 }
00095 dbus_connection_disconnect (_connection);
00096 dbus_connection_unref (_connection);
00097 _connection = NULL;
00098 } else {
00099 report_error ("dbus_bus_get", error);
00100 }
00101 }
00102
00103
00105 ~Impl()
00106 {
00107 if (_context) {
00108 libhal_ctx_free (_context);
00109 }
00110 if (_connection) {
00111 dbus_connection_disconnect (_connection);
00112 dbus_connection_unref (_connection);
00113 }
00114 }
00115
00120 bool query( const std::string & cap_r ) const
00121 { return query( cap_r, Rel::ANY, std::string() ); }
00122
00126 bool query( const std::string & cap_r,
00127 Rel op_r,
00128 const std::string & val_r ) const
00129 {
00130 DBusError error;
00131 dbus_error_init (&error);
00132
00133
00134
00135 bool result = false;
00136
00137 int device_count;
00138 char **device_names = libhal_find_device_by_capability (_context, cap_r.c_str(), &device_count, &error);
00139
00140 if (device_names == NULL) {
00141 report_error ("libhal_find_device_by_capability", error);
00142 result = false;
00143 }
00144 else if (device_count > 0) {
00145
00146 #if 0 // once we get a capabilities value from HAL, we can compare it ...
00147 if (value) {
00148 string lhs (value);
00149 int cmp = (lhs != rhs) ? ((lhs < rhs) ? -1 : 1) : 0;
00150
00151 switch ( relation.inSwitch() )
00152 {
00153 case Rel::EQ_e:
00154 res = (cmp == 0);
00155 break;
00156 case Rel::NE_e:
00157 res = (cmp != 0);
00158 break;
00159 case Rel::LT_e:
00160 res = (cmp == -1);
00161 break;
00162 case Rel::LE_e:
00163 res = (cmp != 1);
00164 break;
00165 case Rel::GT_e:
00166 res = (cmp == 1);
00167 break;
00168 case Rel::GE_e:
00169 res = (cmp != -1);
00170 break;
00171 case Rel::ANY_e:
00172 res = true;
00173 break;
00174 case Rel::NONE_e:
00175 res = false;
00176 break;
00177 default:
00178
00179 INT << "Unknown relational opertor '" << relation << "' treated as 'NONE'" << endl;
00180 break;
00181 }
00182 }
00183 #endif
00184
00185 result = true;
00186
00187 }
00188
00189 if (device_names != NULL)
00190 libhal_free_string_array (device_names);
00191
00192 return result;
00193 }
00194
00195 public:
00197 static shared_ptr<Impl> nullimpl()
00198 {
00199 static shared_ptr<Impl> _nullimpl( new Impl );
00200 return _nullimpl;
00201 }
00202
00203 };
00204
00205
00206 #else // FAKE_HAL
00207 struct Hal::Impl
00208 {
00209 bool query( const std::string & cap_r ) const
00210 { return query( cap_r, Rel::ANY, std::string() ); }
00211 bool query( const std::string & cap_r,
00212 Rel op_r,
00213 const std::string & val_r ) const
00214 { return false; }
00216 static shared_ptr<Impl> nullimpl()
00217 {
00218 static shared_ptr<Impl> _nullimpl( new Impl );
00219 return _nullimpl;
00220 }
00221 };
00222 #endif
00223
00225
00230 inline std::ostream & operator<<( std::ostream & str, const Hal::Impl & obj )
00231 {
00232 return str << "Hal::Impl";
00233 }
00234
00236
00237
00238
00240
00242
00243
00244
00245
00246 Hal::Hal()
00247 : _pimpl( Impl::nullimpl() )
00248 {}
00249
00251
00252
00253
00254
00255 Hal::~Hal()
00256 {}
00257
00259
00260
00261
00262
00263 Hal & Hal::instance()
00264 {
00265 static Hal _singleton;
00266 return _singleton;
00267 }
00268
00270
00272
00273 bool Hal::query( const std::string & cap_r ) const
00274 { return _pimpl->query( cap_r ); }
00275
00276 bool Hal::query( const std::string & cap_r,
00277 Rel op_r,
00278 const std::string & val_r ) const
00279 { return _pimpl->query( cap_r, op_r, val_r ); }
00280
00281
00282
00283
00284
00285
00286 std::ostream & operator<<( std::ostream & str, const Hal & obj )
00287 {
00288 return str << *obj._pimpl;
00289 }
00290
00292 }
00295 }
00298 }