tdestoragedevice.cpp
00001 /* This file is part of the TDE libraries 00002 Copyright (C) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net> 00003 (C) 2013 Golubev Alexander <fatzer2@gmail.com> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License version 2 as published by the Free Software Foundation. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "tdestoragedevice.h" 00021 00022 #include <unistd.h> 00023 #include <fcntl.h> 00024 #include <sys/stat.h> 00025 #include <sys/ioctl.h> 00026 #include <linux/cdrom.h> 00027 00028 #include <tqregexp.h> 00029 #include <tqpixmap.h> 00030 #include <tqfile.h> 00031 00032 #include "kdebug.h" 00033 #include "tdelocale.h" 00034 #include "tdeglobal.h" 00035 #include "kiconloader.h" 00036 #include "tdetempfile.h" 00037 #include "kstandarddirs.h" 00038 00039 #include "tdehardwaredevices.h" 00040 00041 #include "config.h" 00042 00043 #if defined(WITH_CRYPTSETUP) 00044 #ifdef CRYPTSETUP_OLD_API 00045 #define class cryptsetup_class 00046 #define CRYPT_SLOT_INVALID INVALID 00047 #define CRYPT_SLOT_INACTIVE INACTIVE 00048 #define CRYPT_SLOT_ACTIVE ACTIVE 00049 #define CRYPT_SLOT_BUSY BUSY 00050 #define CRYPT_SLOT_ACTIVE_LAST ACTIVE 00051 #include <libcryptsetup.h> 00052 #undef class 00053 #else 00054 #include <libcryptsetup.h> 00055 #endif 00056 #endif 00057 00058 // uDisks2 integration 00059 #if defined(WITH_UDISKS) || defined(WITH_UDISKS2) 00060 #include <tqdbusdata.h> 00061 #include <tqdbusmessage.h> 00062 #include <tqdbusproxy.h> 00063 #include <tqdbusvariant.h> 00064 #include <tqdbusconnection.h> 00065 #include <tqdbuserror.h> 00066 #include <tqdbusdatamap.h> 00067 #include <tqdbusobjectpath.h> 00068 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2) 00069 #if defined(WITH_UDISKS) 00070 #include "tqdbusdatalist.h" 00071 #endif // ddefined(WITH_UDISKS) 00072 00073 #if defined(WITH_UDISKS) || defined(WITH_UDISKS2) 00074 // Defined in tdehardwaredevices.cpp 00075 TQT_DBusData convertDBUSDataToVariantData(TQT_DBusData); 00076 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2) 00077 00078 TDEStorageDevice::TDEStorageDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn), m_mediaInserted(true), m_cryptDevice(NULL) { 00079 m_diskType = TDEDiskDeviceType::Null; 00080 m_diskStatus = TDEDiskDeviceStatus::Null; 00081 } 00082 00083 TDEStorageDevice::~TDEStorageDevice() { 00084 #if defined(WITH_CRYPTSETUP) 00085 if (m_cryptDevice) { 00086 crypt_free(m_cryptDevice); 00087 m_cryptDevice = NULL; 00088 } 00089 #endif 00090 } 00091 00092 TDEDiskDeviceType::TDEDiskDeviceType TDEStorageDevice::diskType() { 00093 return m_diskType; 00094 } 00095 00096 void TDEStorageDevice::internalGetLUKSKeySlotStatus() { 00097 #if defined(WITH_CRYPTSETUP) 00098 unsigned int i; 00099 crypt_keyslot_info keyslot_status; 00100 TDELUKSKeySlotStatus::TDELUKSKeySlotStatus tde_keyslot_status; 00101 00102 m_cryptKeyslotStatus.clear(); 00103 for (i = 0; i < m_cryptKeySlotCount; i++) { 00104 keyslot_status = crypt_keyslot_status(m_cryptDevice, i); 00105 tde_keyslot_status = TDELUKSKeySlotStatus::Invalid; 00106 if (keyslot_status == CRYPT_SLOT_INACTIVE) { 00107 tde_keyslot_status = TDELUKSKeySlotStatus::Inactive; 00108 } 00109 else if (keyslot_status == CRYPT_SLOT_ACTIVE) { 00110 tde_keyslot_status = TDELUKSKeySlotStatus::Active; 00111 } 00112 else if (keyslot_status == CRYPT_SLOT_ACTIVE_LAST) { 00113 tde_keyslot_status = TDELUKSKeySlotStatus::Active | TDELUKSKeySlotStatus::Last; 00114 } 00115 m_cryptKeyslotStatus.append(tde_keyslot_status); 00116 } 00117 #endif 00118 } 00119 00120 void TDEStorageDevice::internalInitializeLUKSIfNeeded() { 00121 #if defined(WITH_CRYPTSETUP) 00122 int ret; 00123 00124 if (m_diskType & TDEDiskDeviceType::LUKS) { 00125 if (!m_cryptDevice) { 00126 TQString node = deviceNode(); 00127 if (node != "") { 00128 ret = crypt_init(&m_cryptDevice, node.ascii()); 00129 if (ret == 0) { 00130 ret = crypt_load(m_cryptDevice, NULL, NULL); 00131 if (ret == 0) { 00132 int keyslot_count; 00133 #if defined(CRYPTSETUP_OLD_API) || !defined(HAVE_CRYPTSETUP_GET_TYPE) 00134 kdWarning() << "TDEStorageDevice: The version of libcryptsetup that TDE was compiled against was too old! Most LUKS features will not function" << endl; 00135 m_cryptDeviceType = TQString::null; 00136 keyslot_count = 0; 00137 #else 00138 m_cryptDeviceType = crypt_get_type(m_cryptDevice); 00139 keyslot_count = crypt_keyslot_max(m_cryptDeviceType.ascii()); 00140 #endif 00141 if (keyslot_count < 0) { 00142 m_cryptKeySlotCount = 0; 00143 } 00144 else { 00145 m_cryptKeySlotCount = keyslot_count; 00146 } 00147 internalGetLUKSKeySlotStatus(); 00148 } 00149 } 00150 else { 00151 m_cryptDevice = NULL; 00152 } 00153 } 00154 } 00155 } 00156 else { 00157 if (m_cryptDevice) { 00158 crypt_free(m_cryptDevice); 00159 m_cryptDevice = NULL; 00160 } 00161 } 00162 #endif 00163 } 00164 00165 void TDEStorageDevice::cryptSetOperationsUnlockPassword(TQByteArray password) { 00166 #if defined(WITH_CRYPTSETUP) 00167 crypt_memory_lock(NULL, 1); 00168 m_cryptDevicePassword = password; 00169 #endif 00170 } 00171 00172 void TDEStorageDevice::cryptClearOperationsUnlockPassword() { 00173 m_cryptDevicePassword.fill(0); 00174 m_cryptDevicePassword.resize(0); 00175 #if defined(WITH_CRYPTSETUP) 00176 crypt_memory_lock(NULL, 0); 00177 #endif 00178 } 00179 00180 bool TDEStorageDevice::cryptOperationsUnlockPasswordSet() { 00181 if (m_cryptDevicePassword.size() > 0) { 00182 return true; 00183 } 00184 else { 00185 return false; 00186 } 00187 } 00188 00189 TDELUKSResult::TDELUKSResult TDEStorageDevice::cryptCheckKey(unsigned int keyslot) { 00190 #if defined(WITH_CRYPTSETUP) 00191 int ret; 00192 00193 if (m_cryptDevice) { 00194 if (keyslot < m_cryptKeySlotCount) { 00195 ret = crypt_activate_by_passphrase(m_cryptDevice, NULL, keyslot, m_cryptDevicePassword.data(), m_cryptDevicePassword.size(), 0); 00196 if (ret < 0) { 00197 return TDELUKSResult::KeyslotOpFailed; 00198 } 00199 else { 00200 return TDELUKSResult::Success; 00201 } 00202 } 00203 else { 00204 return TDELUKSResult::InvalidKeyslot; 00205 } 00206 } 00207 else { 00208 return TDELUKSResult::LUKSNotFound; 00209 } 00210 #else 00211 return TDELUKSResult::LUKSNotSupported; 00212 #endif 00213 } 00214 00215 TDELUKSResult::TDELUKSResult TDEStorageDevice::cryptAddKey(unsigned int keyslot, TQByteArray password) { 00216 #if defined(WITH_CRYPTSETUP) 00217 int ret; 00218 00219 if (m_cryptDevice) { 00220 if (keyslot < m_cryptKeySlotCount) { 00221 ret = crypt_keyslot_add_by_passphrase(m_cryptDevice, keyslot, m_cryptDevicePassword.data(), m_cryptDevicePassword.size(), password.data(), password.size()); 00222 if (ret < 0) { 00223 return TDELUKSResult::KeyslotOpFailed; 00224 } 00225 else { 00226 internalGetLUKSKeySlotStatus(); 00227 return TDELUKSResult::Success; 00228 } 00229 } 00230 else { 00231 return TDELUKSResult::InvalidKeyslot; 00232 } 00233 } 00234 else { 00235 return TDELUKSResult::LUKSNotFound; 00236 } 00237 #else 00238 return TDELUKSResult::LUKSNotSupported; 00239 #endif 00240 } 00241 00242 TDELUKSResult::TDELUKSResult TDEStorageDevice::cryptDelKey(unsigned int keyslot) { 00243 #if defined(WITH_CRYPTSETUP) 00244 int ret; 00245 00246 if (m_cryptDevice) { 00247 if (keyslot < m_cryptKeySlotCount) { 00248 ret = crypt_keyslot_destroy(m_cryptDevice, keyslot); 00249 if (ret < 0) { 00250 return TDELUKSResult::KeyslotOpFailed; 00251 } 00252 else { 00253 internalGetLUKSKeySlotStatus(); 00254 return TDELUKSResult::Success; 00255 } 00256 } 00257 else { 00258 return TDELUKSResult::InvalidKeyslot; 00259 } 00260 } 00261 else { 00262 return TDELUKSResult::LUKSNotFound; 00263 } 00264 #else 00265 return TDELUKSResult::LUKSNotSupported; 00266 #endif 00267 } 00268 00269 unsigned int TDEStorageDevice::cryptKeySlotCount() { 00270 return m_cryptKeySlotCount; 00271 } 00272 00273 TDELUKSKeySlotStatusList TDEStorageDevice::cryptKeySlotStatus() { 00274 return m_cryptKeyslotStatus; 00275 } 00276 00277 TQString TDEStorageDevice::cryptKeySlotFriendlyName(TDELUKSKeySlotStatus::TDELUKSKeySlotStatus status) { 00278 if (status & TDELUKSKeySlotStatus::Inactive) { 00279 return i18n("Inactive"); 00280 } 00281 else if (status & TDELUKSKeySlotStatus::Active) { 00282 return i18n("Active"); 00283 } 00284 else { 00285 return i18n("Unknown"); 00286 } 00287 } 00288 00289 void TDEStorageDevice::internalSetDeviceNode(TQString sn) { 00290 TDEGenericDevice::internalSetDeviceNode(sn); 00291 internalInitializeLUKSIfNeeded(); 00292 } 00293 00294 void TDEStorageDevice::internalSetDiskType(TDEDiskDeviceType::TDEDiskDeviceType dt) { 00295 m_diskType = dt; 00296 internalInitializeLUKSIfNeeded(); 00297 } 00298 00299 bool TDEStorageDevice::isDiskOfType(TDEDiskDeviceType::TDEDiskDeviceType tf) { 00300 return ((m_diskType&tf)!=TDEDiskDeviceType::Null); 00301 } 00302 00303 TDEDiskDeviceStatus::TDEDiskDeviceStatus TDEStorageDevice::diskStatus() { 00304 return m_diskStatus; 00305 } 00306 00307 void TDEStorageDevice::internalSetDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus st) { 00308 m_diskStatus = st; 00309 } 00310 00311 bool TDEStorageDevice::checkDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus sf) { 00312 return ((m_diskStatus&sf)!=(TDEDiskDeviceStatus::TDEDiskDeviceStatus)0); 00313 } 00314 00315 bool TDEStorageDevice::lockDriveMedia(bool lock) { 00316 int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK); 00317 if (fd < 0) { 00318 return false; 00319 } 00320 if (ioctl(fd, CDROM_LOCKDOOR, (lock)?1:0) != 0) { 00321 close(fd); 00322 return false; 00323 } 00324 else { 00325 close(fd); 00326 return true; 00327 } 00328 } 00329 00330 bool ejectDriveUDisks(TDEStorageDevice* sdevice) { 00331 #ifdef WITH_UDISKS 00332 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00333 if (dbusConn.isConnected()) { 00334 TQString blockDeviceString = sdevice->deviceNode(); 00335 blockDeviceString.replace("/dev/", ""); 00336 blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString; 00337 00338 // Eject the drive! 00339 TQT_DBusError error; 00340 TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn); 00341 if (driveControl.canSend()) { 00342 TQValueList<TQT_DBusData> params; 00343 TQT_DBusDataList options; 00344 params << TQT_DBusData::fromList(options); 00345 TQT_DBusMessage reply = driveControl.sendWithReply("DriveEject", params, &error); 00346 if (error.isValid()) { 00347 // Error! 00348 printf("[ERROR][tdehwlib] ejectDriveUDisks: %s\n", error.name().ascii()); fflush(stdout); 00349 return FALSE; 00350 } 00351 else { 00352 return TRUE; 00353 } 00354 } 00355 } 00356 #endif // WITH_UDISKS 00357 return FALSE; 00358 } 00359 00360 bool ejectDriveUDisks2(TDEStorageDevice* sdevice) { 00361 #ifdef WITH_UDISKS2 00362 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00363 if (dbusConn.isConnected()) { 00364 TQString blockDeviceString = sdevice->deviceNode(); 00365 blockDeviceString.replace("/dev/", ""); 00366 blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString; 00367 TQT_DBusProxy hardwareControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.DBus.Properties", dbusConn); 00368 if (hardwareControl.canSend()) { 00369 // get associated udisks2 drive path 00370 TQT_DBusError error; 00371 TQValueList<TQT_DBusData> params; 00372 params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Block") << TQT_DBusData::fromString("Drive"); 00373 TQT_DBusMessage reply = hardwareControl.sendWithReply("Get", params, &error); 00374 if (error.isValid()) { 00375 // Error! 00376 printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00377 return FALSE; 00378 } 00379 else { 00380 if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) { 00381 TQT_DBusObjectPath driveObjectPath = reply[0].toVariant().value.toObjectPath(); 00382 if (!driveObjectPath.isValid()) { 00383 return FALSE; 00384 } 00385 00386 error = TQT_DBusError(); 00387 TQT_DBusProxy driveInformation("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.DBus.Properties", dbusConn); 00388 // can eject? 00389 TQValueList<TQT_DBusData> params; 00390 params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Drive") << TQT_DBusData::fromString("Ejectable"); 00391 TQT_DBusMessage reply = driveInformation.sendWithReply("Get", params, &error); 00392 if (error.isValid()) { 00393 // Error! 00394 printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00395 return FALSE; 00396 } 00397 if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) { 00398 bool ejectable = reply[0].toVariant().value.toBool(); 00399 if (!ejectable) { 00400 return FALSE; 00401 } 00402 00403 // Eject the drive! 00404 TQT_DBusProxy driveControl("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.UDisks2.Drive", dbusConn); 00405 TQValueList<TQT_DBusData> params; 00406 TQT_DBusDataMap<TQString> options(TQT_DBusData::Variant); 00407 params << TQT_DBusData::fromStringKeyMap(options); 00408 TQT_DBusMessage reply = driveControl.sendWithReply("Eject", params, &error); 00409 if (error.isValid()) { 00410 // Error! 00411 printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00412 return FALSE; 00413 } 00414 else { 00415 return TRUE; 00416 } 00417 } 00418 } 00419 } 00420 } 00421 } 00422 #endif // WITH_UDISKS2 00423 return FALSE; 00424 } 00425 00426 int mountDriveUDisks(TQString deviceNode, TQString fileSystemType, TQStringList mountOptions, TQString* errStr = NULL) { 00427 #ifdef WITH_UDISKS 00428 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00429 if (dbusConn.isConnected()) { 00430 TQString blockDeviceString = deviceNode; 00431 blockDeviceString.replace("/dev/", ""); 00432 blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString; 00433 00434 // Mount the drive! 00435 TQT_DBusError error; 00436 TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn); 00437 if (driveControl.canSend()) { 00438 TQValueList<TQT_DBusData> params; 00439 params << TQT_DBusData::fromString(fileSystemType); 00440 params << TQT_DBusData::fromList(TQT_DBusDataList(mountOptions)); 00441 TQT_DBusMessage reply = driveControl.sendWithReply("FilesystemMount", params, &error); 00442 if (error.isValid()) { 00443 // Error! 00444 if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") { 00445 // Service not installed or unavailable 00446 return -2; 00447 } 00448 if (errStr) { 00449 *errStr = error.name() + ": " + error.message(); 00450 } 00451 else { 00452 printf("[ERROR][tdehwlib] mountDriveUDisks: %s\n", error.name().ascii()); fflush(stdout); 00453 } 00454 return -1; 00455 } 00456 else { 00457 return 0; 00458 } 00459 } 00460 else { 00461 return -2; 00462 } 00463 } 00464 #endif // WITH_UDISKS 00465 return -2; 00466 } 00467 00468 int mountDriveUDisks2(TQString deviceNode, TQString fileSystemType, TQString mountOptions, TQString* errStr = NULL) { 00469 #ifdef WITH_UDISKS2 00470 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00471 if (dbusConn.isConnected()) { 00472 TQString blockDeviceString = deviceNode; 00473 blockDeviceString.replace("/dev/", ""); 00474 blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString; 00475 00476 // Mount the drive! 00477 TQT_DBusError error; 00478 TQT_DBusProxy driveControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.UDisks2.Filesystem", dbusConn); 00479 if (driveControl.canSend()) { 00480 TQValueList<TQT_DBusData> params; 00481 TQMap<TQString, TQT_DBusData> optionsMap; 00482 if (fileSystemType != "") { 00483 optionsMap["fstype"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(fileSystemType)); 00484 } 00485 optionsMap["options"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(mountOptions)); 00486 params << TQT_DBusData::fromStringKeyMap(TQT_DBusDataMap<TQString>(optionsMap)); 00487 TQT_DBusMessage reply = driveControl.sendWithReply("Mount", params, &error); 00488 if (error.isValid()) { 00489 // Error! 00490 if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") { 00491 // Service not installed or unavailable 00492 return -2; 00493 } 00494 if (errStr) { 00495 *errStr = error.name() + ": " + error.message(); 00496 } 00497 else { 00498 printf("[ERROR][tdehwlib] mountDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00499 } 00500 return -1; 00501 } 00502 else { 00503 return 0; 00504 } 00505 } 00506 else { 00507 return -2; 00508 } 00509 } 00510 #endif // WITH_UDISKS2 00511 return -2; 00512 } 00513 00514 int unMountDriveUDisks(TQString deviceNode, TQStringList unMountOptions, TQString* errStr = NULL) { 00515 #ifdef WITH_UDISKS 00516 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00517 if (dbusConn.isConnected()) { 00518 TQString blockDeviceString = deviceNode; 00519 blockDeviceString.replace("/dev/", ""); 00520 blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString; 00521 00522 // Mount the drive! 00523 TQT_DBusError error; 00524 TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn); 00525 if (driveControl.canSend()) { 00526 TQValueList<TQT_DBusData> params; 00527 params << TQT_DBusData::fromList(TQT_DBusDataList(unMountOptions)); 00528 TQT_DBusMessage reply = driveControl.sendWithReply("FilesystemUnmount", params, &error); 00529 if (error.isValid()) { 00530 // Error! 00531 if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") { 00532 // Service not installed or unavailable 00533 return -2; 00534 } 00535 if (errStr) { 00536 *errStr = error.name() + ": " + error.message(); 00537 } 00538 else { 00539 printf("[ERROR][tdehwlib] unMountDriveUDisks: %s\n", error.name().ascii()); fflush(stdout); 00540 } 00541 return -1; 00542 } 00543 else { 00544 return 0; 00545 } 00546 } 00547 else { 00548 return -2; 00549 } 00550 } 00551 #endif // WITH_UDISKS 00552 return -2; 00553 } 00554 00555 int unMountDriveUDisks2(TQString deviceNode, TQString unMountOptions, TQString* errStr = NULL) { 00556 #ifdef WITH_UDISKS2 00557 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00558 if (dbusConn.isConnected()) { 00559 TQString blockDeviceString = deviceNode; 00560 blockDeviceString.replace("/dev/", ""); 00561 blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString; 00562 00563 // Mount the drive! 00564 TQT_DBusError error; 00565 TQT_DBusProxy driveControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.UDisks2.Filesystem", dbusConn); 00566 if (driveControl.canSend()) { 00567 TQValueList<TQT_DBusData> params; 00568 TQMap<TQString, TQT_DBusData> optionsMap; 00569 optionsMap["options"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(unMountOptions)); 00570 params << TQT_DBusData::fromStringKeyMap(TQT_DBusDataMap<TQString>(optionsMap)); 00571 TQT_DBusMessage reply = driveControl.sendWithReply("Unmount", params, &error); 00572 if (error.isValid()) { 00573 // Error! 00574 if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") { 00575 // Service not installed or unavailable 00576 return -2; 00577 } 00578 if (errStr) { 00579 *errStr = error.name() + ": " + error.message(); 00580 } 00581 else { 00582 printf("[ERROR][tdehwlib] unMountDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00583 } 00584 return -1; 00585 } 00586 else { 00587 return 0; 00588 } 00589 } 00590 else { 00591 return -2; 00592 } 00593 } 00594 #endif // WITH_UDISKS2 00595 return -2; 00596 } 00597 00598 bool TDEStorageDevice::ejectDrive() { 00599 #ifdef WITH_UDISKS2 00600 if (!(TDEGlobal::dirs()->findExe("udisksctl").isEmpty())) { 00601 if (ejectDriveUDisks2(this)) { 00602 return TRUE; 00603 } 00604 else { 00605 printf("[tdehwlib] Failed to eject drive '%s' via udisks2, falling back to alternate mechanism\n", deviceNode().ascii()); 00606 fflush(stdout); 00607 } 00608 } 00609 #endif // WITH_UDISKS2 00610 00611 #ifdef WITH_UDISKS 00612 if (!(TDEGlobal::dirs()->findExe("udisks").isEmpty())) { 00613 if (ejectDriveUDisks(this)) { 00614 return TRUE; 00615 } 00616 else { 00617 printf("[tdehwlib] Failed to eject drive '%s' via udisks, falling back to alternate mechanism\n", deviceNode().ascii()); 00618 fflush(stdout); 00619 } 00620 } 00621 #endif // WITH_UDISKS 00622 00623 if (!(TDEGlobal::dirs()->findExe("eject").isEmpty())) { 00624 TQString command = TQString("eject -v '%1' 2>&1").arg(deviceNode()); 00625 00626 FILE *exepipe = popen(command.ascii(), "r"); 00627 if (exepipe) { 00628 TQString eject_output; 00629 TQTextStream ts(exepipe, IO_ReadOnly); 00630 eject_output = ts.read(); 00631 int retcode = pclose(exepipe); 00632 if (retcode == 0) { 00633 return TRUE; 00634 } 00635 } 00636 printf("[tdehwlib] Failed to eject drive '%s' via 'eject' command\n", deviceNode().ascii()); 00637 fflush(stdout); 00638 } 00639 00640 return FALSE; 00641 } 00642 00643 bool TDEStorageDevice::ejectDriveMedia() { 00644 int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK); 00645 if (fd < 0) { 00646 return false; 00647 } 00648 if (ioctl(fd, CDROMEJECT) != 0) { 00649 close(fd); 00650 return false; 00651 } 00652 else { 00653 close(fd); 00654 return true; 00655 } 00656 } 00657 00658 TQString TDEStorageDevice::diskLabel() { 00659 return m_diskName; 00660 } 00661 00662 void TDEStorageDevice::internalSetDiskLabel(TQString dn) { 00663 m_diskName = dn; 00664 } 00665 00666 bool TDEStorageDevice::mediaInserted() { 00667 return m_mediaInserted; 00668 } 00669 00670 void TDEStorageDevice::internalSetMediaInserted(bool inserted) { 00671 m_mediaInserted = inserted; 00672 } 00673 00674 TQString TDEStorageDevice::fileSystemName() { 00675 return m_fileSystemName; 00676 } 00677 00678 void TDEStorageDevice::internalSetFileSystemName(TQString fn) { 00679 m_fileSystemName = fn; 00680 } 00681 00682 TQString TDEStorageDevice::fileSystemUsage() { 00683 return m_fileSystemUsage; 00684 } 00685 00686 void TDEStorageDevice::internalSetFileSystemUsage(TQString fu) { 00687 m_fileSystemUsage = fu; 00688 } 00689 00690 TQString TDEStorageDevice::diskUUID() { 00691 return m_diskUUID; 00692 } 00693 00694 void TDEStorageDevice::internalSetDiskUUID(TQString id) { 00695 m_diskUUID = id; 00696 } 00697 00698 TQStringList TDEStorageDevice::holdingDevices() { 00699 return m_holdingDevices; 00700 } 00701 00702 void TDEStorageDevice::internalSetHoldingDevices(TQStringList hd) { 00703 m_holdingDevices = hd; 00704 } 00705 00706 TQStringList TDEStorageDevice::slaveDevices() { 00707 return m_slaveDevices; 00708 } 00709 00710 void TDEStorageDevice::internalSetSlaveDevices(TQStringList sd) { 00711 m_slaveDevices = sd; 00712 } 00713 00714 TQString decodeHexEncoding(TQString str) { 00715 TQRegExp hexEncRegExp("\\\\x[0-9A-Fa-f]{1,2}"); 00716 hexEncRegExp.setMinimal(false); 00717 hexEncRegExp.setCaseSensitive(true); 00718 int s = -1; 00719 00720 while((s = hexEncRegExp.search(str, s+1))>=0){ 00721 str.replace(s, hexEncRegExp.cap(0).length(), TQChar((char)strtol(hexEncRegExp.cap(0).mid(2).ascii(), NULL, 16))); 00722 } 00723 00724 return str; 00725 } 00726 00727 TQString TDEStorageDevice::friendlyName() { 00728 // Return the actual storage device name 00729 TQString devicevendorid = vendorEncoded(); 00730 TQString devicemodelid = modelEncoded(); 00731 00732 devicevendorid = decodeHexEncoding(devicevendorid); 00733 devicemodelid = decodeHexEncoding(devicemodelid); 00734 00735 devicevendorid = devicevendorid.stripWhiteSpace(); 00736 devicemodelid = devicemodelid.stripWhiteSpace(); 00737 devicevendorid = devicevendorid.simplifyWhiteSpace(); 00738 devicemodelid = devicemodelid.simplifyWhiteSpace(); 00739 00740 TQString devicename = devicevendorid + " " + devicemodelid; 00741 00742 devicename = devicename.stripWhiteSpace(); 00743 devicename = devicename.simplifyWhiteSpace(); 00744 00745 if (devicename != "") { 00746 return devicename; 00747 } 00748 00749 if (isDiskOfType(TDEDiskDeviceType::Camera)) { 00750 return TDEGenericDevice::friendlyName(); 00751 } 00752 00753 if (isDiskOfType(TDEDiskDeviceType::Floppy)) { 00754 return friendlyDeviceType(); 00755 } 00756 00757 TQString label = diskLabel(); 00758 if (label.isNull()) { 00759 if (deviceSize() > 0) { 00760 if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { 00761 label = i18n("%1 Removable Device").arg(deviceFriendlySize()); 00762 } 00763 else { 00764 label = i18n("%1 Fixed Storage Device").arg(deviceFriendlySize()); 00765 } 00766 } 00767 } 00768 00769 if (!label.isNull()) { 00770 return label; 00771 } 00772 00773 return friendlyDeviceType(); 00774 } 00775 00776 TQString TDEStorageDevice::detailedFriendlyName() { 00777 return TQString("%1 [%2]").arg(friendlyName()).arg(deviceNode()); 00778 } 00779 00780 TQString TDEStorageDevice::friendlyDeviceType() { 00781 TQString ret = i18n("Hard Disk Drive"); 00782 00783 // Keep this in sync with TDEStorageDevice::icon(TDEIcon::StdSizes size) below 00784 if (isDiskOfType(TDEDiskDeviceType::Floppy)) { 00785 ret = i18n("Floppy Drive"); 00786 } 00787 if (isDiskOfType(TDEDiskDeviceType::Optical)) { 00788 ret = i18n("Optical Drive"); 00789 } 00790 if (isDiskOfType(TDEDiskDeviceType::CDROM)) { 00791 ret = i18n("CDROM Drive"); 00792 } 00793 if (isDiskOfType(TDEDiskDeviceType::CDRW)) { 00794 ret = i18n("CDRW Drive"); 00795 } 00796 if (isDiskOfType(TDEDiskDeviceType::DVDROM)) { 00797 ret = i18n("DVD Drive"); 00798 } 00799 if (isDiskOfType(TDEDiskDeviceType::DVDRW)) { 00800 ret = i18n("DVDRW Drive"); 00801 } 00802 if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) { 00803 ret = i18n("DVDRAM Drive"); 00804 } 00805 if (isDiskOfType(TDEDiskDeviceType::Zip)) { 00806 ret = i18n("Zip Drive"); 00807 } 00808 if (isDiskOfType(TDEDiskDeviceType::Tape)) { 00809 ret = i18n("Tape Drive"); 00810 } 00811 if (isDiskOfType(TDEDiskDeviceType::Camera)) { 00812 ret = i18n("Digital Camera"); 00813 } 00814 00815 if (isDiskOfType(TDEDiskDeviceType::HDD)) { 00816 ret = i18n("Hard Disk Drive"); 00817 if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { 00818 ret = i18n("Removable Storage"); 00819 } 00820 if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) { 00821 ret = i18n("Compact Flash"); 00822 } 00823 if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) { 00824 ret = i18n("Memory Stick"); 00825 } 00826 if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) { 00827 ret = i18n("Smart Media"); 00828 } 00829 if (isDiskOfType(TDEDiskDeviceType::SDMMC)) { 00830 ret = i18n("Secure Digital"); 00831 } 00832 } 00833 00834 if (isDiskOfType(TDEDiskDeviceType::RAM)) { 00835 ret = i18n("Random Access Memory"); 00836 } 00837 if (isDiskOfType(TDEDiskDeviceType::Loop)) { 00838 ret = i18n("Loop Device"); 00839 } 00840 00841 return ret; 00842 } 00843 00844 TQPixmap TDEStorageDevice::icon(TDEIcon::StdSizes size) { 00845 TQString mountString; 00846 if (mountPath() != TQString::null) { 00847 mountString = "-mounted"; 00848 } 00849 00850 TQPixmap ret = DesktopIcon("drive-harddisk" + mountString, size); 00851 00852 if (isDiskOfType(TDEDiskDeviceType::Floppy)) { 00853 ret = DesktopIcon("media-floppy-3_5" + mountString, size); 00854 } 00855 if (isDiskOfType(TDEDiskDeviceType::Optical)) { 00856 ret = DesktopIcon("media-optical-cdrom" + mountString, size); 00857 } 00858 if (isDiskOfType(TDEDiskDeviceType::CDROM)) { 00859 ret = DesktopIcon("media-optical-cdrom" + mountString, size); 00860 } 00861 if (isDiskOfType(TDEDiskDeviceType::CDRW)) { 00862 ret = DesktopIcon("media-optical-cdwriter" + mountString, size); 00863 } 00864 if (isDiskOfType(TDEDiskDeviceType::DVDROM)) { 00865 ret = DesktopIcon("media-optical-dvd" + mountString, size); 00866 } 00867 if (isDiskOfType(TDEDiskDeviceType::DVDRW)) { 00868 ret = DesktopIcon("media-optical-dvd" + mountString, size); 00869 } 00870 if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) { 00871 ret = DesktopIcon("media-optical-dvd" + mountString, size); 00872 } 00873 if (isDiskOfType(TDEDiskDeviceType::Zip)) { 00874 ret = DesktopIcon("media-floppy-zip" + mountString, size); 00875 } 00876 if (isDiskOfType(TDEDiskDeviceType::Tape)) { 00877 ret = DesktopIcon("media-tape" + mountString, size); 00878 } 00879 if (isDiskOfType(TDEDiskDeviceType::Camera)) { 00880 ret = DesktopIcon("camera" + TQString((mountPath() != TQString::null) ? "_mount" : "_umount"), size); 00881 } 00882 00883 if (isDiskOfType(TDEDiskDeviceType::HDD)) { 00884 ret = DesktopIcon("drive-harddisk" + mountString, size); 00885 if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { 00886 ret = DesktopIcon("media-flash-usb" + mountString, size); 00887 } 00888 if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) { 00889 ret = DesktopIcon("media-flash-compact_flash" + mountString, size); 00890 } 00891 if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) { 00892 ret = DesktopIcon("media-flash-memory_stick" + mountString, size); 00893 } 00894 if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) { 00895 ret = DesktopIcon("media-flash-smart_media" + mountString, size); 00896 } 00897 if (isDiskOfType(TDEDiskDeviceType::SDMMC)) { 00898 ret = DesktopIcon("media-flash-sd_mmc" + mountString, size); 00899 } 00900 } 00901 00902 if (isDiskOfType(TDEDiskDeviceType::RAM)) { 00903 ret = DesktopIcon("memory" + mountString, size); 00904 } 00905 if (isDiskOfType(TDEDiskDeviceType::Loop)) { 00906 ret = DesktopIcon("blockdevice" + mountString, size); 00907 } 00908 00909 return ret; 00910 } 00911 00912 unsigned long long TDEStorageDevice::deviceSize() { 00913 TQString bsnodename = systemPath(); 00914 // While at first glance it would seem that checking /queue/physical_block_size would be needed to get an accurate device size, in reality Linux 00915 // appears to only ever report the device size in 512 byte units. This does not appear to be documented anywhere! 00916 TQString blocksize = "512"; 00917 00918 TQString dsnodename = systemPath(); 00919 dsnodename.append("/size"); 00920 TQFile dsfile( dsnodename ); 00921 TQString devicesize; 00922 if ( dsfile.open( IO_ReadOnly ) ) { 00923 TQTextStream stream( &dsfile ); 00924 devicesize = stream.readLine(); 00925 dsfile.close(); 00926 } 00927 00928 return ((unsigned long long)blocksize.toULong()*(unsigned long long)devicesize.toULong()); 00929 } 00930 00931 TQString TDEStorageDevice::deviceFriendlySize() { 00932 return TDEHardwareDevices::bytesToFriendlySizeString(deviceSize()); 00933 } 00934 00935 TQString TDEStorageDevice::mountPath() { 00936 // See if this device node is mounted 00937 // This requires parsing /proc/mounts, looking for deviceNode() 00938 00939 // The Device Mapper throws a monkey wrench into this 00940 // It likes to advertise mounts as /dev/mapper/<something>, 00941 // where <something> is listed in <system path>/dm/name 00942 00943 // First, ensure that all device information (mainly holders/slaves) is accurate 00944 TDEGlobal::hardwareDevices()->rescanDeviceInformation(this); 00945 00946 TQString dmnodename = systemPath(); 00947 dmnodename.append("/dm/name"); 00948 TQFile namefile( dmnodename ); 00949 TQString dmaltname; 00950 if ( namefile.open( IO_ReadOnly ) ) { 00951 TQTextStream stream( &namefile ); 00952 dmaltname = stream.readLine(); 00953 namefile.close(); 00954 } 00955 if (!dmaltname.isNull()) { 00956 dmaltname.prepend("/dev/mapper/"); 00957 } 00958 00959 TQStringList lines; 00960 TQFile file( "/proc/mounts" ); 00961 if ( file.open( IO_ReadOnly ) ) { 00962 TQTextStream stream( &file ); 00963 TQString line; 00964 while ( !stream.atEnd() ) { 00965 line = stream.readLine(); 00966 TQStringList mountInfo = TQStringList::split(" ", line, true); 00967 TQString testNode = *mountInfo.at(0); 00968 // Check for match 00969 if ((testNode == deviceNode()) || (testNode == dmaltname) || (testNode == ("/dev/disk/by-uuid/" + diskUUID()))) { 00970 TQString ret = *mountInfo.at(1); 00971 ret.replace("\\040", " "); 00972 return ret; 00973 } 00974 lines += line; 00975 } 00976 file.close(); 00977 } 00978 00979 // While this device is not directly mounted, it could concievably be mounted via the Device Mapper 00980 // If so, try to retrieve the mount path... 00981 TQStringList slaveDeviceList = holdingDevices(); 00982 for ( TQStringList::Iterator slavedevit = slaveDeviceList.begin(); slavedevit != slaveDeviceList.end(); ++slavedevit ) { 00983 // Try to locate this device path in the TDE device tree 00984 TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); 00985 TDEGenericDevice *hwdevice = hwdevices->findBySystemPath(*slavedevit); 00986 if ((hwdevice) && (hwdevice->type() == TDEGenericDeviceType::Disk)) { 00987 TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice); 00988 return sdevice->mountPath(); 00989 } 00990 } 00991 00992 return TQString::null; 00993 } 00994 00995 TQString TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageMountOptions mountOptions, TQString* errRet, int* retcode) { 00996 int internal_retcode; 00997 if (!retcode) { 00998 retcode = &internal_retcode; 00999 } 01000 01001 TQString ret = mountPath(); 01002 01003 // Device is already mounted 01004 if (!ret.isNull()) { 01005 return ret; 01006 } 01007 01008 TQString command; 01009 TQString devNode = deviceNode(); 01010 devNode.replace("'", "'\\''"); 01011 mediaName.replace("'", "'\\''"); 01012 01013 #if defined(WITH_UDEVIL) || defined(WITH_UDISKS2) || defined(WITH_UDISKS) 01014 // Prepare filesystem options for mount 01015 TQStringList udisksOptions; 01016 TQString optionString; 01017 01018 if (mountOptions["ro"] == "true") { 01019 udisksOptions.append("ro"); 01020 } 01021 01022 if (mountOptions["atime"] != "true") { 01023 udisksOptions.append("noatime"); 01024 } 01025 01026 if (mountOptions["sync"] == "true") { 01027 udisksOptions.append("sync"); 01028 } 01029 01030 if( (mountOptions["filesystem"] == "fat") 01031 || (mountOptions["filesystem"] == "vfat") 01032 || (mountOptions["filesystem"] == "msdos") 01033 || (mountOptions["filesystem"] == "umsdos") 01034 ) { 01035 if (mountOptions.contains("shortname")) { 01036 udisksOptions.append(TQString("shortname=%1").arg(mountOptions["shortname"])); 01037 } 01038 } 01039 01040 if( (mountOptions["filesystem"] == "jfs")) { 01041 if (mountOptions["utf8"] == "true") { 01042 // udisks/udisks2 for now does not support option iocharset= for jfs 01043 // udisksOptions.append("iocharset=utf8"); 01044 } 01045 } 01046 01047 if( (mountOptions["filesystem"] == "ntfs-3g") ) { 01048 if (mountOptions.contains("locale")) { 01049 udisksOptions.append(TQString("locale=%1").arg(mountOptions["locale"])); 01050 } 01051 } 01052 01053 if( (mountOptions["filesystem"] == "ext3") 01054 || (mountOptions["filesystem"] == "ext4") 01055 ) { 01056 if (mountOptions.contains("journaling")) { 01057 // udisks/udisks2 for now does not support option data= for ext3/ext4 01058 // udisksOptions.append(TQString("data=%1").arg(mountOptions["journaling"])); 01059 } 01060 } 01061 01062 for (TQStringList::Iterator it = udisksOptions.begin(); it != udisksOptions.end(); ++it) { 01063 optionString.append(","); 01064 optionString.append(*it); 01065 } 01066 01067 if (!optionString.isEmpty()) { 01068 optionString.remove(0, 1); 01069 } 01070 #endif // defined(WITH_UDEVIL) || defined(WITH_UDISKS2) || defined(WITH_UDISKS) 01071 01072 #ifdef WITH_UDEVIL 01073 if(command.isEmpty()) { 01074 // Use 'udevil' command, if available 01075 TQString udevilProg = TDEGlobal::dirs()->findExe("udevil"); 01076 if (!udevilProg.isEmpty()) { 01077 01078 TQString fileSystemType; 01079 if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { 01080 fileSystemType = TQString("-t %1").arg(mountOptions["filesystem"]); 01081 } 01082 01083 TQString mountpoint; 01084 if (mountOptions.contains("mountpoint") 01085 && !mountOptions["mountpoint"].isEmpty() 01086 && (mountOptions["mountpoint"] != "/media/")) { 01087 mountpoint = mountOptions["mountpoint"]; 01088 mountpoint.replace("'", "'\\''"); 01089 } 01090 else { 01091 mountpoint = TQString("/media/%1").arg(mediaName); 01092 } 01093 01094 command = TQString("udevil mount %1 -o '%2' '%3' '%4' 2>&1").arg(fileSystemType).arg(optionString).arg(devNode).arg(mountpoint); 01095 } 01096 } 01097 #endif // WITH_UDEVIL 01098 01099 #ifdef WITH_UDISKS2 01100 if(command.isEmpty()) { 01101 // Try to use UDISKS v2 via DBUS, if available 01102 TQString errorString; 01103 TQString fileSystemType; 01104 01105 if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { 01106 fileSystemType = mountOptions["filesystem"]; 01107 } 01108 01109 int uDisks2Ret = mountDriveUDisks2(devNode, fileSystemType, optionString, &errorString); 01110 if (uDisks2Ret == 0) { 01111 // Update internal mount data 01112 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01113 01114 ret = mountPath(); 01115 return ret; 01116 } 01117 else if (uDisks2Ret == -1) { 01118 if (errRet) { 01119 *errRet = errorString; 01120 } 01121 01122 // Update internal mount data 01123 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01124 01125 ret = mountPath(); 01126 return ret; 01127 } 01128 else { 01129 // The UDISKS v2 DBUS service was either not available or was unusable; try another method... 01130 command = TQString::null; 01131 } 01132 } 01133 #endif // WITH_UDISKS2 01134 01135 #ifdef WITH_UDISKS 01136 if(command.isEmpty()) { 01137 // Try to use UDISKS v1 via DBUS, if available 01138 TQString errorString; 01139 TQString fileSystemType; 01140 01141 if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { 01142 fileSystemType = mountOptions["filesystem"]; 01143 } 01144 01145 int uDisksRet = mountDriveUDisks(devNode, fileSystemType, udisksOptions, &errorString); 01146 if (uDisksRet == 0) { 01147 // Update internal mount data 01148 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01149 01150 ret = mountPath(); 01151 return ret; 01152 } 01153 else if (uDisksRet == -1) { 01154 if (errRet) { 01155 *errRet = errorString; 01156 } 01157 01158 // Update internal mount data 01159 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01160 01161 ret = mountPath(); 01162 return ret; 01163 } 01164 else { 01165 // The UDISKS v1 DBUS service was either not available or was unusable; try another method... 01166 command = TQString::null; 01167 } 01168 } 01169 #endif // WITH_UDISKS 01170 01171 if(command.isEmpty()) { 01172 // Use 'pmount' command, if available 01173 TQString pmountProg = TDEGlobal::dirs()->findExe("pmount"); 01174 if (!pmountProg.isEmpty()) { 01175 // Create dummy password file 01176 KTempFile passwordFile(TQString::null, "tmp", 0600); 01177 passwordFile.setAutoDelete(true); 01178 01179 TQString optionString; 01180 if (mountOptions["ro"] == "true") { 01181 optionString.append(" -r"); 01182 } 01183 01184 if (mountOptions["atime"] != "true") { 01185 optionString.append(" -A"); 01186 } 01187 01188 if (mountOptions["utf8"] == "true") { 01189 optionString.append(" -c utf8"); 01190 } 01191 01192 if (mountOptions["sync"] == "true") { 01193 optionString.append(" -s"); 01194 } 01195 01196 if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { 01197 optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"])); 01198 } 01199 01200 if (mountOptions.contains("locale")) { 01201 optionString.append(TQString(" -c %1").arg(mountOptions["locale"])); 01202 } 01203 01204 TQString mountpoint; 01205 if (mountOptions.contains("mountpoint") 01206 && !mountOptions["mountpoint"].isEmpty() 01207 && (mountOptions["mountpoint"] != "/media/")) { 01208 mountpoint = mountOptions["mountpoint"]; 01209 mountpoint.replace("'", "'\\''"); 01210 } 01211 else { 01212 mountpoint = mediaName; 01213 } 01214 01215 TQString passFileName = passwordFile.name(); 01216 passFileName.replace("'", "'\\''"); 01217 01218 command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1").arg(passFileName).arg(optionString).arg(devNode).arg(mountpoint); 01219 } 01220 } 01221 01222 if(command.isEmpty()) { 01223 if (errRet) { 01224 *errRet = i18n("No supported mounting methods were detected on your system"); 01225 } 01226 return ret; 01227 } 01228 01229 FILE *exepipe = popen(command.local8Bit(), "r"); 01230 if (exepipe) { 01231 TQString mount_output; 01232 TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly); 01233 mount_output = ts->read(); 01234 delete ts; 01235 *retcode = pclose(exepipe); 01236 if (errRet) { 01237 *errRet = mount_output; 01238 } 01239 } 01240 01241 // Update internal mount data 01242 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01243 01244 ret = mountPath(); 01245 01246 return ret; 01247 } 01248 01249 TQString TDEStorageDevice::mountEncryptedDevice(TQString passphrase, TQString mediaName, TDEStorageMountOptions mountOptions, TQString* errRet, int* retcode) { 01250 int internal_retcode; 01251 if (!retcode) { 01252 retcode = &internal_retcode; 01253 } 01254 01255 TQString ret = mountPath(); 01256 01257 if (!ret.isNull()) { 01258 return ret; 01259 } 01260 01261 // Create dummy password file 01262 KTempFile passwordFile(TQString::null, "tmp", 0600); 01263 passwordFile.setAutoDelete(true); 01264 TQFile* pwFile = passwordFile.file(); 01265 if (!pwFile) { 01266 return TQString::null; 01267 } 01268 01269 pwFile->writeBlock(passphrase.ascii(), passphrase.length()); 01270 pwFile->flush(); 01271 01272 TQString optionString; 01273 if (mountOptions["ro"] == "true") { 01274 optionString.append(" -r"); 01275 } 01276 01277 if (mountOptions["atime"] != "true") { 01278 optionString.append(" -A"); 01279 } 01280 01281 if (mountOptions["utf8"] == "true") { 01282 optionString.append(" -c utf8"); 01283 } 01284 01285 if (mountOptions["sync"] == "true") { 01286 optionString.append(" -s"); 01287 } 01288 01289 if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { 01290 optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"])); 01291 } 01292 01293 if (mountOptions.contains("locale")) { 01294 optionString.append(TQString(" -c %1").arg(mountOptions["locale"])); 01295 } 01296 01297 TQString passFileName = passwordFile.name(); 01298 TQString devNode = deviceNode(); 01299 passFileName.replace("'", "'\\''"); 01300 devNode.replace("'", "'\\''"); 01301 mediaName.replace("'", "'\\''"); 01302 TQString command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1").arg(passFileName).arg(optionString).arg(devNode).arg(mediaName); 01303 01304 FILE *exepipe = popen(command.local8Bit(), "r"); 01305 if (exepipe) { 01306 TQString mount_output; 01307 TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly); 01308 mount_output = ts->read(); 01309 delete ts; 01310 *retcode = pclose(exepipe); 01311 if (errRet) { 01312 *errRet = mount_output; 01313 } 01314 } 01315 01316 // Update internal mount data 01317 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01318 01319 ret = mountPath(); 01320 01321 return ret; 01322 } 01323 01324 bool TDEStorageDevice::unmountDevice(TQString* errRet, int* retcode) { 01325 int internal_retcode; 01326 if (!retcode) { 01327 retcode = &internal_retcode; 01328 } 01329 01330 TQString mountpoint = mountPath(); 01331 TQString devNode = deviceNode(); 01332 01333 if (mountpoint.isNull()) { 01334 return true; 01335 } 01336 01337 mountpoint.replace("'", "'\\''"); 01338 01339 TQString command; 01340 01341 #ifdef WITH_UDEVIL 01342 if(command.isEmpty() && 01343 !(TDEGlobal::dirs()->findExe("udevil").isEmpty())) { 01344 command = TQString("udevil umount '%1' 2>&1").arg(mountpoint); 01345 } 01346 #endif // WITH_UDEVIL 01347 01348 #ifdef WITH_UDISKS2 01349 if(command.isEmpty()) { 01350 // Try to use UDISKS v2 via DBUS, if available 01351 TQString errorString; 01352 int unMountUDisks2Ret = unMountDriveUDisks2(devNode, TQString::null, &errorString); 01353 if (unMountUDisks2Ret == 0) { 01354 // Update internal mount data 01355 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01356 01357 return true; 01358 } 01359 else if (unMountUDisks2Ret == -1) { 01360 if (errRet) { 01361 *errRet = errorString; 01362 } 01363 01364 // Update internal mount data 01365 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01366 01367 return false; 01368 } 01369 else { 01370 // The UDISKS v2 DBUS service was either not available or was unusable; try another method... 01371 command = TQString::null; 01372 } 01373 } 01374 #endif // WITH_UDISKS2 01375 01376 #ifdef WITH_UDISKS 01377 if(command.isEmpty()) { 01378 // Try to use UDISKS v1 via DBUS, if available 01379 TQString errorString; 01380 int unMountUDisksRet = unMountDriveUDisks(devNode, TQStringList(), &errorString); 01381 if (unMountUDisksRet == 0) { 01382 // Update internal mount data 01383 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01384 01385 return true; 01386 } 01387 else if (unMountUDisksRet == -1) { 01388 if (errRet) { 01389 *errRet = errorString; 01390 } 01391 01392 // Update internal mount data 01393 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01394 01395 return false; 01396 } 01397 else { 01398 // The UDISKS v1 DBUS service was either not available or was unusable; try another method... 01399 command = TQString::null; 01400 } 01401 } 01402 #endif // WITH_UDISKS 01403 01404 if(command.isEmpty() && 01405 !(TDEGlobal::dirs()->findExe("pumount").isEmpty())) { 01406 command = TQString("pumount '%1' 2>&1").arg(mountpoint); 01407 } 01408 01409 if(command.isEmpty()) { 01410 if (errRet) { 01411 *errRet = i18n("No supported unmounting methods were detected on your system"); 01412 } 01413 return true; 01414 } 01415 01416 FILE *exepipe = popen(command.local8Bit(), "r"); 01417 if (exepipe) { 01418 TQString umount_output; 01419 TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly); 01420 umount_output = ts->read(); 01421 delete ts; 01422 *retcode = pclose(exepipe); 01423 if (*retcode == 0) { 01424 // Update internal mount data 01425 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01426 01427 return true; 01428 } 01429 else { 01430 if (errRet) { 01431 *errRet = umount_output; 01432 } 01433 } 01434 } 01435 01436 // Update internal mount data 01437 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01438 01439 return false; 01440 } 01441 01442 TQString TDEStorageDevice::determineFileSystemType(TQString path) { 01443 TQStringList mountTable; 01444 TQString prevPath = path; 01445 dev_t prevDev = 0; 01446 int pos; 01447 struct stat directory_info; 01448 if (path.startsWith("/")) { 01449 stat(path.local8Bit(), &directory_info); 01450 prevDev = directory_info.st_dev; 01451 // Walk the directory tree up to the root, checking for any change in st_dev 01452 // If a change is found, the previous value of path is the mount point itself 01453 while (path != "/") { 01454 pos = path.findRev("/", -1, TRUE); 01455 if (pos < 0) { 01456 break; 01457 } 01458 path = path.mid(0, pos); 01459 if (path == "") { 01460 path = "/"; 01461 } 01462 stat(path.local8Bit(), &directory_info); 01463 if (directory_info.st_dev != prevDev) { 01464 break; 01465 } 01466 prevPath = path; 01467 prevDev = directory_info.st_dev; 01468 } 01469 } 01470 01471 // Read in mount table 01472 mountTable.clear(); 01473 TQFile file( "/proc/mounts" ); 01474 if ( file.open( IO_ReadOnly ) ) { 01475 TQTextStream stream( &file ); 01476 while ( !stream.atEnd() ) { 01477 mountTable.append(stream.readLine()); 01478 } 01479 file.close(); 01480 } 01481 01482 // Parse mount table 01483 TQStringList::Iterator it; 01484 for ( it = mountTable.begin(); it != mountTable.end(); ++it ) { 01485 TQStringList mountInfo = TQStringList::split(" ", (*it), true); 01486 if ((*mountInfo.at(1)) == prevPath) { 01487 return (*mountInfo.at(2)); 01488 } 01489 } 01490 01491 // Unknown file system type 01492 return TQString::null; 01493 } 01494 01495 #include "tdestoragedevice.moc"
Trinity API Reference