File indexing completed on 2024-06-09 04:00:37
0001 /* 0002 SPDX-FileCopyrightText: 2010 Mario Bensi <mbensi@ipsquad.net> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "fstabstorageaccess.h" 0008 #include "fstabwatcher.h" 0009 #include <QStringList> 0010 #include <solid/devices/backends/fstab/fstabdevice.h> 0011 #include <solid/devices/backends/fstab/fstabhandling.h> 0012 #include <solid/devices/backends/fstab/fstabservice.h> 0013 0014 #include <QDir> 0015 #include <QProcess> 0016 #include <QTimer> 0017 0018 #include <errno.h> 0019 0020 #define MTAB "/etc/mtab" 0021 0022 using namespace Solid::Backends::Fstab; 0023 0024 FstabStorageAccess::FstabStorageAccess(Solid::Backends::Fstab::FstabDevice *device) 0025 : QObject(device) 0026 , m_fstabDevice(device) 0027 { 0028 QStringList currentMountPoints = FstabHandling::currentMountPoints(device->device()); 0029 if (currentMountPoints.isEmpty()) { 0030 QStringList mountPoints = FstabHandling::mountPoints(device->device()); 0031 m_filePath = mountPoints.isEmpty() ? QString() : mountPoints.first(); 0032 m_isAccessible = false; 0033 } else { 0034 m_filePath = currentMountPoints.first(); 0035 m_isAccessible = true; 0036 } 0037 0038 const bool inUserPath = 0039 m_filePath.startsWith(QLatin1String("/media/")) || m_filePath.startsWith(QLatin1String("/run/media/")) || m_filePath.startsWith(QDir::homePath()); 0040 0041 const bool gvfsHidden = FstabHandling::options(device->device()).contains(QLatin1String("x-gvfs-hide")); 0042 const bool fsIsOverlay = FstabHandling::fstype(device->device()) == QLatin1String("overlay"); 0043 0044 m_isIgnored = gvfsHidden || 0045 // ignore overlay fs not pointing to / or seemingly mounted by user 0046 (fsIsOverlay && m_filePath != QLatin1String("/") && !inUserPath); 0047 0048 connect(device, SIGNAL(mtabChanged(QString)), this, SLOT(onMtabChanged(QString))); 0049 QTimer::singleShot(0, this, SLOT(connectDBusSignals())); 0050 } 0051 0052 FstabStorageAccess::~FstabStorageAccess() 0053 { 0054 } 0055 0056 void FstabStorageAccess::connectDBusSignals() 0057 { 0058 m_fstabDevice->registerAction("setup", this, SLOT(slotSetupRequested()), SLOT(slotSetupDone(int, QString))); 0059 0060 m_fstabDevice->registerAction("teardown", this, SLOT(slotTeardownRequested()), SLOT(slotTeardownDone(int, QString))); 0061 } 0062 0063 const Solid::Backends::Fstab::FstabDevice *FstabStorageAccess::fstabDevice() const 0064 { 0065 return m_fstabDevice; 0066 } 0067 0068 bool FstabStorageAccess::isAccessible() const 0069 { 0070 return m_isAccessible; 0071 } 0072 0073 QString FstabStorageAccess::filePath() const 0074 { 0075 return m_filePath; 0076 } 0077 0078 bool FstabStorageAccess::isIgnored() const 0079 { 0080 return m_isIgnored; 0081 } 0082 0083 bool FstabStorageAccess::isEncrypted() const 0084 { 0085 return m_fstabDevice->isEncrypted(); 0086 } 0087 0088 bool FstabStorageAccess::setup() 0089 { 0090 if (filePath().isEmpty()) { 0091 return false; 0092 } 0093 m_fstabDevice->broadcastActionRequested("setup"); 0094 return FstabHandling::callSystemCommand("mount", {filePath()}, this, [this](QProcess *process) { 0095 if (process->exitCode() == 0) { 0096 m_fstabDevice->broadcastActionDone("setup", Solid::NoError, QString()); 0097 } else { 0098 m_fstabDevice->broadcastActionDone("setup", Solid::UnauthorizedOperation, process->readAllStandardError().trimmed()); 0099 } 0100 }); 0101 } 0102 0103 void FstabStorageAccess::slotSetupRequested() 0104 { 0105 Q_EMIT setupRequested(m_fstabDevice->udi()); 0106 } 0107 0108 bool FstabStorageAccess::teardown() 0109 { 0110 if (filePath().isEmpty()) { 0111 return false; 0112 } 0113 m_fstabDevice->broadcastActionRequested("teardown"); 0114 return FstabHandling::callSystemCommand("umount", {filePath()}, this, [this](QProcess *process) { 0115 if (process->exitCode() == 0) { 0116 m_fstabDevice->broadcastActionDone("teardown", Solid::NoError); 0117 } else if (process->exitCode() == EBUSY) { 0118 m_fstabDevice->broadcastActionDone("teardown", Solid::DeviceBusy); 0119 } else if (process->exitCode() == EPERM) { 0120 m_fstabDevice->broadcastActionDone("teardown", Solid::UnauthorizedOperation, process->readAllStandardError().trimmed()); 0121 } else { 0122 m_fstabDevice->broadcastActionDone("teardown", Solid::OperationFailed, process->readAllStandardError().trimmed()); 0123 } 0124 }); 0125 } 0126 0127 void FstabStorageAccess::slotTeardownRequested() 0128 { 0129 Q_EMIT teardownRequested(m_fstabDevice->udi()); 0130 } 0131 0132 void FstabStorageAccess::slotSetupDone(int error, const QString &errorString) 0133 { 0134 Q_EMIT setupDone(static_cast<Solid::ErrorType>(error), errorString, m_fstabDevice->udi()); 0135 } 0136 0137 void FstabStorageAccess::slotTeardownDone(int error, const QString &errorString) 0138 { 0139 Q_EMIT teardownDone(static_cast<Solid::ErrorType>(error), errorString, m_fstabDevice->udi()); 0140 } 0141 0142 void FstabStorageAccess::onMtabChanged(const QString &device) 0143 { 0144 QStringList currentMountPoints = FstabHandling::currentMountPoints(device); 0145 if (currentMountPoints.isEmpty()) { 0146 // device umounted 0147 m_filePath = FstabHandling::mountPoints(device).first(); 0148 m_isAccessible = false; 0149 Q_EMIT accessibilityChanged(false, QString(FSTAB_UDI_PREFIX) + "/" + device); 0150 } else { 0151 // device added 0152 m_filePath = currentMountPoints.first(); 0153 m_isAccessible = true; 0154 Q_EMIT accessibilityChanged(true, QString(FSTAB_UDI_PREFIX) + "/" + device); 0155 } 0156 } 0157 0158 #include "moc_fstabstorageaccess.cpp"