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 "tdelocale.h" 00033 #include "tdeglobal.h" 00034 #include "kiconloader.h" 00035 #include "tdetempfile.h" 00036 #include "kstandarddirs.h" 00037 00038 #include "tdehardwaredevices.h" 00039 00040 #include "config.h" 00041 00042 // uDisks2 integration 00043 #if defined(WITH_UDISKS) || defined(WITH_UDISKS2) 00044 #include <tqdbusdata.h> 00045 #include <tqdbusmessage.h> 00046 #include <tqdbusproxy.h> 00047 #include <tqdbusvariant.h> 00048 #include <tqdbusconnection.h> 00049 #include <tqdbuserror.h> 00050 #include <tqdbusdatamap.h> 00051 #include <tqdbusobjectpath.h> 00052 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2) 00053 #if defined(WITH_UDISKS) 00054 #include "tqdbusdatalist.h" 00055 #endif // ddefined(WITH_UDISKS) 00056 00057 #if defined(WITH_UDISKS) || defined(WITH_UDISKS2) 00058 // Defined in tdehardwaredevices.cpp 00059 TQT_DBusData convertDBUSDataToVariantData(TQT_DBusData); 00060 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2) 00061 00062 TDEStorageDevice::TDEStorageDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn), m_mediaInserted(true) { 00063 m_diskType = TDEDiskDeviceType::Null; 00064 m_diskStatus = TDEDiskDeviceStatus::Null; 00065 } 00066 00067 TDEStorageDevice::~TDEStorageDevice() { 00068 } 00069 00070 TDEDiskDeviceType::TDEDiskDeviceType TDEStorageDevice::diskType() { 00071 return m_diskType; 00072 } 00073 00074 void TDEStorageDevice::internalSetDiskType(TDEDiskDeviceType::TDEDiskDeviceType dt) { 00075 m_diskType = dt; 00076 } 00077 00078 bool TDEStorageDevice::isDiskOfType(TDEDiskDeviceType::TDEDiskDeviceType tf) { 00079 return ((m_diskType&tf)!=TDEDiskDeviceType::Null); 00080 } 00081 00082 TDEDiskDeviceStatus::TDEDiskDeviceStatus TDEStorageDevice::diskStatus() { 00083 return m_diskStatus; 00084 } 00085 00086 void TDEStorageDevice::internalSetDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus st) { 00087 m_diskStatus = st; 00088 } 00089 00090 bool TDEStorageDevice::checkDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus sf) { 00091 return ((m_diskStatus&sf)!=(TDEDiskDeviceStatus::TDEDiskDeviceStatus)0); 00092 } 00093 00094 bool TDEStorageDevice::lockDriveMedia(bool lock) { 00095 int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK); 00096 if (fd < 0) { 00097 return false; 00098 } 00099 if (ioctl(fd, CDROM_LOCKDOOR, (lock)?1:0) != 0) { 00100 close(fd); 00101 return false; 00102 } 00103 else { 00104 close(fd); 00105 return true; 00106 } 00107 } 00108 00109 bool ejectDriveUDisks(TDEStorageDevice* sdevice) { 00110 #ifdef WITH_UDISKS 00111 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00112 if (dbusConn.isConnected()) { 00113 TQString blockDeviceString = sdevice->deviceNode(); 00114 blockDeviceString.replace("/dev/", ""); 00115 blockDeviceString.replace("-", "_2d"); 00116 blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString; 00117 00118 // Eject the drive! 00119 TQT_DBusError error; 00120 TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn); 00121 if (driveControl.canSend()) { 00122 TQValueList<TQT_DBusData> params; 00123 TQT_DBusDataList options; 00124 params << TQT_DBusData::fromList(options); 00125 TQT_DBusMessage reply = driveControl.sendWithReply("DriveEject", params, &error); 00126 if (error.isValid()) { 00127 // Error! 00128 printf("[ERROR][tdehwlib] ejectDriveUDisks: %s\n", error.name().ascii()); fflush(stdout); 00129 return FALSE; 00130 } 00131 else { 00132 return TRUE; 00133 } 00134 } 00135 } 00136 #endif // WITH_UDISKS 00137 return FALSE; 00138 } 00139 00140 bool ejectDriveUDisks2(TDEStorageDevice* sdevice) { 00141 #ifdef WITH_UDISKS2 00142 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00143 if (dbusConn.isConnected()) { 00144 TQString blockDeviceString = sdevice->deviceNode(); 00145 blockDeviceString.replace("/dev/", ""); 00146 blockDeviceString.replace("-", "_2d"); 00147 blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString; 00148 TQT_DBusProxy hardwareControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.DBus.Properties", dbusConn); 00149 if (hardwareControl.canSend()) { 00150 // get associated udisks2 drive path 00151 TQT_DBusError error; 00152 TQValueList<TQT_DBusData> params; 00153 params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Block") << TQT_DBusData::fromString("Drive"); 00154 TQT_DBusMessage reply = hardwareControl.sendWithReply("Get", params, &error); 00155 if (error.isValid()) { 00156 // Error! 00157 printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00158 return FALSE; 00159 } 00160 else { 00161 if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) { 00162 TQT_DBusObjectPath driveObjectPath = reply[0].toVariant().value.toObjectPath(); 00163 if (!driveObjectPath.isValid()) { 00164 return FALSE; 00165 } 00166 00167 error = TQT_DBusError(); 00168 TQT_DBusProxy driveInformation("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.DBus.Properties", dbusConn); 00169 // can eject? 00170 TQValueList<TQT_DBusData> params; 00171 params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Drive") << TQT_DBusData::fromString("Ejectable"); 00172 TQT_DBusMessage reply = driveInformation.sendWithReply("Get", params, &error); 00173 if (error.isValid()) { 00174 // Error! 00175 printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00176 return FALSE; 00177 } 00178 if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) { 00179 bool ejectable = reply[0].toVariant().value.toBool(); 00180 if (!ejectable) { 00181 return FALSE; 00182 } 00183 00184 // Eject the drive! 00185 TQT_DBusProxy driveControl("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.UDisks2.Drive", dbusConn); 00186 TQValueList<TQT_DBusData> params; 00187 TQT_DBusDataMap<TQString> options(TQT_DBusData::Variant); 00188 params << TQT_DBusData::fromStringKeyMap(options); 00189 TQT_DBusMessage reply = driveControl.sendWithReply("Eject", params, &error); 00190 if (error.isValid()) { 00191 // Error! 00192 printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00193 return FALSE; 00194 } 00195 else { 00196 return TRUE; 00197 } 00198 } 00199 } 00200 } 00201 } 00202 } 00203 #endif // WITH_UDISKS2 00204 return FALSE; 00205 } 00206 00207 int mountDriveUDisks(TQString deviceNode, TQString fileSystemType, TQStringList mountOptions, TQString* errStr = NULL) { 00208 #ifdef WITH_UDISKS 00209 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00210 if (dbusConn.isConnected()) { 00211 TQString blockDeviceString = deviceNode; 00212 blockDeviceString.replace("/dev/", ""); 00213 blockDeviceString.replace("-", "_2d"); 00214 blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString; 00215 00216 // Mount the drive! 00217 TQT_DBusError error; 00218 TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn); 00219 if (driveControl.canSend()) { 00220 TQValueList<TQT_DBusData> params; 00221 params << TQT_DBusData::fromString(fileSystemType); 00222 params << TQT_DBusData::fromList(TQT_DBusDataList(mountOptions)); 00223 TQT_DBusMessage reply = driveControl.sendWithReply("FilesystemMount", params, &error); 00224 if (error.isValid()) { 00225 // Error! 00226 if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") { 00227 // Service not installed or unavailable 00228 return -2; 00229 } 00230 if (errStr) { 00231 *errStr = error.name() + ": " + error.message(); 00232 } 00233 else { 00234 printf("[ERROR][tdehwlib] mountDriveUDisks: %s\n", error.name().ascii()); fflush(stdout); 00235 } 00236 return -1; 00237 } 00238 else { 00239 return 0; 00240 } 00241 } 00242 else { 00243 return -2; 00244 } 00245 } 00246 #endif // WITH_UDISKS 00247 return -2; 00248 } 00249 00250 int mountDriveUDisks2(TQString deviceNode, TQString fileSystemType, TQString mountOptions, TQString* errStr = NULL) { 00251 #ifdef WITH_UDISKS2 00252 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00253 if (dbusConn.isConnected()) { 00254 TQString blockDeviceString = deviceNode; 00255 blockDeviceString.replace("/dev/", ""); 00256 blockDeviceString.replace("-", "_2d"); 00257 blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString; 00258 00259 // Mount the drive! 00260 TQT_DBusError error; 00261 TQT_DBusProxy driveControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.UDisks2.Filesystem", dbusConn); 00262 if (driveControl.canSend()) { 00263 TQValueList<TQT_DBusData> params; 00264 TQMap<TQString, TQT_DBusData> optionsMap; 00265 if (fileSystemType != "") { 00266 optionsMap["fstype"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(fileSystemType)); 00267 } 00268 optionsMap["options"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(mountOptions)); 00269 params << TQT_DBusData::fromStringKeyMap(TQT_DBusDataMap<TQString>(optionsMap)); 00270 TQT_DBusMessage reply = driveControl.sendWithReply("Mount", params, &error); 00271 if (error.isValid()) { 00272 // Error! 00273 if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") { 00274 // Service not installed or unavailable 00275 return -2; 00276 } 00277 if (errStr) { 00278 *errStr = error.name() + ": " + error.message(); 00279 } 00280 else { 00281 printf("[ERROR][tdehwlib] mountDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00282 } 00283 return -1; 00284 } 00285 else { 00286 return 0; 00287 } 00288 } 00289 else { 00290 return -2; 00291 } 00292 } 00293 #endif // WITH_UDISKS2 00294 return -2; 00295 } 00296 00297 int unMountDriveUDisks(TQString deviceNode, TQStringList unMountOptions, TQString* errStr = NULL) { 00298 #ifdef WITH_UDISKS 00299 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00300 if (dbusConn.isConnected()) { 00301 TQString blockDeviceString = deviceNode; 00302 blockDeviceString.replace("/dev/", ""); 00303 blockDeviceString.replace("-", "_2d"); 00304 blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString; 00305 00306 // Mount the drive! 00307 TQT_DBusError error; 00308 TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn); 00309 if (driveControl.canSend()) { 00310 TQValueList<TQT_DBusData> params; 00311 params << TQT_DBusData::fromList(TQT_DBusDataList(unMountOptions)); 00312 TQT_DBusMessage reply = driveControl.sendWithReply("FilesystemUnmount", params, &error); 00313 if (error.isValid()) { 00314 // Error! 00315 if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") { 00316 // Service not installed or unavailable 00317 return -2; 00318 } 00319 if (errStr) { 00320 *errStr = error.name() + ": " + error.message(); 00321 } 00322 else { 00323 printf("[ERROR][tdehwlib] unMountDriveUDisks: %s\n", error.name().ascii()); fflush(stdout); 00324 } 00325 return -1; 00326 } 00327 else { 00328 return 0; 00329 } 00330 } 00331 else { 00332 return -2; 00333 } 00334 } 00335 #endif // WITH_UDISKS 00336 return -2; 00337 } 00338 00339 int unMountDriveUDisks2(TQString deviceNode, TQString unMountOptions, TQString* errStr = NULL) { 00340 #ifdef WITH_UDISKS2 00341 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); 00342 if (dbusConn.isConnected()) { 00343 TQString blockDeviceString = deviceNode; 00344 blockDeviceString.replace("/dev/", ""); 00345 blockDeviceString.replace("-", "_2d"); 00346 blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString; 00347 00348 // Mount the drive! 00349 TQT_DBusError error; 00350 TQT_DBusProxy driveControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.UDisks2.Filesystem", dbusConn); 00351 if (driveControl.canSend()) { 00352 TQValueList<TQT_DBusData> params; 00353 TQMap<TQString, TQT_DBusData> optionsMap; 00354 optionsMap["options"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(unMountOptions)); 00355 params << TQT_DBusData::fromStringKeyMap(TQT_DBusDataMap<TQString>(optionsMap)); 00356 TQT_DBusMessage reply = driveControl.sendWithReply("Unmount", params, &error); 00357 if (error.isValid()) { 00358 // Error! 00359 if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") { 00360 // Service not installed or unavailable 00361 return -2; 00362 } 00363 if (errStr) { 00364 *errStr = error.name() + ": " + error.message(); 00365 } 00366 else { 00367 printf("[ERROR][tdehwlib] unMountDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout); 00368 } 00369 return -1; 00370 } 00371 else { 00372 return 0; 00373 } 00374 } 00375 else { 00376 return -2; 00377 } 00378 } 00379 #endif // WITH_UDISKS2 00380 return -2; 00381 } 00382 00383 bool TDEStorageDevice::ejectDrive() { 00384 #ifdef WITH_UDISKS2 00385 if (!(TDEGlobal::dirs()->findExe("udisksctl").isEmpty())) { 00386 if (ejectDriveUDisks2(this)) { 00387 return TRUE; 00388 } 00389 else { 00390 printf("[tdehwlib] Failed to eject drive '%s' via udisks2, falling back to alternate mechanism\n", deviceNode().ascii()); 00391 fflush(stdout); 00392 } 00393 } 00394 #endif // WITH_UDISKS2 00395 00396 #ifdef WITH_UDISKS 00397 if (!(TDEGlobal::dirs()->findExe("udisks").isEmpty())) { 00398 if (ejectDriveUDisks(this)) { 00399 return TRUE; 00400 } 00401 else { 00402 printf("[tdehwlib] Failed to eject drive '%s' via udisks, falling back to alternate mechanism\n", deviceNode().ascii()); 00403 fflush(stdout); 00404 } 00405 } 00406 #endif // WITH_UDISKS 00407 00408 if (!(TDEGlobal::dirs()->findExe("eject").isEmpty())) { 00409 TQString command = TQString("eject -v '%1' 2>&1").arg(deviceNode()); 00410 00411 FILE *exepipe = popen(command.ascii(), "r"); 00412 if (exepipe) { 00413 TQString eject_output; 00414 TQTextStream ts(exepipe, IO_ReadOnly); 00415 eject_output = ts.read(); 00416 int retcode = pclose(exepipe); 00417 if (retcode == 0) { 00418 return TRUE; 00419 } 00420 } 00421 printf("[tdehwlib] Failed to eject drive '%s' via 'eject' command\n", deviceNode().ascii()); 00422 fflush(stdout); 00423 } 00424 00425 return FALSE; 00426 } 00427 00428 bool TDEStorageDevice::ejectDriveMedia() { 00429 int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK); 00430 if (fd < 0) { 00431 return false; 00432 } 00433 if (ioctl(fd, CDROMEJECT) != 0) { 00434 close(fd); 00435 return false; 00436 } 00437 else { 00438 close(fd); 00439 return true; 00440 } 00441 } 00442 00443 TQString TDEStorageDevice::diskLabel() { 00444 return m_diskName; 00445 } 00446 00447 void TDEStorageDevice::internalSetDiskLabel(TQString dn) { 00448 m_diskName = dn; 00449 } 00450 00451 bool TDEStorageDevice::mediaInserted() { 00452 return m_mediaInserted; 00453 } 00454 00455 void TDEStorageDevice::internalSetMediaInserted(bool inserted) { 00456 m_mediaInserted = inserted; 00457 } 00458 00459 TQString TDEStorageDevice::fileSystemName() { 00460 return m_fileSystemName; 00461 } 00462 00463 void TDEStorageDevice::internalSetFileSystemName(TQString fn) { 00464 m_fileSystemName = fn; 00465 } 00466 00467 TQString TDEStorageDevice::fileSystemUsage() { 00468 return m_fileSystemUsage; 00469 } 00470 00471 void TDEStorageDevice::internalSetFileSystemUsage(TQString fu) { 00472 m_fileSystemUsage = fu; 00473 } 00474 00475 TQString TDEStorageDevice::diskUUID() { 00476 return m_diskUUID; 00477 } 00478 00479 void TDEStorageDevice::internalSetDiskUUID(TQString id) { 00480 m_diskUUID = id; 00481 } 00482 00483 TQStringList TDEStorageDevice::holdingDevices() { 00484 return m_holdingDevices; 00485 } 00486 00487 void TDEStorageDevice::internalSetHoldingDevices(TQStringList hd) { 00488 m_holdingDevices = hd; 00489 } 00490 00491 TQStringList TDEStorageDevice::slaveDevices() { 00492 return m_slaveDevices; 00493 } 00494 00495 void TDEStorageDevice::internalSetSlaveDevices(TQStringList sd) { 00496 m_slaveDevices = sd; 00497 } 00498 00499 TQString decodeHexEncoding(TQString str) { 00500 TQRegExp hexEncRegExp("\\\\x[0-9A-Fa-f]{1,2}"); 00501 hexEncRegExp.setMinimal(false); 00502 hexEncRegExp.setCaseSensitive(true); 00503 int s = -1; 00504 00505 while((s = hexEncRegExp.search(str, s+1))>=0){ 00506 str.replace(s, hexEncRegExp.cap(0).length(), TQChar((char)strtol(hexEncRegExp.cap(0).mid(2).ascii(), NULL, 16))); 00507 } 00508 00509 return str; 00510 } 00511 00512 TQString TDEStorageDevice::friendlyName() { 00513 // Return the actual storage device name 00514 TQString devicevendorid = vendorEncoded(); 00515 TQString devicemodelid = modelEncoded(); 00516 00517 devicevendorid = decodeHexEncoding(devicevendorid); 00518 devicemodelid = decodeHexEncoding(devicemodelid); 00519 00520 devicevendorid = devicevendorid.stripWhiteSpace(); 00521 devicemodelid = devicemodelid.stripWhiteSpace(); 00522 devicevendorid = devicevendorid.simplifyWhiteSpace(); 00523 devicemodelid = devicemodelid.simplifyWhiteSpace(); 00524 00525 TQString devicename = devicevendorid + " " + devicemodelid; 00526 00527 devicename = devicename.stripWhiteSpace(); 00528 devicename = devicename.simplifyWhiteSpace(); 00529 00530 if (devicename != "") { 00531 return devicename; 00532 } 00533 00534 if (isDiskOfType(TDEDiskDeviceType::Camera)) { 00535 return TDEGenericDevice::friendlyName(); 00536 } 00537 00538 if (isDiskOfType(TDEDiskDeviceType::Floppy)) { 00539 return friendlyDeviceType(); 00540 } 00541 00542 TQString label = diskLabel(); 00543 if (label.isNull()) { 00544 if (deviceSize() > 0) { 00545 if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { 00546 label = i18n("%1 Removable Device").arg(deviceFriendlySize()); 00547 } 00548 else { 00549 label = i18n("%1 Fixed Storage Device").arg(deviceFriendlySize()); 00550 } 00551 } 00552 } 00553 00554 if (!label.isNull()) { 00555 return label; 00556 } 00557 00558 return friendlyDeviceType(); 00559 } 00560 00561 TQString TDEStorageDevice::detailedFriendlyName() { 00562 return TQString("%1 [%2]").arg(friendlyName()).arg(deviceNode()); 00563 } 00564 00565 TQString TDEStorageDevice::friendlyDeviceType() { 00566 TQString ret = i18n("Hard Disk Drive"); 00567 00568 // Keep this in sync with TDEStorageDevice::icon(TDEIcon::StdSizes size) below 00569 if (isDiskOfType(TDEDiskDeviceType::Floppy)) { 00570 ret = i18n("Floppy Drive"); 00571 } 00572 if (isDiskOfType(TDEDiskDeviceType::Optical)) { 00573 ret = i18n("Optical Drive"); 00574 } 00575 if (isDiskOfType(TDEDiskDeviceType::CDROM)) { 00576 ret = i18n("CDROM Drive"); 00577 } 00578 if (isDiskOfType(TDEDiskDeviceType::CDRW)) { 00579 ret = i18n("CDRW Drive"); 00580 } 00581 if (isDiskOfType(TDEDiskDeviceType::DVDROM)) { 00582 ret = i18n("DVD Drive"); 00583 } 00584 if (isDiskOfType(TDEDiskDeviceType::DVDRW)) { 00585 ret = i18n("DVDRW Drive"); 00586 } 00587 if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) { 00588 ret = i18n("DVDRAM Drive"); 00589 } 00590 if (isDiskOfType(TDEDiskDeviceType::Zip)) { 00591 ret = i18n("Zip Drive"); 00592 } 00593 if (isDiskOfType(TDEDiskDeviceType::Tape)) { 00594 ret = i18n("Tape Drive"); 00595 } 00596 if (isDiskOfType(TDEDiskDeviceType::Camera)) { 00597 ret = i18n("Digital Camera"); 00598 } 00599 00600 if (isDiskOfType(TDEDiskDeviceType::HDD)) { 00601 ret = i18n("Hard Disk Drive"); 00602 if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { 00603 ret = i18n("Removable Storage"); 00604 } 00605 if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) { 00606 ret = i18n("Compact Flash"); 00607 } 00608 if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) { 00609 ret = i18n("Memory Stick"); 00610 } 00611 if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) { 00612 ret = i18n("Smart Media"); 00613 } 00614 if (isDiskOfType(TDEDiskDeviceType::SDMMC)) { 00615 ret = i18n("Secure Digital"); 00616 } 00617 } 00618 00619 if (isDiskOfType(TDEDiskDeviceType::RAM)) { 00620 ret = i18n("Random Access Memory"); 00621 } 00622 if (isDiskOfType(TDEDiskDeviceType::Loop)) { 00623 ret = i18n("Loop Device"); 00624 } 00625 00626 return ret; 00627 } 00628 00629 TQPixmap TDEStorageDevice::icon(TDEIcon::StdSizes size) { 00630 TQString mountString; 00631 if (mountPath() != TQString::null) { 00632 mountString = "-mounted"; 00633 } 00634 00635 TQPixmap ret = DesktopIcon("drive-harddisk" + mountString, size); 00636 00637 if (isDiskOfType(TDEDiskDeviceType::Floppy)) { 00638 ret = DesktopIcon("media-floppy-3_5" + mountString, size); 00639 } 00640 if (isDiskOfType(TDEDiskDeviceType::Optical)) { 00641 ret = DesktopIcon("media-optical-cdrom" + mountString, size); 00642 } 00643 if (isDiskOfType(TDEDiskDeviceType::CDROM)) { 00644 ret = DesktopIcon("media-optical-cdrom" + mountString, size); 00645 } 00646 if (isDiskOfType(TDEDiskDeviceType::CDRW)) { 00647 ret = DesktopIcon("media-optical-cdwriter" + mountString, size); 00648 } 00649 if (isDiskOfType(TDEDiskDeviceType::DVDROM)) { 00650 ret = DesktopIcon("media-optical-dvd" + mountString, size); 00651 } 00652 if (isDiskOfType(TDEDiskDeviceType::DVDRW)) { 00653 ret = DesktopIcon("media-optical-dvd" + mountString, size); 00654 } 00655 if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) { 00656 ret = DesktopIcon("media-optical-dvd" + mountString, size); 00657 } 00658 if (isDiskOfType(TDEDiskDeviceType::Zip)) { 00659 ret = DesktopIcon("media-floppy-zip" + mountString, size); 00660 } 00661 if (isDiskOfType(TDEDiskDeviceType::Tape)) { 00662 ret = DesktopIcon("media-tape" + mountString, size); 00663 } 00664 if (isDiskOfType(TDEDiskDeviceType::Camera)) { 00665 ret = DesktopIcon("camera" + TQString((mountPath() != TQString::null) ? "_mount" : "_umount"), size); 00666 } 00667 00668 if (isDiskOfType(TDEDiskDeviceType::HDD)) { 00669 ret = DesktopIcon("drive-harddisk" + mountString, size); 00670 if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { 00671 ret = DesktopIcon("media-flash-usb" + mountString, size); 00672 } 00673 if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) { 00674 ret = DesktopIcon("media-flash-compact_flash" + mountString, size); 00675 } 00676 if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) { 00677 ret = DesktopIcon("media-flash-memory_stick" + mountString, size); 00678 } 00679 if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) { 00680 ret = DesktopIcon("media-flash-smart_media" + mountString, size); 00681 } 00682 if (isDiskOfType(TDEDiskDeviceType::SDMMC)) { 00683 ret = DesktopIcon("media-flash-sd_mmc" + mountString, size); 00684 } 00685 } 00686 00687 if (isDiskOfType(TDEDiskDeviceType::RAM)) { 00688 ret = DesktopIcon("memory" + mountString, size); 00689 } 00690 if (isDiskOfType(TDEDiskDeviceType::Loop)) { 00691 ret = DesktopIcon("blockdevice" + mountString, size); 00692 } 00693 00694 return ret; 00695 } 00696 00697 unsigned long long TDEStorageDevice::deviceSize() { 00698 TQString bsnodename = systemPath(); 00699 // 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 00700 // appears to only ever report the device size in 512 byte units. This does not appear to be documented anywhere! 00701 TQString blocksize = "512"; 00702 00703 TQString dsnodename = systemPath(); 00704 dsnodename.append("/size"); 00705 TQFile dsfile( dsnodename ); 00706 TQString devicesize; 00707 if ( dsfile.open( IO_ReadOnly ) ) { 00708 TQTextStream stream( &dsfile ); 00709 devicesize = stream.readLine(); 00710 dsfile.close(); 00711 } 00712 00713 return ((unsigned long long)blocksize.toULong()*(unsigned long long)devicesize.toULong()); 00714 } 00715 00716 TQString TDEStorageDevice::deviceFriendlySize() { 00717 return TDEHardwareDevices::bytesToFriendlySizeString(deviceSize()); 00718 } 00719 00720 TQString TDEStorageDevice::mountPath() { 00721 // See if this device node is mounted 00722 // This requires parsing /proc/mounts, looking for deviceNode() 00723 00724 // The Device Mapper throws a monkey wrench into this 00725 // It likes to advertise mounts as /dev/mapper/<something>, 00726 // where <something> is listed in <system path>/dm/name 00727 00728 // First, ensure that all device information (mainly holders/slaves) is accurate 00729 TDEGlobal::hardwareDevices()->rescanDeviceInformation(this); 00730 00731 TQString dmnodename = systemPath(); 00732 dmnodename.append("/dm/name"); 00733 TQFile namefile( dmnodename ); 00734 TQString dmaltname; 00735 if ( namefile.open( IO_ReadOnly ) ) { 00736 TQTextStream stream( &namefile ); 00737 dmaltname = stream.readLine(); 00738 namefile.close(); 00739 } 00740 if (!dmaltname.isNull()) { 00741 dmaltname.prepend("/dev/mapper/"); 00742 } 00743 00744 TQStringList lines; 00745 TQFile file( "/proc/mounts" ); 00746 if ( file.open( IO_ReadOnly ) ) { 00747 TQTextStream stream( &file ); 00748 TQString line; 00749 while ( !stream.atEnd() ) { 00750 line = stream.readLine(); 00751 TQStringList mountInfo = TQStringList::split(" ", line, true); 00752 TQString testNode = *mountInfo.at(0); 00753 // Check for match 00754 if ((testNode == deviceNode()) || (testNode == dmaltname) || (testNode == ("/dev/disk/by-uuid/" + diskUUID()))) { 00755 TQString ret = *mountInfo.at(1); 00756 ret.replace("\\040", " "); 00757 return ret; 00758 } 00759 lines += line; 00760 } 00761 file.close(); 00762 } 00763 00764 // While this device is not directly mounted, it could concievably be mounted via the Device Mapper 00765 // If so, try to retrieve the mount path... 00766 TQStringList slaveDeviceList = holdingDevices(); 00767 for ( TQStringList::Iterator slavedevit = slaveDeviceList.begin(); slavedevit != slaveDeviceList.end(); ++slavedevit ) { 00768 // Try to locate this device path in the TDE device tree 00769 TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); 00770 TDEGenericDevice *hwdevice = hwdevices->findBySystemPath(*slavedevit); 00771 if ((hwdevice) && (hwdevice->type() == TDEGenericDeviceType::Disk)) { 00772 TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice); 00773 return sdevice->mountPath(); 00774 } 00775 } 00776 00777 return TQString::null; 00778 } 00779 00780 TQString TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageMountOptions mountOptions, TQString* errRet, int* retcode) { 00781 int internal_retcode; 00782 if (!retcode) { 00783 retcode = &internal_retcode; 00784 } 00785 00786 TQString ret = mountPath(); 00787 00788 // Device is already mounted 00789 if (!ret.isNull()) { 00790 return ret; 00791 } 00792 00793 TQString command; 00794 TQString devNode = deviceNode(); 00795 devNode.replace("'", "'\\''"); 00796 mediaName.replace("'", "'\\''"); 00797 00798 #if defined(WITH_UDISKS2) || defined(WITH_UDISKS) 00799 // Prepare filesystem options for mount 00800 TQStringList udisksOptions; 00801 TQString optionString; 00802 00803 if (mountOptions["ro"] == "true") { 00804 udisksOptions.append("ro"); 00805 } 00806 00807 if (mountOptions["atime"] != "true") { 00808 udisksOptions.append("noatime"); 00809 } 00810 00811 if (mountOptions["sync"] == "true") { 00812 udisksOptions.append("sync"); 00813 } 00814 00815 if( (mountOptions["filesystem"] == "fat") 00816 || (mountOptions["filesystem"] == "vfat") 00817 || (mountOptions["filesystem"] == "msdos") 00818 || (mountOptions["filesystem"] == "umsdos") 00819 ) { 00820 if (mountOptions.contains("shortname")) { 00821 udisksOptions.append(TQString("shortname=%1").arg(mountOptions["shortname"])); 00822 } 00823 } 00824 00825 if( (mountOptions["filesystem"] == "jfs")) { 00826 if (mountOptions["utf8"] == "true") { 00827 // udisks/udisks2 for now does not support option iocharset= for jfs 00828 // udisksOptions.append("iocharset=utf8"); 00829 } 00830 } 00831 00832 if( (mountOptions["filesystem"] == "ntfs-3g") ) { 00833 if (mountOptions.contains("locale")) { 00834 udisksOptions.append(TQString("locale=%1").arg(mountOptions["locale"])); 00835 } 00836 } 00837 00838 if( (mountOptions["filesystem"] == "ext3") 00839 || (mountOptions["filesystem"] == "ext4") 00840 ) { 00841 if (mountOptions.contains("journaling")) { 00842 // udisks/udisks2 for now does not support option data= for ext3/ext4 00843 // udisksOptions.append(TQString("data=%1").arg(mountOptions["journaling"])); 00844 } 00845 } 00846 00847 for (TQStringList::Iterator it = udisksOptions.begin(); it != udisksOptions.end(); ++it) { 00848 optionString.append(","); 00849 optionString.append(*it); 00850 } 00851 00852 if (!optionString.isEmpty()) { 00853 optionString.remove(0, 1); 00854 } 00855 #endif // defined(WITH_UDISKS2) || defined(WITH_UDISKS) 00856 00857 #ifdef WITH_UDISKS2 00858 if(command.isEmpty()) { 00859 // Try to use UDISKS v2 via DBUS, if available 00860 TQString errorString; 00861 TQString fileSystemType; 00862 00863 if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { 00864 fileSystemType = mountOptions["filesystem"]; 00865 } 00866 00867 int uDisks2Ret = mountDriveUDisks2(devNode, fileSystemType, optionString, &errorString); 00868 if (uDisks2Ret == 0) { 00869 // Update internal mount data 00870 TDEGlobal::hardwareDevices()->processModifiedMounts(); 00871 00872 ret = mountPath(); 00873 return ret; 00874 } 00875 else if (uDisks2Ret == -1) { 00876 if (errRet) { 00877 *errRet = errorString; 00878 } 00879 00880 // Update internal mount data 00881 TDEGlobal::hardwareDevices()->processModifiedMounts(); 00882 00883 ret = mountPath(); 00884 return ret; 00885 } 00886 else { 00887 // The UDISKS v2 DBUS service was either not available or was unusable; try another method... 00888 command = TQString::null; 00889 } 00890 } 00891 #endif // WITH_UDISKS2 00892 00893 #ifdef WITH_UDISKS 00894 if(command.isEmpty()) { 00895 // Try to use UDISKS v1 via DBUS, if available 00896 TQString errorString; 00897 TQString fileSystemType; 00898 00899 if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { 00900 fileSystemType = mountOptions["filesystem"]; 00901 } 00902 00903 int uDisksRet = mountDriveUDisks(devNode, fileSystemType, udisksOptions, &errorString); 00904 if (uDisksRet == 0) { 00905 // Update internal mount data 00906 TDEGlobal::hardwareDevices()->processModifiedMounts(); 00907 00908 ret = mountPath(); 00909 return ret; 00910 } 00911 else if (uDisksRet == -1) { 00912 if (errRet) { 00913 *errRet = errorString; 00914 } 00915 00916 // Update internal mount data 00917 TDEGlobal::hardwareDevices()->processModifiedMounts(); 00918 00919 ret = mountPath(); 00920 return ret; 00921 } 00922 else { 00923 // The UDISKS v1 DBUS service was either not available or was unusable; try another method... 00924 command = TQString::null; 00925 } 00926 } 00927 #endif // WITH_UDISKS 00928 00929 if(command.isEmpty()) { 00930 // Use 'pmount' command, if available 00931 TQString pmountProg = TDEGlobal::dirs()->findExe("pmount"); 00932 if (!pmountProg.isEmpty()) { 00933 // Create dummy password file 00934 KTempFile passwordFile(TQString::null, "tmp", 0600); 00935 passwordFile.setAutoDelete(true); 00936 00937 TQString optionString; 00938 if (mountOptions["ro"] == "true") { 00939 optionString.append(" -r"); 00940 } 00941 00942 if (mountOptions["atime"] != "true") { 00943 optionString.append(" -A"); 00944 } 00945 00946 if (mountOptions["utf8"] == "true") { 00947 optionString.append(" -c utf8"); 00948 } 00949 00950 if (mountOptions["sync"] == "true") { 00951 optionString.append(" -s"); 00952 } 00953 00954 if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { 00955 optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"])); 00956 } 00957 00958 if (mountOptions.contains("locale")) { 00959 optionString.append(TQString(" -c %1").arg(mountOptions["locale"])); 00960 } 00961 00962 TQString mountpoint; 00963 if (mountOptions.contains("mountpoint") 00964 && !mountOptions["mountpoint"].isEmpty() 00965 && (mountOptions["mountpoint"] != "/media/")) { 00966 mountpoint = mountOptions["mountpoint"]; 00967 mountpoint.replace("'", "'\\''"); 00968 } 00969 else { 00970 mountpoint = mediaName; 00971 } 00972 00973 TQString passFileName = passwordFile.name(); 00974 passFileName.replace("'", "'\\''"); 00975 00976 command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1").arg(passFileName).arg(optionString).arg(devNode).arg(mountpoint); 00977 } 00978 } 00979 00980 if(command.isEmpty()) { 00981 if (errRet) { 00982 *errRet = i18n("No supported mounting methods were detected on your system"); 00983 } 00984 return ret; 00985 } 00986 00987 FILE *exepipe = popen(command.local8Bit(), "r"); 00988 if (exepipe) { 00989 TQString mount_output; 00990 TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly); 00991 mount_output = ts->read(); 00992 delete ts; 00993 *retcode = pclose(exepipe); 00994 if (errRet) { 00995 *errRet = mount_output; 00996 } 00997 } 00998 00999 // Update internal mount data 01000 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01001 01002 ret = mountPath(); 01003 01004 return ret; 01005 } 01006 01007 TQString TDEStorageDevice::mountEncryptedDevice(TQString passphrase, TQString mediaName, TDEStorageMountOptions mountOptions, TQString* errRet, int* retcode) { 01008 int internal_retcode; 01009 if (!retcode) { 01010 retcode = &internal_retcode; 01011 } 01012 01013 TQString ret = mountPath(); 01014 01015 if (!ret.isNull()) { 01016 return ret; 01017 } 01018 01019 // Create dummy password file 01020 KTempFile passwordFile(TQString::null, "tmp", 0600); 01021 passwordFile.setAutoDelete(true); 01022 TQFile* pwFile = passwordFile.file(); 01023 if (!pwFile) { 01024 return TQString::null; 01025 } 01026 01027 pwFile->writeBlock(passphrase.ascii(), passphrase.length()); 01028 pwFile->flush(); 01029 01030 TQString optionString; 01031 if (mountOptions["ro"] == "true") { 01032 optionString.append(" -r"); 01033 } 01034 01035 if (mountOptions["atime"] != "true") { 01036 optionString.append(" -A"); 01037 } 01038 01039 if (mountOptions["utf8"] == "true") { 01040 optionString.append(" -c utf8"); 01041 } 01042 01043 if (mountOptions["sync"] == "true") { 01044 optionString.append(" -s"); 01045 } 01046 01047 if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) { 01048 optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"])); 01049 } 01050 01051 if (mountOptions.contains("locale")) { 01052 optionString.append(TQString(" -c %1").arg(mountOptions["locale"])); 01053 } 01054 01055 TQString passFileName = passwordFile.name(); 01056 TQString devNode = deviceNode(); 01057 passFileName.replace("'", "'\\''"); 01058 devNode.replace("'", "'\\''"); 01059 mediaName.replace("'", "'\\''"); 01060 TQString command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1").arg(passFileName).arg(optionString).arg(devNode).arg(mediaName); 01061 01062 FILE *exepipe = popen(command.local8Bit(), "r"); 01063 if (exepipe) { 01064 TQString mount_output; 01065 TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly); 01066 mount_output = ts->read(); 01067 delete ts; 01068 *retcode = pclose(exepipe); 01069 if (errRet) { 01070 *errRet = mount_output; 01071 } 01072 } 01073 01074 // Update internal mount data 01075 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01076 01077 ret = mountPath(); 01078 01079 return ret; 01080 } 01081 01082 bool TDEStorageDevice::unmountDevice(TQString* errRet, int* retcode) { 01083 int internal_retcode; 01084 if (!retcode) { 01085 retcode = &internal_retcode; 01086 } 01087 01088 TQString mountpoint = mountPath(); 01089 TQString devNode = deviceNode(); 01090 01091 if (mountpoint.isNull()) { 01092 return true; 01093 } 01094 01095 mountpoint.replace("'", "'\\''"); 01096 01097 TQString command; 01098 01099 #ifdef WITH_UDISKS2 01100 if(command.isEmpty()) { 01101 // Try to use UDISKS v2 via DBUS, if available 01102 TQString errorString; 01103 int unMountUDisks2Ret = unMountDriveUDisks2(devNode, TQString::null, &errorString); 01104 if (unMountUDisks2Ret == 0) { 01105 // Update internal mount data 01106 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01107 01108 return true; 01109 } 01110 else if (unMountUDisks2Ret == -1) { 01111 if (errRet) { 01112 *errRet = errorString; 01113 } 01114 01115 // Update internal mount data 01116 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01117 01118 return false; 01119 } 01120 else { 01121 // The UDISKS v2 DBUS service was either not available or was unusable; try another method... 01122 command = TQString::null; 01123 } 01124 } 01125 #endif // WITH_UDISKS2 01126 #ifdef WITH_UDISKS 01127 if(command.isEmpty()) { 01128 // Try to use UDISKS v1 via DBUS, if available 01129 TQString errorString; 01130 int unMountUDisksRet = unMountDriveUDisks(devNode, TQStringList(), &errorString); 01131 if (unMountUDisksRet == 0) { 01132 // Update internal mount data 01133 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01134 01135 return true; 01136 } 01137 else if (unMountUDisksRet == -1) { 01138 if (errRet) { 01139 *errRet = errorString; 01140 } 01141 01142 // Update internal mount data 01143 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01144 01145 return false; 01146 } 01147 else { 01148 // The UDISKS v1 DBUS service was either not available or was unusable; try another method... 01149 command = TQString::null; 01150 } 01151 } 01152 #endif // WITH_UDISKS 01153 if(command.isEmpty() && 01154 !(TDEGlobal::dirs()->findExe("pumount").isEmpty())) { 01155 command = TQString("pumount '%1' 2>&1").arg(mountpoint); 01156 } 01157 01158 if(command.isEmpty()) { 01159 if (errRet) { 01160 *errRet = i18n("No supported unmounting methods were detected on your system"); 01161 } 01162 return true; 01163 } 01164 01165 FILE *exepipe = popen(command.local8Bit(), "r"); 01166 if (exepipe) { 01167 TQString umount_output; 01168 TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly); 01169 umount_output = ts->read(); 01170 delete ts; 01171 *retcode = pclose(exepipe); 01172 if (*retcode == 0) { 01173 // Update internal mount data 01174 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01175 01176 return true; 01177 } 01178 else { 01179 if (errRet) { 01180 *errRet = umount_output; 01181 } 01182 } 01183 } 01184 01185 // Update internal mount data 01186 TDEGlobal::hardwareDevices()->processModifiedMounts(); 01187 01188 return false; 01189 } 01190 01191 TQString TDEStorageDevice::determineFileSystemType(TQString path) { 01192 TQStringList mountTable; 01193 TQString prevPath = path; 01194 dev_t prevDev = 0; 01195 int pos; 01196 struct stat directory_info; 01197 if (path.startsWith("/")) { 01198 stat(path.local8Bit(), &directory_info); 01199 prevDev = directory_info.st_dev; 01200 // Walk the directory tree up to the root, checking for any change in st_dev 01201 // If a change is found, the previous value of path is the mount point itself 01202 while (path != "/") { 01203 pos = path.findRev("/", -1, TRUE); 01204 if (pos < 0) { 01205 break; 01206 } 01207 path = path.mid(0, pos); 01208 if (path == "") { 01209 path = "/"; 01210 } 01211 stat(path.local8Bit(), &directory_info); 01212 if (directory_info.st_dev != prevDev) { 01213 break; 01214 } 01215 prevPath = path; 01216 prevDev = directory_info.st_dev; 01217 } 01218 } 01219 01220 // Read in mount table 01221 mountTable.clear(); 01222 TQFile file( "/proc/mounts" ); 01223 if ( file.open( IO_ReadOnly ) ) { 01224 TQTextStream stream( &file ); 01225 while ( !stream.atEnd() ) { 01226 mountTable.append(stream.readLine()); 01227 } 01228 file.close(); 01229 } 01230 01231 // Parse mount table 01232 TQStringList::Iterator it; 01233 for ( it = mountTable.begin(); it != mountTable.end(); ++it ) { 01234 TQStringList mountInfo = TQStringList::split(" ", (*it), true); 01235 if ((*mountInfo.at(1)) == prevPath) { 01236 return (*mountInfo.at(2)); 01237 } 01238 } 01239 01240 // Unknown file system type 01241 return TQString::null; 01242 } 01243 01244 #include "tdestoragedevice.moc"