• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

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"

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.6.3
This website is maintained by Timothy Pearson.