From 92f320b50180eb728a8f33f65ccc5c1b3264c745 Mon Sep 17 00:00:00 2001 From: Duncan Mac-Vicar P Date: Wed, 18 May 2011 12:01:41 +0000 Subject: [PATCH] Allow MediaCD to build against udev _and_ HAL, or even without both (limited functionality detecting devices then) --- CMakeLists.txt | 21 +- zypp/CMakeLists.txt | 24 +- zypp/media/MediaCD.cc | 86 ++- zypp/target/hal/HalContext.cc | 1255 ++++++++++++++++++++++++++++++++++++++++ zypp/target/hal/HalContext.h | 346 +++++++++++ zypp/target/hal/HalException.h | 116 ++++ 6 files changed, 1845 insertions(+), 3 deletions(-) create mode 100644 zypp/target/hal/HalContext.cc create mode 100644 zypp/target/hal/HalContext.h create mode 100644 zypp/target/hal/HalException.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f3e33cb..7d67706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,7 +128,26 @@ ENDIF( NOT SATSOLVER_FOUND ) FIND_PACKAGE(EXPAT REQUIRED) FIND_PACKAGE(OpenSSL REQUIRED) -FIND_PACKAGE(Udev REQUIRED) + +FIND_PACKAGE(Udev) +IF ( NOT UDEV_FOUND ) + FIND_PACKAGE(Hal) + IF ( NOT HAL_FOUND ) + MESSAGE(WARNING "No udev or HAL. CD device detection will be poor") + ELSE ( NOT HAL_FOUND ) + ADD_DEFINITIONS(-DHAVE_HAL) + INCLUDE_DIRECTORIES(${HAL_INCLUDE_DIR}) + INCLUDE_DIRECTORIES(${HAL_INCLUDE_DIR}/hal) + # HAL requires working dbus + FIND_PACKAGE(Dbus REQUIRED) + IF(DBUS_FOUND) + INCLUDE_DIRECTORIES(${DBUS_INCLUDE_DIR}) + INCLUDE_DIRECTORIES(${DBUS_ARCH_INCLUDE_DIR}) + ENDIF(DBUS_FOUND) + ENDIF ( NOT HAL_FOUND ) +ELSE ( NOT UDEV_FOUND ) + ADD_DEFINITIONS(-DHAVE_UDEV) +ENDIF ( NOT UDEV_FOUND ) FIND_PACKAGE(libproxy) IF ( NOT LIBPROXY_FOUND ) diff --git a/zypp/CMakeLists.txt b/zypp/CMakeLists.txt index d14f83a..ca0f768 100644 --- a/zypp/CMakeLists.txt +++ b/zypp/CMakeLists.txt @@ -601,6 +601,19 @@ INSTALL( FILES DESTINATION ${CMAKE_INSTALL_PREFIX}/include/zypp/target ) +IF(NOT UDEV_FOUND) +IF(HAL_FOUND) +SET( zypp_target_hal_SRCS + target/hal/HalContext.cc +) +SET( zypp_target_hal_HEADERS + target/hal/HalContext.h + target/hal/HalException.h +) +ENDIF(HAL_FOUND) +ENDIF(NOT UDEV_FOUND) +# as HAL is deprecated, we don't install headers + SET( zypp_target_modalias_SRCS target/modalias/Modalias.cc ) @@ -816,6 +829,7 @@ ${zypp_repo_yum_SRCS} ${zypp_repo_susetags_SRCS} ${zypp_repo_data_SRCS} ${zypp_target_rpm_SRCS} +${zypp_target_hal_SRCS} ${zypp_target_modalias_SRCS} ${zypp_target_SRCS} ${zypp_solver_detail_SRCS} @@ -918,7 +932,15 @@ TARGET_LINK_LIBRARIES(zypp ${SATSOLVER_LIBRARY} ${SATSOLVER_EXT_LIBRARY} ${EXPAT TARGET_LINK_LIBRARIES(zypp ${OPENSSL_LIBRARIES} ) TARGET_LINK_LIBRARIES(zypp ${CRYPTO_LIBRARIES} ) TARGET_LINK_LIBRARIES(zypp ${SIGNALS_LIBRARY} ) -TARGET_LINK_LIBRARIES(zypp ${UDEV_LIBRARY} ) + +IF ( UDEV_FOUND ) + TARGET_LINK_LIBRARIES(zypp ${UDEV_LIBRARY} ) +ELSE ( UDEV_FOUND ) + IF ( HAL_FOUND ) + TARGET_LINK_LIBRARIES(zypp ${HAL_LIBRARY} ${HAL_STORAGE_LIBRARY} ${DBUS_LIBRARY} ) + ENDIF ( HAL_FOUND ) +ENDIF ( UDEV_FOUND ) + TARGET_LINK_LIBRARIES(zypp ${LIBPROXY_LIBRARIES} ) INSTALL(TARGETS zypp LIBRARY DESTINATION ${LIB_INSTALL_DIR} ) diff --git a/zypp/media/MediaCD.cc b/zypp/media/MediaCD.cc index 8ec3feb..1a7b70b 100644 --- a/zypp/media/MediaCD.cc +++ b/zypp/media/MediaCD.cc @@ -13,9 +13,17 @@ extern "C" { #include #include +#if HAVE_UDEV #include +#endif } +#ifndef HAVE_UDEV +#if HAVE_HAL +#include "zypp/target/hal/HalContext.h" +#endif +#endif + #include // strerror #include // getenv #include @@ -202,6 +210,8 @@ namespace zypp { // MediaCD::DeviceList MediaCD::detectDevices( bool supportingDVD ) const { + DeviceList detected; +#ifdef HAVE_UDEV // http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/index.html zypp::AutoDispose udev( ::udev_new(), ::udev_unref ); if ( ! udev ) @@ -221,7 +231,6 @@ namespace zypp { ::udev_enumerate_add_match_property( enumerate, "ID_CDROM", "1" ); ::udev_enumerate_scan_devices( enumerate ); - DeviceList detected; struct udev_list_entry * entry = 0; udev_list_entry_foreach( entry, ::udev_enumerate_get_list_entry( enumerate ) ) { @@ -259,6 +268,81 @@ namespace zypp { } if ( detected.empty() ) WAR << "Did not find any CD/DVD device." << endl; +#elsif HAVE_HAL + using namespace zypp::target::hal; + try + { + HalContext hal(true); + + std::vector drv_udis; + drv_udis = hal.findDevicesByCapability("storage.cdrom"); + + DBG << "Found " << drv_udis.size() << " cdrom drive udis" << std::endl; + for(size_t d = 0; d < drv_udis.size(); d++) + { + HalDrive drv( hal.getDriveFromUDI( drv_udis[d])); + + if( drv) + { + bool supportsDVD=false; + if( supportingDVD) + { + std::vector caps; + try { + caps = drv.getCdromCapabilityNames(); + } + catch(const HalException &e) + { + ZYPP_CAUGHT(e); + } + + std::vector::const_iterator ci; + for( ci=caps.begin(); ci != caps.end(); ++ci) + { + if( *ci == "dvd") + supportsDVD = true; + } + } + + MediaSource media("cdrom", drv.getDeviceFile(), + drv.getDeviceMajor(), + drv.getDeviceMinor()); + DBG << "Found " << drv_udis[d] << ": " + << media.asString() << std::endl; + if( supportingDVD && supportsDVD) + { + detected.push_front(media); + } + else + { + detected.push_back(media); + } + } + } + } + catch(const zypp::target::hal::HalException &e) + { + ZYPP_CAUGHT(e); + } +#else // manual way +#warning Poor CDROM devices detection without udev/HAL + WAR << "Cdrom drive detection without HAL! " << std::endl; + PathInfo dvdinfo( "/dev/dvd" ); + PathInfo cdrinfo( "/dev/cdrom" ); + if ( dvdinfo.isBlk() ) + { + MediaSource media( "cdrom", dvdinfo.path().asString(), dvdinfo.major(), dvdinfo.minor() ); + DBG << "Found (NO_HAL): " << media << std::endl; + detected.push_back( media ); + } + if ( cdrinfo.isBlk() + && ! ( cdrinfo.major() == dvdinfo.major() && cdrinfo.minor() == dvdinfo.minor() ) ) + { + MediaSource media( "cdrom", cdrinfo.path().asString(), cdrinfo.major(), cdrinfo.minor() ); + DBG << "Found (NO_HAL): " << media << std::endl; + detected.push_back( media ); + } +#endif return detected; } diff --git a/zypp/target/hal/HalContext.cc b/zypp/target/hal/HalContext.cc new file mode 100644 index 0000000..c80367d --- /dev/null +++ b/zypp/target/hal/HalContext.cc @@ -0,0 +1,1255 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/target/hal/HalContext.cc + * + * \brief Hardware abstaction layer library wrapper implementation. + */ +#include +////////////////////////////////////////////////////////////////////// +namespace zypp +{ //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// + namespace target + { ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + namespace hal + { //////////////////////////////////////////////////////////////// + NoHalException::NoHalException() + : Exception(_("Sorry, but this version of libzypp was built without HAL support.")) + {} + //////////////////////////////////////////////////////////////// + } // namespace hal + ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + } // namespace target + //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// +} // namespace zypp +////////////////////////////////////////////////////////////////////// + +#ifndef NO_HAL // disables zypp's HAL dependency + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +using namespace std; + +////////////////////////////////////////////////////////////////////// +namespace zypp +{ //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// + namespace target + { ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + namespace hal + { //////////////////////////////////////////////////////////////// + + using zypp::thread::Mutex; + using zypp::thread::MutexLock; + + //////////////////////////////////////////////////////////////// + namespace // anonymous + { ////////////////////////////////////////////////////////////// + + + ////////////////////////////////////////////////////////////// + // STATIC + /** + ** hmm... currently a global one.. + */ + static Mutex g_Mutex; + + + ////////////////////////////////////////////////////////////// + /** + * Internal hal (dbus ) error helper class. + */ + class HalError + { + public: + DBusError error; + + HalError() { dbus_error_init(&error); } + ~HalError() { dbus_error_free(&error); } + + inline bool isSet() const + { + return dbus_error_is_set(&error); + } + + inline HalException halException(const std::string &msg = std::string()) const + { + if( isSet() && error.name != NULL && error.message != NULL) { + return HalException(error.name, error.message); + } + else if( !msg.empty()) { + return HalException(msg); + } + else { + return HalException(); + } + } + }; + + + // ----------------------------------------------------------- + inline void + VERIFY_CONTEXT(const zypp::RW_pointer &h) + { + if( !h) + { + ZYPP_THROW(HalException(_("HalContext not connected"))); + } + } + + // ----------------------------------------------------------- + inline void + VERIFY_DRIVE(const zypp::RW_pointer &d) + { + if( !d) + { + ZYPP_THROW(HalException(_("HalDrive not initialized"))); + } + } + + // ----------------------------------------------------------- + inline void + VERIFY_VOLUME(const zypp::RW_pointer &v) + { + if( !v) + { + ZYPP_THROW(HalException(_("HalVolume not initialized"))); + } + } + + ////////////////////////////////////////////////////////////// + } // anonymous + //////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////// + std::ostream & + HalException::dumpOn( std::ostream & str ) const + { + if(!e_name.empty() && !e_msg.empty()) + return str << msg() << ": " << e_msg << " (" << e_name << ")"; + else if(!e_msg.empty()) + return str << msg() << ": " << e_msg; + else + return str << msg(); + } + + //////////////////////////////////////////////////////////////// + class HalContext_Impl + { + public: + HalContext_Impl(); + ~HalContext_Impl(); + + DBusConnection *conn; + LibHalContext *hctx; + bool pcon; // private connection + }; + + + //////////////////////////////////////////////////////////////// + class HalDrive_Impl + { + public: + zypp::RW_pointer hal; + LibHalDrive *drv; + + HalDrive_Impl() + : hal(), drv(NULL) + { + } + + HalDrive_Impl(const zypp::RW_pointer &r, + LibHalDrive *d) + : hal(r), drv(d) + { + } + + ~HalDrive_Impl() + { + if( drv) + libhal_drive_free(drv); + } + }; + + + //////////////////////////////////////////////////////////////// + class HalVolume_Impl + { + public: + LibHalVolume *vol; + + HalVolume_Impl(LibHalVolume *v=NULL) + : vol(v) + { + } + + ~HalVolume_Impl() + { + if( vol) + libhal_volume_free(vol); + } + }; + + + //////////////////////////////////////////////////////////////// + HalContext_Impl::HalContext_Impl() + : conn(NULL) + , hctx(NULL) + , pcon(false) // we allways use shared connections at the moment + { + HalError err; + + if( pcon) + conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err.error); + else + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err.error); + if( !conn) { + ZYPP_THROW(err.halException( + _("Unable to create dbus connection") + )); + } + + hctx = libhal_ctx_new(); + if( !hctx) + { + if( pcon) + dbus_connection_close(conn); + dbus_connection_unref(conn); + conn = NULL; + + ZYPP_THROW(HalException( + _("libhal_ctx_new: Can't create libhal context") + )); + } + + if( !libhal_ctx_set_dbus_connection(hctx, conn)) + { + libhal_ctx_free(hctx); + hctx = NULL; + + if( pcon) + dbus_connection_close(conn); + dbus_connection_unref(conn); + conn = NULL; + + ZYPP_THROW(HalException( + _("libhal_set_dbus_connection: Can't set dbus connection") + )); + } + + if( !libhal_ctx_init(hctx, &err.error)) + { + libhal_ctx_free(hctx); + hctx = NULL; + + if( pcon) + dbus_connection_close(conn); + dbus_connection_unref(conn); + conn = NULL; + + ZYPP_THROW(err.halException( + _("Unable to initalize HAL context -- hald not running?") + )); + } + } + + // ------------------------------------------------------------- + HalContext_Impl::~HalContext_Impl() + { + if( hctx) + { + HalError err; + libhal_ctx_shutdown(hctx, &err.error); + libhal_ctx_free( hctx); + } + if( conn) + { + if( pcon) + dbus_connection_close(conn); + dbus_connection_unref(conn); + } + } + + + //////////////////////////////////////////////////////////////// + HalContext::HalContext(bool autoconnect) + : h_impl( NULL) + { + MutexLock lock(g_Mutex); + + if( autoconnect) + h_impl.reset( new HalContext_Impl()); + } + + // ------------------------------------------------------------- + HalContext::HalContext(const HalContext &context) + : h_impl( NULL) + { + MutexLock lock(g_Mutex); + + zypp::RW_pointer(context.h_impl).swap(h_impl); + } + + // ------------------------------------------------------------- + HalContext::~HalContext() + { + MutexLock lock(g_Mutex); + + h_impl.reset(); + } + + // -------------------------------------------------------------- + HalContext & + HalContext::operator=(const HalContext &context) + { + MutexLock lock(g_Mutex); + + if( this == &context) + return *this; + + zypp::RW_pointer(context.h_impl).swap(h_impl); + return *this; + } + + // -------------------------------------------------------------- + HalContext::operator HalContext::bool_type() const + { + MutexLock lock(g_Mutex); + + return h_impl; + } + + // -------------------------------------------------------------- + void + HalContext::connect() + { + MutexLock lock(g_Mutex); + + if( !h_impl) + h_impl.reset( new HalContext_Impl()); + } + + // -------------------------------------------------------------- + std::vector + HalContext::getAllDevices() const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + char **names; + int count = 0; + + names = libhal_get_all_devices( h_impl->hctx, &count, &err.error); + if( !names) + { + ZYPP_THROW(err.halException()); + } + + std::vector ret(names, names + count); + libhal_free_string_array(names); + return ret; + } + + // -------------------------------------------------------------- + HalDrive + HalContext::getDriveFromUDI(const std::string &udi) const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + LibHalDrive *drv = libhal_drive_from_udi(h_impl->hctx, udi.c_str()); + if( drv != NULL) + return HalDrive(new HalDrive_Impl( h_impl, drv)); + else + return HalDrive(); + } + + // -------------------------------------------------------------- + HalVolume + HalContext::getVolumeFromUDI(const std::string &udi) const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + LibHalVolume *vol = libhal_volume_from_udi(h_impl->hctx, udi.c_str()); + if( vol) + return HalVolume( new HalVolume_Impl(vol)); + else + return HalVolume(); + } + + // -------------------------------------------------------------- + HalVolume + HalContext::getVolumeFromDeviceFile(const std::string &device_file) const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + LibHalVolume *vol = libhal_volume_from_device_file(h_impl->hctx, + device_file.c_str()); + if( vol) + return HalVolume( new HalVolume_Impl(vol)); + else + return HalVolume(); + } + + // -------------------------------------------------------------- + std::vector + HalContext::findDevicesByCapability(const std::string &capability) const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + char **names; + int count = 0; + + names = libhal_find_device_by_capability(h_impl->hctx, + capability.c_str(), + &count, &err.error); + if( !names) + { + ZYPP_THROW(err.halException()); + } + + std::vector ret(names, names + count); + libhal_free_string_array(names); + return ret; + } + + // -------------------------------------------------------------- + bool + HalContext::getDevicePropertyBool (const std::string &udi, + const std::string &key) const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + dbus_bool_t ret; + + ret = libhal_device_get_property_bool (h_impl->hctx, + udi.c_str(), + key.c_str(), + &err.error); + if( err.isSet()) + { + ZYPP_THROW(err.halException()); + } + return ret; + } + + // -------------------------------------------------------------- + int32_t + HalContext::getDevicePropertyInt32 (const std::string &udi, + const std::string &key) const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + dbus_int32_t ret; + + ret = libhal_device_get_property_int (h_impl->hctx, + udi.c_str(), + key.c_str(), + &err.error); + if( err.isSet()) + { + ZYPP_THROW(err.halException()); + } + return ret; + } + + // -------------------------------------------------------------- + uint64_t + HalContext::getDevicePropertyUInt64(const std::string &udi, + const std::string &key) const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + dbus_uint64_t ret; + + ret = libhal_device_get_property_uint64(h_impl->hctx, + udi.c_str(), + key.c_str(), + &err.error); + if( err.isSet()) + { + ZYPP_THROW(err.halException()); + } + return ret; + } + + // -------------------------------------------------------------- + double + HalContext::getDevicePropertyDouble(const std::string &udi, + const std::string &key) const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + double ret; + + ret = libhal_device_get_property_bool (h_impl->hctx, + udi.c_str(), + key.c_str(), + &err.error); + if( err.isSet()) + { + ZYPP_THROW(err.halException()); + } + return ret; + } + + + // -------------------------------------------------------------- + std::string + HalContext::getDevicePropertyString(const std::string &udi, + const std::string &key) const + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + std::string ret; + char *ptr; + + ptr = libhal_device_get_property_string(h_impl->hctx, + udi.c_str(), + key.c_str(), + &err.error); + if( err.isSet()) + { + ZYPP_THROW(err.halException()); + } + if( ptr != NULL) + { + ret = ptr; + free(ptr); + } + return ret; + } + + // -------------------------------------------------------------- + void + HalContext::setDevicePropertyBool (const std::string &udi, + const std::string &key, + bool value) + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + dbus_bool_t ret; + + ret = libhal_device_set_property_bool (h_impl->hctx, + udi.c_str(), + key.c_str(), + value ? 1 : 0, + &err.error); + if( !ret) + { + ZYPP_THROW(err.halException()); + } + } + + // -------------------------------------------------------------- + void + HalContext::setDevicePropertyInt32 (const std::string &udi, + const std::string &key, + int32_t value) + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + dbus_bool_t ret; + + ret = libhal_device_set_property_int (h_impl->hctx, + udi.c_str(), + key.c_str(), + value, + &err.error); + if( !ret) + { + ZYPP_THROW(err.halException()); + } + } + + // -------------------------------------------------------------- + void + HalContext::setDevicePropertyUInt64(const std::string &udi, + const std::string &key, + uint64_t value) + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + dbus_bool_t ret; + + ret = libhal_device_set_property_uint64(h_impl->hctx, + udi.c_str(), + key.c_str(), + value, + &err.error); + if( !ret) + { + ZYPP_THROW(err.halException()); + } + } + + // -------------------------------------------------------------- + void + HalContext::setDevicePropertyDouble(const std::string &udi, + const std::string &key, + double value) + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + dbus_bool_t ret; + + ret = libhal_device_set_property_double(h_impl->hctx, + udi.c_str(), + key.c_str(), + value, + &err.error); + if( !ret) + { + ZYPP_THROW(err.halException()); + } + } + + // -------------------------------------------------------------- + void + HalContext::setDevicePropertyString(const std::string &udi, + const std::string &key, + const std::string &value) + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + dbus_bool_t ret; + + ret = libhal_device_set_property_string(h_impl->hctx, + udi.c_str(), + key.c_str(), + value.c_str(), + &err.error); + if( !ret) + { + ZYPP_THROW(err.halException()); + } + } + + // -------------------------------------------------------------- + void + HalContext::removeDeviceProperty(const std::string &udi, + const std::string &key) + { + MutexLock lock(g_Mutex); + VERIFY_CONTEXT(h_impl); + + HalError err; + dbus_bool_t ret; + + ret = libhal_device_remove_property(h_impl->hctx, + udi.c_str(), + key.c_str(), + &err.error); + if( !ret) + { + ZYPP_THROW(err.halException()); + } + } + + //////////////////////////////////////////////////////////////// + HalDrive::HalDrive() + : d_impl( NULL) + { + } + + // -------------------------------------------------------------- + HalDrive::HalDrive(HalDrive_Impl *impl) + : d_impl( NULL) + { + MutexLock lock(g_Mutex); + + d_impl.reset(impl); + } + + // -------------------------------------------------------------- + HalDrive::HalDrive(const HalDrive &drive) + : d_impl( NULL) + { + MutexLock lock(g_Mutex); + + zypp::RW_pointer(drive.d_impl).swap(d_impl); + } + + // -------------------------------------------------------------- + HalDrive::~HalDrive() + { + MutexLock lock(g_Mutex); + + d_impl.reset(); + } + + // -------------------------------------------------------------- + HalDrive & + HalDrive::operator=(const HalDrive &drive) + { + MutexLock lock(g_Mutex); + + if( this == &drive) + return *this; + + zypp::RW_pointer(drive.d_impl).swap(d_impl); + return *this; + } + + // -------------------------------------------------------------- + HalDrive::operator HalDrive::bool_type() const + { + MutexLock lock(g_Mutex); + + return d_impl; + } + + // -------------------------------------------------------------- + std::string + HalDrive::getUDI() const + { + MutexLock lock(g_Mutex); + VERIFY_DRIVE(d_impl); + + const char *ptr = libhal_drive_get_udi(d_impl->drv); + return std::string(ptr ? ptr : ""); + } + + // -------------------------------------------------------------- + std::string + HalDrive::getTypeName() const + { + MutexLock lock(g_Mutex); + VERIFY_DRIVE(d_impl); + + const char *ptr = libhal_drive_get_type_textual(d_impl->drv); + return std::string(ptr ? ptr : ""); + } + + // -------------------------------------------------------------- + std::string + HalDrive::getDeviceFile() const + { + MutexLock lock(g_Mutex); + VERIFY_DRIVE(d_impl); + + return std::string(libhal_drive_get_device_file(d_impl->drv)); + } + + // -------------------------------------------------------------- + unsigned int + HalDrive::getDeviceMajor() const + { + MutexLock lock(g_Mutex); + VERIFY_DRIVE(d_impl); + + return libhal_drive_get_device_major(d_impl->drv); + } + + // -------------------------------------------------------------- + unsigned int + HalDrive::getDeviceMinor() const + { + MutexLock lock(g_Mutex); + VERIFY_DRIVE(d_impl); + + return libhal_drive_get_device_minor(d_impl->drv); + } + + // -------------------------------------------------------------- + bool + HalDrive::usesRemovableMedia() const + { + MutexLock lock(g_Mutex); + VERIFY_DRIVE(d_impl); + + return libhal_drive_uses_removable_media(d_impl->drv); + } + + // -------------------------------------------------------------- + std::vector + HalDrive::getCdromCapabilityNames() const + { + MutexLock lock(g_Mutex); + VERIFY_DRIVE(d_impl); + + std::vector ret; + LibHalDriveCdromCaps caps; + + /* + ** FIXME: there is no textual variant :-( + ** using property key names... + */ + caps = libhal_drive_get_cdrom_caps(d_impl->drv); + + if(caps & LIBHAL_DRIVE_CDROM_CAPS_CDROM) + ret.push_back("cdrom"); + if(caps & LIBHAL_DRIVE_CDROM_CAPS_CDR) + ret.push_back("cdr"); + if(caps & LIBHAL_DRIVE_CDROM_CAPS_CDRW) + ret.push_back("cdrw"); + if(caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRAM) + ret.push_back("dvdram"); + if(caps & LIBHAL_DRIVE_CDROM_CAPS_DVDROM) + ret.push_back("dvd"); + if(caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR) + ret.push_back("dvdr"); + if(caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW) + ret.push_back("dvdrw"); + if(caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR) + ret.push_back("dvdplusr"); + if(caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW) + ret.push_back("dvdplusrw"); + if(caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL) + ret.push_back("dvdplusrdl"); + + return ret; + +#if 0 + if( libhal_drive_get_type(d_impl->drv) != LIBHAL_DRIVE_TYPE_CDROM) + ZYPP_THROW(HalException(_("Not a CDROM drive"))); + + /* + ** FIXME: we use property keys matching + ** "storage.cdrom.cd*" + ** "storage.cdrom.dvd*" + ** but this may print other bool keys, + ** that are not CDROM caps. + */ + LibHalPropertySet *props; + HalError err; + + props = libhal_device_get_all_properties(d_impl->hal->hctx, + getUDI().c_str(), + &err.error); + if( !props) + ZYPP_THROW(err.halException()); + + std::vector ret(1, getTypeName()); + std::string key; + std::string dvd("storage.cdrom.dvd"); + std::string cd ("storage.cdrom.cd"); + + LibHalPropertySetIterator it; + for(libhal_psi_init(&it, props); + libhal_psi_has_more(&it); + libhal_psi_next(&it)) + { + if( libhal_psi_get_type(&it) == LIBHAL_PROPERTY_TYPE_BOOLEAN && + libhal_psi_get_bool(&it)) + { + key = libhal_psi_get_key(&it); + if( key.compare(0, cd.size(), cd) == 0) + { + ret.push_back(key.substr(sizeof("storage.cdrom.")-1)); + } + else + if( key.compare(0, dvd.size(), dvd) == 0) + { + ret.push_back(key.substr(sizeof("storage.cdrom.")-1)); + } + } + } + libhal_free_property_set(props); + + return ret; +#endif + } + + // -------------------------------------------------------------- + std::vector + HalDrive::findAllVolumes() const + { + MutexLock lock(g_Mutex); + VERIFY_DRIVE(d_impl); + + char **names; + int count = 0; + + names = libhal_drive_find_all_volumes(d_impl->hal->hctx, + d_impl->drv, + &count); + + std::vector ret; + ret.assign(names, names + count); + libhal_free_string_array(names); + return ret; + } + + + //////////////////////////////////////////////////////////////// + HalVolume::HalVolume() + : v_impl( NULL) + {} + + HalVolume::HalVolume(HalVolume_Impl *impl) + : v_impl( NULL) + { + MutexLock lock(g_Mutex); + + v_impl.reset(impl); + } + + // -------------------------------------------------------------- + HalVolume::HalVolume(const HalVolume &volume) + : v_impl( NULL) + { + MutexLock lock(g_Mutex); + + zypp::RW_pointer(volume.v_impl).swap(v_impl); + } + + // -------------------------------------------------------------- + HalVolume::~HalVolume() + { + MutexLock lock(g_Mutex); + + v_impl.reset(); + } + + // -------------------------------------------------------------- + HalVolume & + HalVolume::operator=(const HalVolume &volume) + { + MutexLock lock(g_Mutex); + + if( this == &volume) + return *this; + + zypp::RW_pointer(volume.v_impl).swap(v_impl); + return *this; + } + + // -------------------------------------------------------------- + HalVolume::operator HalVolume::bool_type() const + { + MutexLock lock(g_Mutex); + + return v_impl; + } + + // -------------------------------------------------------------- + std::string + HalVolume::getUDI() const + { + MutexLock lock(g_Mutex); + VERIFY_VOLUME(v_impl); + + const char *ptr = libhal_volume_get_udi(v_impl->vol); + return std::string(ptr ? ptr : ""); + } + + // -------------------------------------------------------------- + std::string + HalVolume::getDeviceFile() const + { + MutexLock lock(g_Mutex); + VERIFY_VOLUME(v_impl); + + return std::string(libhal_volume_get_device_file(v_impl->vol)); + } + + // -------------------------------------------------------------- + unsigned int + HalVolume::getDeviceMajor() const + { + MutexLock lock(g_Mutex); + VERIFY_VOLUME(v_impl); + + return libhal_volume_get_device_major(v_impl->vol); + } + + // -------------------------------------------------------------- + unsigned int + HalVolume::getDeviceMinor() const + { + MutexLock lock(g_Mutex); + VERIFY_VOLUME(v_impl); + + return libhal_volume_get_device_minor(v_impl->vol); + } + + // -------------------------------------------------------------- + bool + HalVolume::isDisc() const + { + MutexLock lock(g_Mutex); + VERIFY_VOLUME(v_impl); + + return libhal_volume_is_disc(v_impl->vol); + } + + // -------------------------------------------------------------- + bool + HalVolume::isPartition() const + { + MutexLock lock(g_Mutex); + VERIFY_VOLUME(v_impl); + + return libhal_volume_is_partition(v_impl->vol); + } + + // -------------------------------------------------------------- + bool + HalVolume::isMounted() const + { + MutexLock lock(g_Mutex); + VERIFY_VOLUME(v_impl); + + return libhal_volume_is_mounted(v_impl->vol); + } + + // -------------------------------------------------------------- + std::string + HalVolume::getFSType() const + { + MutexLock lock(g_Mutex); + VERIFY_VOLUME(v_impl); + + return std::string( libhal_volume_get_fstype(v_impl->vol)); + } + + // -------------------------------------------------------------- + std::string + HalVolume::getFSUsage() const + { + MutexLock lock(g_Mutex); + VERIFY_VOLUME(v_impl); + + LibHalVolumeUsage usage( libhal_volume_get_fsusage(v_impl->vol)); + std::string ret; + switch( usage) + { + case LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM: + ret = "filesystem"; + break; + case LIBHAL_VOLUME_USAGE_PARTITION_TABLE: + ret = "partitiontable"; + break; + case LIBHAL_VOLUME_USAGE_RAID_MEMBER: + return "raid"; + break; + case LIBHAL_VOLUME_USAGE_CRYPTO: + ret = "crypto"; + break; + case LIBHAL_VOLUME_USAGE_UNKNOWN: + default: + break; + } + return ret; + } + + // -------------------------------------------------------------- + std::string + HalVolume::getMountPoint() const + { + VERIFY_VOLUME(v_impl); + + return std::string( libhal_volume_get_mount_point(v_impl->vol)); + } + + + //////////////////////////////////////////////////////////////// + } // namespace hal + ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + } // namespace target + //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// +} // namespace zypp +////////////////////////////////////////////////////////////////////// +#else // NO_HAL +#include +#include +namespace zypp +{ //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// + namespace target + { ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + namespace hal + { //////////////////////////////////////////////////////////////// + + std::ostream & + HalException::dumpOn( std::ostream & str ) const + { return str; } + + // -------------------------------------------------------------- + class HalContext_Impl + {}; + class HalDrive_Impl + {}; + class HalVolume_Impl + {}; + + // -------------------------------------------------------------- + HalContext::HalContext(bool) + { ZYPP_THROW( NoHalException() ); } + HalContext::~HalContext() + {} + HalContext & + HalContext::operator=(const HalContext &) + { return *this; } + HalContext::operator HalContext::bool_type() const + { return 0; } + void + HalContext::connect() + {} + std::vector + HalContext::getAllDevices() const + { return std::vector(); } + HalDrive + HalContext::getDriveFromUDI(const std::string &) const + { return HalDrive(); } + HalVolume + HalContext::getVolumeFromUDI(const std::string &) const + { return HalVolume(); } + HalVolume + HalContext::getVolumeFromDeviceFile(const std::string &) const + { return HalVolume(); } + std::vector + HalContext::findDevicesByCapability(const std::string &) const + { return std::vector(); } + bool + HalContext::getDevicePropertyBool(const std::string &, const std::string &) const + { return false; } + void + HalContext::setDevicePropertyBool (const std::string &, const std::string &, bool value) + {} + void + HalContext::removeDeviceProperty(const std::string &, const std::string &) + {} + std::string + HalContext::getDevicePropertyString(const std::string &, const std::string &) const + { return ""; } + // -------------------------------------------------------------- + HalDrive::HalDrive() + { ZYPP_THROW( NoHalException() ); } + HalDrive::~HalDrive() + {} + HalDrive & + HalDrive::operator=(const HalDrive &) + { return *this; } + HalDrive::operator HalDrive::bool_type() const + { return 0; } + std::string + HalDrive::getUDI() const + { return std::string(); } + std::string + HalDrive::getTypeName() const + { return std::string(); } + std::string + HalDrive::getDeviceFile() const + { return std::string(); } + unsigned int + HalDrive::getDeviceMinor() const + { return 0; } + unsigned int + HalDrive::getDeviceMajor() const + { return 0; } + bool + HalDrive::usesRemovableMedia() const + { return false; } + std::vector + HalDrive::getCdromCapabilityNames() const + { return std::vector(); } + std::vector + HalDrive::findAllVolumes() const + { return std::vector(); } + + // -------------------------------------------------------------- + HalVolume::HalVolume() + { ZYPP_THROW( NoHalException() ); } + HalVolume::~HalVolume() + {} + HalVolume & + HalVolume::operator=(const HalVolume &) + { return *this; } + HalVolume::operator HalVolume::bool_type() const + { return 0; } + std::string + HalVolume::getUDI() const + { return std::string(); } + std::string + HalVolume::getDeviceFile() const + { return std::string(); } + unsigned int + HalVolume::getDeviceMinor() const + { return 0; } + unsigned int + HalVolume::getDeviceMajor() const + { return 0; } + bool + HalVolume::isDisc() const + { return false; } + bool + HalVolume::isPartition() const + { return false; } + bool + HalVolume::isMounted() const + { return false; } + std::string + HalVolume::getFSType() const + { return std::string(); } + std::string + HalVolume::getFSUsage() const + { return std::string(); } + std::string + HalVolume::getMountPoint() const + { return std::string(); } + + //////////////////////////////////////////////////////////////// + } // namespace hal + ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + } // namespace target + //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// +} // namespace zypp +////////////////////////////////////////////////////////////////////// +#endif // NO_HAL + +/* +** vim: set ts=2 sts=2 sw=2 ai et: +*/ diff --git a/zypp/target/hal/HalContext.h b/zypp/target/hal/HalContext.h new file mode 100644 index 0000000..9ad75d6 --- /dev/null +++ b/zypp/target/hal/HalContext.h @@ -0,0 +1,346 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/target/hal/HalContext.h + * + * \brief Hardware abstaction layer library wrapper. + */ +#ifndef ZYPP_TARGET_HAL_HALCONTEXT_H +#define ZYPP_TARGET_HAL_HALCONTEXT_H + +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////// +namespace zypp +{ //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// + namespace target + { ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + namespace hal + { //////////////////////////////////////////////////////////////// + + + // ------------------------------------------------------------- + /** @{ + * Forward declarations. + */ + class HalDrive; + class HalVolume; + + class HalDrive_Impl; + class HalVolume_Impl; + class HalContext_Impl; + /** }@ */ + + + //////////////////////////////////////////////////////////////// + // + // CLASS NAME : HalContext + // + /** Hardware abstaction layer context. + * + * Hal context wrapper. It manages the dbus connection and is + * the entry point to query drives, volumes and other information. + * + * @todo: wrap more functions. + */ + class HalContext + { + public: + typedef + zypp::RW_pointer::unspecified_bool_type bool_type; + + HalContext(bool autoconnect=false); + HalContext(const HalContext &context); + ~HalContext(); + + HalContext& + operator=(const HalContext &context); + + /** + * Verifies if the context is initialized. + */ + operator bool_type() const; + + /** + */ + void + connect(); + + /** + * Retrieve UDI's of all devices. + * \return Vector with device UDI's. + */ + std::vector + getAllDevices() const; + + /** + * Construct a HalDrive object for the specified UDI. + * \param The \p udi of the drive. + * \return The HalDrive object. + */ + HalDrive + getDriveFromUDI(const std::string &udi) const; + + /** + * Construct a HalVolume object for the specified UDI. + * \param The \p udi of the volume. + * \return The HalVolume object. + */ + HalVolume + getVolumeFromUDI(const std::string &udi) const; + + HalVolume + getVolumeFromDeviceFile(const std::string &device_file) const; + + /** + * Retrieve UDI's of all devices with a capability. + * \param The \p capability name + * \return Vector with device UDI's. + */ + std::vector + findDevicesByCapability(const std::string &capability) const; + + bool + getDevicePropertyBool (const std::string &udi, + const std::string &key) const; + + int32_t + getDevicePropertyInt32 (const std::string &udi, + const std::string &key) const; + + uint64_t + getDevicePropertyUInt64(const std::string &udi, + const std::string &key) const; + + double + getDevicePropertyDouble(const std::string &udi, + const std::string &key) const; + + std::string + getDevicePropertyString(const std::string &udi, + const std::string &key) const; + + void + setDevicePropertyBool (const std::string &udi, + const std::string &key, + bool value); + + void + setDevicePropertyInt32 (const std::string &udi, + const std::string &key, + int32_t value); + + void + setDevicePropertyUInt64(const std::string &udi, + const std::string &key, + uint64_t value); + + void + setDevicePropertyDouble(const std::string &udi, + const std::string &key, + double value); + + void + setDevicePropertyString(const std::string &udi, + const std::string &key, + const std::string &value); + + void + removeDeviceProperty(const std::string &udi, + const std::string &key); + + private: + + zypp::RW_pointer h_impl; + }; + + + //////////////////////////////////////////////////////////////// + // + // CLASS NAME : HalDrive + // + /** Hardware abstaction layer storage drive object. + * + * @todo: wrap more functions. + */ + class HalDrive + { + public: + typedef + zypp::RW_pointer::unspecified_bool_type bool_type; + + HalDrive(); + HalDrive(const HalDrive &drive); + ~HalDrive(); + + HalDrive& + operator=(const HalDrive &drive); + + operator bool_type() const; + + std::string + getUDI() const; + + std::string + getTypeName() const; + + /** + * \return The drive's device file name. + */ + std::string + getDeviceFile() const; + + /** + * \return The drive's device file major number. + */ + unsigned int + getDeviceMajor() const; + + /** + * \return The drive's device minor number. + */ + unsigned int + getDeviceMinor() const; + + /** + * \return True, if drive uses removable media. + */ + bool + usesRemovableMedia() const; + + /* + ** Returns the media type names supported by the drive. + ** + ** Since hal does not implement a textual form here, we + ** are using the drive type and property names from + ** "storage.cdrom.*" namespace: + ** cdrom, cdr, cdrw, dvd, dvdr, dvdrw, dvdram, + ** dvdplusr, dvdplusrw, dvdplusrdl + ** + ** FIXME: Should we provide own LibHalDriveCdromCaps? + */ + std::vector + getCdromCapabilityNames() const; + + /** + * Retrieve UDI's of all volumes of this drive. + * \return Vector with volume UDI's. + */ + std::vector + findAllVolumes() const; + + private: + friend class HalContext; + + HalDrive(HalDrive_Impl *impl); + + zypp::RW_pointer d_impl; + }; + + + //////////////////////////////////////////////////////////////// + // + // CLASS NAME : HalVolume + // + /** Hardware abstaction layer storage volume object. + * + * @todo: wrap more functions. + */ + class HalVolume + { + public: + typedef + zypp::RW_pointer::unspecified_bool_type bool_type; + + HalVolume(); + HalVolume(const HalVolume &volume); + ~HalVolume(); + + HalVolume& + operator=(const HalVolume &volume); + + operator bool_type() const; + + std::string + getUDI() const; + + /** + * \return The Volume drive's device file name. + */ + std::string + getDeviceFile() const; + + /** + * \return The Volume drive's device major number. + */ + unsigned int + getDeviceMajor() const; + + /** + * \return The Volume drive's device minor number. + */ + unsigned int + getDeviceMinor() const; + + bool + isDisc() const; + + bool + isPartition() const; + + bool + isMounted() const; + + /** + * \return The filesystem name on the volume. + */ + std::string + getFSType() const; + + /** + * \return The filesystem usage purpose. + */ + std::string + getFSUsage() const; + + /** + * \return The mount point of the volume. + */ + std::string + getMountPoint() const; + + private: + friend class HalContext; + friend class HalDrive; + HalVolume(HalVolume_Impl *impl); + + zypp::RW_pointer v_impl; + }; + + + //////////////////////////////////////////////////////////////// + } // namespace hal + ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + } // namespace target + //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// +} // namespace zypp +////////////////////////////////////////////////////////////////////// + +#endif // ZYPP_TARGET_HAL_HALCONTEXT_H + +/* +** vim: set ts=2 sts=2 sw=2 ai et: +*/ diff --git a/zypp/target/hal/HalException.h b/zypp/target/hal/HalException.h new file mode 100644 index 0000000..4b957b8 --- /dev/null +++ b/zypp/target/hal/HalException.h @@ -0,0 +1,116 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/target/hal/HalException.h + * + * \brief Hardware abstaction layer library wrapper. + */ +#ifndef ZYPP_TARGET_HAL_HALEXCEPTION_H +#define ZYPP_TARGET_HAL_HALEXCEPTION_H + +#include +#include +#include + + +////////////////////////////////////////////////////////////////////// +namespace zypp +{ //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// + namespace target + { ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + namespace hal + { //////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////// + // + // CLASS NAME : HalException + // + /** Hardware abstaction layer exception. + * Just inherits Exception to separate hal exceptions. + */ + class HalException: public zypp::Exception + { + public: + /** Default constructor. + * Use \ref ZYPP_THROW to throw exceptions. + */ + HalException() + : zypp::Exception(_("Hal Exception")) + {} + + /** Constructor taking complete hal error message. + * This constructor is used to generate custom error + * messages, in case, that no DBUS error is avaliable. + * Use \ref ZYPP_THROW to throw exceptions. + */ + HalException(const std::string &msg_r) + : zypp::Exception(_("Hal Exception")) + , e_name() + , e_msg(msg_r) + {} + + /** Constructor taking HAL (DBUS) error message components. + * Use \ref ZYPP_THROW to throw exceptions. + */ + HalException(const std::string &err_name, const std::string &err_msg) + : zypp::Exception(_("Hal Exception")) + , e_name(err_name) + , e_msg(err_msg) + {} + + /** Destructor. + */ + virtual ~HalException() throw() {}; + + /** + * \return The HAL (DBUS) error name component. + */ + const std::string & errorName() const + { + return e_name; + } + + /** + * \return The HAL (DBUS) error message component. + */ + const std::string & errorMessage() const + { + return e_msg; + } + + protected: + virtual std::ostream & dumpOn( std::ostream & str ) const; + + private: + std::string e_name; + std::string e_msg; + }; + + /** Exception thrown if we were built without hal support (-DNO_HAL). + */ + struct NoHalException: public Exception + { NoHalException(); }; + + //////////////////////////////////////////////////////////////// + } // namespace hal + ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + } // namespace target + //////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// +} // namespace zypp +////////////////////////////////////////////////////////////////////// + +#endif // ZYPP_TARGET_HAL_HALEXCEPTION_H + +/* +** vim: set ts=2 sts=2 sw=2 ai et: +*/ -- 2.7.4