summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-04-15 13:00:19 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-04-15 13:00:19 -0500
commit43e139235d1457fed093c270b81d5e16c1922fc1 (patch)
treea55570a07bc966845903545d8fe914d6b75d66ef
parentf6402c325a2374e72411ccf4f409f9368b4e42c6 (diff)
downloadtdelibs-43e139235d1457fed093c270b81d5e16c1922fc1.tar.gz
tdelibs-43e139235d1457fed093c270b81d5e16c1922fc1.zip
Add support for udisks2 device eject
-rw-r--r--CMakeLists.txt1
-rw-r--r--tdecore/tdehardwaredevices.cpp112
-rw-r--r--tdecore/tdehardwaredevices.h7
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 <tqdbusdata.h>
#include <tqdbusmessage.h>
#include <tqdbusproxy.h>
#include <tqdbusvariant.h>
#include <tqdbusconnection.h>
-#endif // WITH_NETWORK_MANAGER_BACKEND
+#endif // defined(WITH_UPOWER) || defined(WITH_UDISKS2)
+#ifdef WITH_UDISKS2
+ #include <tqdbuserror.h>
+ #include <tqdbusdatamap.h>
+ #include <tqdbusobjectpath.h>
+#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<TQT_DBusData> 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<TQT_DBusData> 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<TQT_DBusData> params;
+ TQT_DBusDataMap<TQString> 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