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
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
00079 if (_connection) {
00080 _context = libhal_ctx_new ();
00081 if (_context) {
00082 if (libhal_ctx_set_dbus_connection (_context, _connection)) {
00083 if (libhal_ctx_init (_context, &error)) {
00084 return;
00085 } else {
00086 report_error ("libhal_ctx_init", error);
00087 }
00088 } else {
00089 report_error ("libhal_ctx_set_dbus_connection", error);
00090 }
00091 libhal_ctx_free (_context);
00092 _context = NULL;
00093 } else {
00094 report_error ("libhal_ctx_new: Can't create libhal context", error);
00095 }
00096
00097 dbus_connection_unref (_connection);
00098 _connection = NULL;
00099 } else {
00100 report_error ("dbus_bus_get", error);
00101 }
00102 }
00103
00104
00106 ~Impl()
00107 {
00108 if (_context) {
00109 libhal_ctx_free (_context);
00110 }
00111 if (_connection) {
00112
00113 dbus_connection_unref (_connection);
00114 }
00115 }
00116
00121 bool query( const std::string & cap_r ) const
00122 { return query( cap_r, Rel::ANY, std::string() ); }
00123
00127 bool query( const std::string & cap_r,
00128 Rel op_r,
00129 const std::string & val_r ) const
00130 {
00131 DBusError error;
00132 dbus_error_init (&error);
00133
00134
00135
00136 bool result = false;
00137
00138 int device_count;
00139 char **device_names = libhal_find_device_by_capability (_context, cap_r.c_str(), &device_count, &error);
00140
00141 if (device_names == NULL) {
00142 report_error ("libhal_find_device_by_capability", error);
00143 result = false;
00144 }
00145 else if (device_count > 0) {
00146
00147 #if 0 // once we get a capabilities value from HAL, we can compare it ...
00148 if (value) {
00149 string lhs (value);
00150 int cmp = (lhs != rhs) ? ((lhs < rhs) ? -1 : 1) : 0;
00151
00152 switch ( relation.inSwitch() )
00153 {
00154 case Rel::EQ_e:
00155 res = (cmp == 0);
00156 break;
00157 case Rel::NE_e:
00158 res = (cmp != 0);
00159 break;
00160 case Rel::LT_e:
00161 res = (cmp == -1);
00162 break;
00163 case Rel::LE_e:
00164 res = (cmp != 1);
00165 break;
00166 case Rel::GT_e:
00167 res = (cmp == 1);
00168 break;
00169 case Rel::GE_e:
00170 res = (cmp != -1);
00171 break;
00172 case Rel::ANY_e:
00173 res = true;
00174 break;
00175 case Rel::NONE_e:
00176 res = false;
00177 break;
00178 default:
00179
00180 INT << "Unknown relational opertor '" << relation << "' treated as 'NONE'" << endl;
00181 break;
00182 }
00183 }
00184 #endif
00185
00186 result = true;
00187
00188 }
00189
00190 if (device_names != NULL)
00191 libhal_free_string_array (device_names);
00192
00193 return result;
00194 }
00195
00196 public:
00198 static shared_ptr<Impl> nullimpl()
00199 {
00200 static shared_ptr<Impl> _nullimpl( new Impl );
00201 return _nullimpl;
00202 }
00203
00204 };
00205
00206
00207 #else // FAKE_HAL
00208 struct Hal::Impl
00209 {
00210 bool query( const std::string & cap_r ) const
00211 { return query( cap_r, Rel::ANY, std::string() ); }
00212 bool query( const std::string & cap_r,
00213 Rel op_r,
00214 const std::string & val_r ) const
00215 { return false; }
00217 static shared_ptr<Impl> nullimpl()
00218 {
00219 static shared_ptr<Impl> _nullimpl( new Impl );
00220 return _nullimpl;
00221 }
00222 };
00223 #endif
00224
00226
00231 inline std::ostream & operator<<( std::ostream & str, const Hal::Impl & obj )
00232 {
00233 return str << "Hal::Impl";
00234 }
00235
00237
00238
00239
00241
00243
00244
00245
00246
00247 Hal::Hal()
00248 : _pimpl( Impl::nullimpl() )
00249 {}
00250
00252
00253
00254
00255
00256 Hal::~Hal()
00257 {}
00258
00260
00261
00262
00263
00264 Hal & Hal::instance()
00265 {
00266 static Hal _singleton;
00267 return _singleton;
00268 }
00269
00271
00273
00274 bool Hal::query( const std::string & cap_r ) const
00275 { return _pimpl->query( cap_r ); }
00276
00277 bool Hal::query( const std::string & cap_r,
00278 Rel op_r,
00279 const std::string & val_r ) const
00280 { return _pimpl->query( cap_r, op_r, val_r ); }
00281
00282
00283
00284
00285
00286
00287 std::ostream & operator<<( std::ostream & str, const Hal & obj )
00288 {
00289 return str << *obj._pimpl;
00290 }
00291
00293 }
00296 }
00299 }