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