Hal.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
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 //      CLASS NAME : Hal::Impl
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);                   // get DBUS 'socket'
00078         if (_connection) {
00079             _context = libhal_ctx_new ();                                       // create empty HAL context
00080             if (_context) {
00081                 if (libhal_ctx_set_dbus_connection (_context, _connection)) {   // connect to HAL daemon via DBUS
00082                     if (libhal_ctx_init (_context, &error)) {                   // fill HAL context
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);                                     // clean up
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         // ask HAL which devices provide the needed capability
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                         // We shouldn't get here.
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 };  // struct Hal::Impl
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 //      CLASS NAME : Hal
00238 //
00240 
00242 //
00243 //      METHOD NAME : Hal::Hal
00244 //      METHOD TYPE : Ctor
00245 //
00246 Hal::Hal()
00247 : _pimpl( Impl::nullimpl() )
00248 {}
00249 
00251 //
00252 //      METHOD NAME : Hal::~Hal
00253 //      METHOD TYPE : Dtor
00254 //
00255 Hal::~Hal()
00256 {}
00257 
00259 //
00260 //      METHOD NAME : Hal::instance
00261 //      METHOD TYPE : Hal &
00262 //
00263 Hal & Hal::instance()
00264 {
00265   static Hal _singleton;
00266   return _singleton;
00267 }
00268 
00270 // Foreward to implenemtation
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 **      FUNCTION NAME : operator<<
00284 **      FUNCTION TYPE : std::ostream &
00285 */
00286 std::ostream & operator<<( std::ostream & str, const Hal & obj )
00287 {
00288   return str << *obj._pimpl;
00289 }
00290 
00292     } // namespace hal
00295   } // namespace target
00298 } // namespace zypp

Generated on Thu Jul 6 00:07:26 2006 for zypp by  doxygen 1.4.6