From 43e139235d1457fed093c270b81d5e16c1922fc1 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Mon, 15 Apr 2013 13:00:19 -0500 Subject: Add support for udisks2 device eject --- CMakeLists.txt | 1 + tdecore/tdehardwaredevices.cpp | 112 +++++++++++++++++++++++++++++++++++++++-- tdecore/tdehardwaredevices.h | 7 +++ 3 files changed, 117 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fd195cf60..ca0a31b4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ OPTION( WITH_GCC_VISIBILITY "Enable fvisibility and fvisibility-inlines-hidden" OPTION( WITH_INOTIFY "Enable inotify support for tdeio" ON ) OPTION( WITH_GAMIN "Enable FAM/GAMIN support" ${WITH_ALL_OPTIONS} ) option( WITH_UPOWER "Enable UPOWER support" ${WITH_ALL_OPTIONS} ) +option( WITH_UDISKS2 "Enable UDISKS2 support" ${WITH_ALL_OPTIONS} ) OPTION( WITH_NETWORK_MANAGER_BACKEND "Enable network-manager support" OFF ) OPTION( WITH_SUDO_TDESU_BACKEND "Use sudo as backend for tdesu (default is su)" OFF ) diff --git a/tdecore/tdehardwaredevices.cpp b/tdecore/tdehardwaredevices.cpp index b8d6cf29f..3ed8661b6 100644 --- a/tdecore/tdehardwaredevices.cpp +++ b/tdecore/tdehardwaredevices.cpp @@ -67,14 +67,19 @@ #include "networkbackends/network-manager/network-manager.h" #endif // WITH_NETWORK_MANAGER_BACKEND -// uPower integration -#ifdef WITH_UPOWER +// uPower and uDisks2 integration +#if defined(WITH_UPOWER) || defined(WITH_UDISKS2) #include #include #include #include #include -#endif // WITH_NETWORK_MANAGER_BACKEND +#endif // defined(WITH_UPOWER) || defined(WITH_UDISKS2) +#ifdef WITH_UDISKS2 + #include + #include + #include +#endif // WITH_UDISKS2 // BEGIN BLOCK // Copied from include/linux/genhd.h @@ -449,6 +454,107 @@ bool TDEStorageDevice::lockDriveMedia(bool lock) { } } +bool ejectDriveUDisks2(TDEStorageDevice* sdevice) { +#ifdef WITH_UDISKS2 + TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); + if (dbusConn.isConnected()) { + TQString blockDeviceString = sdevice->deviceNode(); + blockDeviceString.replace("/dev/", ""); + blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString; + TQT_DBusProxy hardwareControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.DBus.Properties", dbusConn); + + // get associated udisks2 drive path + TQT_DBusError error; + TQValueList params; + params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Block") << TQT_DBusData::fromString("Drive"); + TQT_DBusMessage reply = hardwareControl.sendWithReply("Get", params, &error); + if (error.isValid()) { + // Error! + printf("[ERROR] %s\n\r", error.name().ascii()); fflush(stdout); + return FALSE; + } + else { + if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) { + TQT_DBusObjectPath driveObjectPath = reply[0].toVariant().value.toObjectPath(); + if (!driveObjectPath.isValid()) { + return FALSE; + } + + error = TQT_DBusError(); + TQT_DBusProxy driveInformation("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.DBus.Properties", dbusConn); + // can eject? + TQValueList params; + params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Drive") << TQT_DBusData::fromString("Ejectable"); + TQT_DBusMessage reply = driveInformation.sendWithReply("Get", params, &error); + if (error.isValid()) { + // Error! + printf("[ERROR] %s\n\r", error.name().ascii()); fflush(stdout); + return FALSE; + } + if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) { + bool ejectable = reply[0].toVariant().value.toBool(); + if (!ejectable) { + return FALSE; + } + + // Eject the drive! + TQT_DBusProxy driveControl("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.UDisks2.Drive", dbusConn); + TQValueList params; + TQT_DBusDataMap options(TQT_DBusData::Variant); + params << TQT_DBusData::fromStringKeyMap(options); + TQT_DBusMessage reply = driveControl.sendWithReply("Eject", params, &error); + if (error.isValid()) { + // Error! + printf("[ERROR] %s\n\r", error.name().ascii()); fflush(stdout); + return FALSE; + } + else { + return TRUE; + } + } + else { + return FALSE; + } + } + else { + return FALSE; + } + } + } + else { + return FALSE; + } +#else // WITH_UDISKS2 + return FALSE; +#endif // WITH_UDISKS2 +} + +bool TDEStorageDevice::ejectDrive() { + if (ejectDriveUDisks2(this)) { + return TRUE; + } + else { + TQString command = TQString("eject -v '%1' 2>&1").arg(deviceNode()); + + FILE *exepipe = popen(command.ascii(), "r"); + if (exepipe) { + TQString pmount_output; + char buffer[8092]; + pmount_output = fgets(buffer, sizeof(buffer), exepipe); + int retcode = pclose(exepipe); + if (retcode == 0) { + return TRUE; + } + else { + return FALSE; + } + } + else { + return FALSE; + } + } +} + bool TDEStorageDevice::ejectDriveMedia() { int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK); if (fd < 0) { diff --git a/tdecore/tdehardwaredevices.h b/tdecore/tdehardwaredevices.h index a31fc8eef..4c9b74940 100644 --- a/tdecore/tdehardwaredevices.h +++ b/tdecore/tdehardwaredevices.h @@ -668,6 +668,13 @@ class TDECORE_EXPORT TDEStorageDevice : public TDEGenericDevice */ bool ejectDriveMedia(); + /** + * @return TRUE on success, FALSE on failure + * + * This method currently works on all removable storage devices + */ + bool ejectDrive(); + protected: /** * @param a TQString with the disk or partition label, if any -- cgit v1.2.1