diff options
Diffstat (limited to 'tdecore/tdehw/tdestoragedevice.cpp')
| -rw-r--r-- | tdecore/tdehw/tdestoragedevice.cpp | 382 |
1 files changed, 189 insertions, 193 deletions
diff --git a/tdecore/tdehw/tdestoragedevice.cpp b/tdecore/tdehw/tdestoragedevice.cpp index bff09e319..318768dfe 100644 --- a/tdecore/tdehw/tdestoragedevice.cpp +++ b/tdecore/tdehw/tdestoragedevice.cpp @@ -34,7 +34,7 @@ #include "tdeglobal.h" #include "kiconloader.h" #include "tdetempfile.h" -#include "kstandarddirs.h" +#include "tdestandarddirs.h" #include "tdehardwaredevices.h" #include "disksHelper.h" @@ -43,11 +43,9 @@ #if defined(WITH_CRYPTSETUP) #ifdef CRYPTSETUP_OLD_API #define class cryptsetup_class - #define CRYPT_SLOT_INVALID INVALID - #define CRYPT_SLOT_INACTIVE INACTIVE - #define CRYPT_SLOT_ACTIVE ACTIVE - #define CRYPT_SLOT_BUSY BUSY - #define CRYPT_SLOT_ACTIVE_LAST ACTIVE + #define CRYPT_SLOT_INACTIVE SLOT_INACTIVE + #define CRYPT_SLOT_ACTIVE SLOT_ACTIVE + #define CRYPT_SLOT_ACTIVE_LAST SLOT_ACTIVE_LAST #include <libcryptsetup.h> #undef class #else @@ -55,7 +53,7 @@ #endif #endif -TDEStorageDevice::TDEStorageDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn), m_mediaInserted(true), m_cryptDevice(NULL) { +TDEStorageDevice::TDEStorageDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn), m_mediaInserted(true), m_cryptDevice(NULL), m_cryptKeySlotCount(0) { m_diskType = TDEDiskDeviceType::Null; m_diskStatus = TDEDiskDeviceStatus::Null; } @@ -69,6 +67,26 @@ TDEStorageDevice::~TDEStorageDevice() { #endif } +TQString TDEStorageDevice::mappedName() { + return m_mappedName; +} + +void TDEStorageDevice::internalUpdateMappedName() { + // Get the device mapped name if present + m_mappedName = TQString::null; + TQString dmnodename = systemPath(); + dmnodename.append("/dm/name"); + TQFile dmnamefile(dmnodename); + if (dmnamefile.open(IO_ReadOnly)) { + TQTextStream stream(&dmnamefile); + m_mappedName = stream.readLine(); + dmnamefile.close(); + } + if (!m_mappedName.isEmpty()) { + m_mappedName.prepend("/dev/mapper/"); + } +} + TDEDiskDeviceType::TDEDiskDeviceType TDEStorageDevice::diskType() { return m_diskType; } @@ -266,8 +284,8 @@ TQString TDEStorageDevice::cryptKeySlotFriendlyName(TDELUKSKeySlotStatus::TDELUK } } -void TDEStorageDevice::internalSetDeviceNode(TQString sn) { - TDEGenericDevice::internalSetDeviceNode(sn); +void TDEStorageDevice::internalSetDeviceNode(TQString dn) { + TDEGenericDevice::internalSetDeviceNode(dn); internalInitializeLUKSIfNeeded(); } @@ -307,28 +325,40 @@ bool TDEStorageDevice::lockDriveMedia(bool lock) { } } -bool TDEStorageDevice::ejectDrive() { +TQStringVariantMap TDEStorageDevice::ejectDrive() { + TQStringVariantMap result; + TQStringVariantMap ejectResult; + + // If the device is mounted, try unmounting it first + if (!mountPath().isEmpty()) { + unmountDevice(); + } + #ifdef WITH_UDISKS2 if (!(TDEGlobal::dirs()->findExe("udisksctl").isEmpty())) { - TQStringVariantMap ejectResult = UDisks2EjectDrive(this); + ejectResult = udisks2EjectDrive(this); if (ejectResult["result"].toBool()) { - return true; + result["result"] = true; + return result; } else { - printf("[tdehwlib] Failed to eject drive '%s' via udisks2, falling back to alternate mechanism\n", deviceNode().ascii()); - fflush(stdout); + result["errStr"] = ejectResult["errStr"]; + result["result"] = false; + return result; } } #endif #ifdef WITH_UDISKS if (!(TDEGlobal::dirs()->findExe("udisks").isEmpty())) { - TQStringVariantMap ejectResult = UDisksEjectDrive(this); + ejectResult = udisksEjectDrive(this); if (ejectResult["result"].toBool()) { - return true; + result["result"] = true; + return result; } else { - printf("[tdehwlib] Failed to eject drive '%s' via udisks, falling back to alternate mechanism\n", deviceNode().ascii()); - fflush(stdout); + result["errStr"] = ejectResult["errStr"]; + result["result"] = false; + return result; } } #endif @@ -343,14 +373,18 @@ bool TDEStorageDevice::ejectDrive() { eject_output = ts.read(); int retcode = pclose(exepipe); if (retcode == 0) { - return true; + result["result"] = true; + return result; + } + else { + result["errStr"] = eject_output; + result["retCode"] = retcode; } } - printf("[tdehwlib] Failed to eject drive '%s' via 'eject' command\n", deviceNode().ascii()); - fflush(stdout); } - return false; + result["result"] = false; + return result; } bool TDEStorageDevice::ejectDriveMedia() { @@ -470,7 +504,7 @@ TQString TDEStorageDevice::friendlyName() { TQString label = diskLabel(); if (label.isNull()) { if (deviceSize() > 0) { - if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { + if (checkDiskStatus(TDEDiskDeviceStatus::Removable)) { label = i18n("%1 Removable Device").arg(deviceFriendlySize()); } else { @@ -527,7 +561,7 @@ TQString TDEStorageDevice::friendlyDeviceType() { if (isDiskOfType(TDEDiskDeviceType::HDD)) { ret = i18n("Hard Disk Drive"); - if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { + if (checkDiskStatus(TDEDiskDeviceStatus::Removable)) { ret = i18n("Removable Storage"); } if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) { @@ -598,7 +632,7 @@ TQPixmap TDEStorageDevice::icon(TDEIcon::StdSizes size) { if (isDiskOfType(TDEDiskDeviceType::HDD)) { ret = DesktopIcon("drive-harddisk" + mountString, size); - if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { + if (checkDiskStatus(TDEDiskDeviceStatus::Removable)) { ret = DesktopIcon("media-flash-usb" + mountString, size); } if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) { @@ -648,7 +682,13 @@ TQString TDEStorageDevice::deviceFriendlySize() { return TDEHardwareDevices::bytesToFriendlySizeString(deviceSize()); } -TQString TDEStorageDevice::mountPath() { +TQString TDEStorageDevice::mountPath() +{ + return m_mountPath; +} + +void TDEStorageDevice::internalUpdateMountPath() +{ // See if this device node is mounted // This requires parsing /proc/mounts, looking for deviceNode() @@ -656,21 +696,10 @@ TQString TDEStorageDevice::mountPath() { // It likes to advertise mounts as /dev/mapper/<something>, // where <something> is listed in <system path>/dm/name - // First, ensure that all device information (mainly holders/slaves) is accurate - TDEGlobal::hardwareDevices()->rescanDeviceInformation(this); + // Assumed all device information (mainly holders/slaves) is accurate + // prior to the call - TQString dmnodename = systemPath(); - dmnodename.append("/dm/name"); - TQFile namefile( dmnodename ); - TQString dmaltname; - if ( namefile.open( IO_ReadOnly ) ) { - TQTextStream stream( &namefile ); - dmaltname = stream.readLine(); - namefile.close(); - } - if (!dmaltname.isNull()) { - dmaltname.prepend("/dev/mapper/"); - } + m_mountPath = TQString::null; TQStringList lines; TQFile file( "/proc/mounts" ); @@ -682,30 +711,16 @@ TQString TDEStorageDevice::mountPath() { TQStringList mountInfo = TQStringList::split(" ", line, true); TQString testNode = *mountInfo.at(0); // Check for match - if ((testNode == deviceNode()) || (testNode == dmaltname) || (testNode == ("/dev/disk/by-uuid/" + diskUUID()))) { - TQString ret = *mountInfo.at(1); - ret.replace("\\040", " "); - return ret; + if ((testNode == deviceNode()) || (testNode == mappedName()) || (testNode == ("/dev/disk/by-uuid/" + diskUUID()))) { + m_mountPath = *mountInfo.at(1); + m_mountPath.replace("\\040", " "); + file.close(); + return; } lines += line; } file.close(); } - - // While this device is not directly mounted, it could concievably be mounted via the Device Mapper - // If so, try to retrieve the mount path... - TQStringList slaveDeviceList = holdingDevices(); - for ( TQStringList::Iterator slavedevit = slaveDeviceList.begin(); slavedevit != slaveDeviceList.end(); ++slavedevit ) { - // Try to locate this device path in the TDE device tree - TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); - TDEGenericDevice *hwdevice = hwdevices->findBySystemPath(*slavedevit); - if ((hwdevice) && (hwdevice->type() == TDEGenericDeviceType::Disk)) { - TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice); - return sdevice->mountPath(); - } - } - - return TQString::null; } TQStringVariantMap TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageMountOptions mountOptions) { @@ -786,7 +801,7 @@ TQStringVariantMap TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageM #if defined(WITH_UDISKS2) // Try to use UDISKS v2 via DBUS, if available - mountResult = UDisks2MountDrive(devNode, fileSystemType, optionString); + mountResult = udisks2MountDrive(devNode, fileSystemType, optionString); if (mountResult["result"].toBool()) { // Update internal mount data TDEGlobal::hardwareDevices()->processModifiedMounts(); @@ -806,7 +821,7 @@ TQStringVariantMap TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageM #if defined(WITH_UDISKS) // The UDISKS v2 DBUS service was either not available or was unusable // Try to use UDISKS v1 via DBUS, if available - mountResult = UDisksMountDrive(devNode, fileSystemType, udisksOptions); + mountResult = udisksMountDrive(devNode, fileSystemType, udisksOptions); if (mountResult["result"].toBool()) { // Update internal mount data TDEGlobal::hardwareDevices()->processModifiedMounts(); @@ -847,10 +862,6 @@ TQStringVariantMap TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageM // If no other method was found, use 'pmount' command if available if(command.isEmpty()) { if (!TDEGlobal::dirs()->findExe("pmount").isEmpty()) { - // Create dummy password file - KTempFile passwordFile(TQString::null, "tmp", 0600); - passwordFile.setAutoDelete(true); - TQString optionString; if (mountOptions["ro"] == "true") { optionString.append(" -r"); @@ -886,11 +897,9 @@ TQStringVariantMap TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageM mountpoint = mediaName; } - TQString passFileName = passwordFile.name(); - passFileName.replace("'", "'\\''"); - - command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1") - .arg(passFileName).arg(optionString).arg(devNode).arg(mountpoint); + // %1 (option string) without quotes, otherwise pmount fails + command = TQString("pmount %1 '%2' '%3' 2>&1") + .arg(optionString).arg(devNode).arg(mountpoint); } } @@ -917,99 +926,24 @@ TQStringVariantMap TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageM return result; } -TQStringVariantMap TDEStorageDevice::mountEncryptedDevice(TQString passphrase, TQString mediaName, - TDEStorageMountOptions mountOptions) { - TQStringVariantMap result; - - // Check if device is already mounted - TQString mountpath = mountPath(); - if (!mountpath.isEmpty()) { - result["mountPath"] = mountpath; - result["result"] = true; - return result; - } - - // Create dummy password file - KTempFile passwordFile(TQString::null, "tmp", 0600); - passwordFile.setAutoDelete(true); - TQFile* pwFile = passwordFile.file(); - if (!pwFile) { - result["errStr"] = i18n("Cannot create temporary password file"); - result["result"] = false; - return result; - } - - pwFile->writeBlock(passphrase.ascii(), passphrase.length()); - pwFile->flush(); - - TQString optionString; - if (mountOptions["ro"] == "true") { - optionString.append(" -r"); - } - - if (mountOptions["atime"] != "true") { - optionString.append(" -A"); - } - - if (mountOptions["utf8"] == "true") { - optionString.append(" -c utf8"); - } - - if (mountOptions["sync"] == "true") { - optionString.append(" -s"); - } - - if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { - optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"])); - } - - if (mountOptions.contains("locale")) { - optionString.append(TQString(" -c %1").arg(mountOptions["locale"])); - } - - TQString passFileName = passwordFile.name(); - TQString devNode = deviceNode(); - passFileName.replace("'", "'\\''"); - devNode.replace("'", "'\\''"); - mediaName.replace("'", "'\\''"); - TQString command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1") - .arg(passFileName).arg(optionString).arg(devNode).arg(mediaName); - - FILE *exepipe = popen(command.local8Bit(), "r"); - if (exepipe) { - TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly); - TQString mount_output = ts->read(); - delete ts; - int retcode = pclose(exepipe); - result["errStr"] = mount_output; - result["retCode"] = retcode; - } - - // Update internal mount data - TDEGlobal::hardwareDevices()->processModifiedMounts(); - result["mountPath"] = mountPath(); - result["result"] = !mountPath().isEmpty(); - return result; -} - TQStringVariantMap TDEStorageDevice::unmountDevice() { TQStringVariantMap result; // Check if device is already unmounted - TQString mountpoint = mountPath(); - if (mountpoint.isEmpty()) { + TQString mountpath = mountPath(); + if (mountpath.isEmpty()) { result["result"] = true; return result; } - mountpoint.replace("'", "'\\''"); + mountpath.replace("'", "'\\''"); TQString devNode = deviceNode(); TQString command = TQString::null; TQStringVariantMap unmountResult; #if defined(WITH_UDISKS2) // Try to use UDISKS v2 via DBUS, if available - unmountResult = UDisks2UnmountDrive(devNode, TQString::null); + unmountResult = udisks2UnmountDrive(devNode, TQString::null); if (unmountResult["result"].toBool()) { // Update internal mount data TDEGlobal::hardwareDevices()->processModifiedMounts(); @@ -1028,7 +962,7 @@ TQStringVariantMap TDEStorageDevice::unmountDevice() { #if defined(WITH_UDISKS) // The UDISKS v2 DBUS service was either not available or was unusable // Try to use UDISKS v1 via DBUS, if available - unmountResult = UDisksUnmountDrive(devNode, TQStringList()); + unmountResult = udisksUnmountDrive(devNode, TQStringList()); if (unmountResult["result"].toBool()) { // Update internal mount data TDEGlobal::hardwareDevices()->processModifiedMounts(); @@ -1048,13 +982,13 @@ TQStringVariantMap TDEStorageDevice::unmountDevice() { // The UDISKS v1 DBUS service was either not available or was unusable // Use 'udevil' command, if available if (!TDEGlobal::dirs()->findExe("udevil").isEmpty()) { - command = TQString("udevil umount '%1' 2>&1").arg(mountpoint); + command = TQString("udevil umount '%1' 2>&1").arg(mountpath); } #endif // If no other method was found, use 'pmount' command if available if(command.isEmpty() && !TDEGlobal::dirs()->findExe("pumount").isEmpty()) { - command = TQString("pumount '%1' 2>&1").arg(mountpoint); + command = TQString("pumount '%1' 2>&1").arg(mountpath); } if(command.isEmpty()) { @@ -1087,57 +1021,119 @@ TQStringVariantMap TDEStorageDevice::unmountDevice() { return result; } -TQString TDEStorageDevice::determineFileSystemType(TQString path) { - TQStringList mountTable; - TQString prevPath = path; - dev_t prevDev = 0; - int pos; - struct stat directory_info; - if (path.startsWith("/")) { - stat(path.local8Bit(), &directory_info); - prevDev = directory_info.st_dev; - // Walk the directory tree up to the root, checking for any change in st_dev - // If a change is found, the previous value of path is the mount point itself - while (path != "/") { - pos = path.findRev("/", -1, true); - if (pos < 0) { - break; - } - path = path.mid(0, pos); - if (path == "") { - path = "/"; +TQStringVariantMap TDEStorageDevice::unlockDevice(const TQString &passphrase) +{ + TQStringVariantMap result; + + TQString devNode = deviceNode(); + devNode.replace("'", "'\\''"); + + TQStringVariantMap unlockResult; + +#if defined(WITH_UDISKS2) + // Try to use UDISKS v2 via DBUS, if available + unlockResult = udisks2UnlockDrive(devNode, passphrase); + if (unlockResult["result"].toBool()) { + result["unlockedDevice"] = unlockResult["unlockedDevice"]; + result["result"] = true; + return result; + } + else if (unlockResult["retcode"].toInt() == -1) { + result["errStr"] = unlockResult["errStr"]; + result["result"] = false; + return result; + } +#endif + + // If no other method was found, use 'pmount' command if available + if (!TDEGlobal::dirs()->findExe("pmount").isEmpty()) { + // Create dummy password file + KTempFile passwordFile(TQString::null, "tmp", 0600); + passwordFile.setAutoDelete(true); + TQFile *pwFile = passwordFile.file(); + if (!pwFile) { + result["errStr"] = i18n("Cannot create temporary password file"); + result["result"] = false; + return result; + } + pwFile->writeBlock(passphrase.local8Bit(), passphrase.length()); + pwFile->flush(); + TQString passFileName = passwordFile.name(); + passFileName.replace("'", "'\\''"); + + TQString command = TQString("pmount -p '%1' '%2'").arg(passFileName).arg(devNode); + FILE *exepipe = popen(command.local8Bit(), "r"); + if (exepipe) { + TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly); + TQString unlock_output = ts->read(); + delete ts; + int retcode = pclose(exepipe); + if (retcode == 0) { + result["result"] = true; } - stat(path.local8Bit(), &directory_info); - if (directory_info.st_dev != prevDev) { - break; + else { + result["errStr"] = unlock_output; + result["retCode"] = retcode; + result["result"] = false; } - prevPath = path; - prevDev = directory_info.st_dev; + return result; } } - // Read in mount table - mountTable.clear(); - TQFile file( "/proc/mounts" ); - if ( file.open( IO_ReadOnly ) ) { - TQTextStream stream( &file ); - while ( !stream.atEnd() ) { - mountTable.append(stream.readLine()); - } - file.close(); + // No supported methods found for unlocking the device + result["errStr"] = i18n("No supported unlocking methods were detected on your system."); + result["result"] = false; + return result; +} + +TQStringVariantMap TDEStorageDevice::lockDevice() +{ + TQStringVariantMap result; + + TQString devNode = deviceNode(); + devNode.replace("'", "'\\''"); + + TQStringVariantMap lockResult; + +#if defined(WITH_UDISKS2) + // Try to use UDISKS v2 via DBUS, if available + lockResult = udisks2LockDrive(devNode); + if (lockResult["result"].toBool()) { + result["result"] = true; + return result; } + else if (lockResult["retcode"].toInt() == -1) { + result["errStr"] = lockResult["errStr"]; + result["result"] = false; + return result; + } +#endif - // Parse mount table - TQStringList::Iterator it; - for ( it = mountTable.begin(); it != mountTable.end(); ++it ) { - TQStringList mountInfo = TQStringList::split(" ", (*it), true); - if ((*mountInfo.at(1)) == prevPath) { - return (*mountInfo.at(2)); + // If no other method was found, use 'pumount' command if available + if (!TDEGlobal::dirs()->findExe("pumount").isEmpty()) { + TQString command = TQString("pumount '%1'").arg(devNode); + FILE *exepipe = popen(command.local8Bit(), "r"); + if (exepipe) { + TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly); + TQString lock_output = ts->read(); + delete ts; + int retcode = pclose(exepipe); + if (retcode == 0) { + result["result"] = true; + } + else { + result["errStr"] = lock_output; + result["retCode"] = retcode; + result["result"] = false; + } + return result; } } - // Unknown file system type - return TQString::null; + // No supported methods found for locking the device + result["errStr"] = i18n("No supported locking methods were detected on your system."); + result["result"] = false; + return result; } #include "tdestoragedevice.moc" |
