Solid

fstabstorageaccess.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Mario Bensi <mbensi@ipsquad.net>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6
7#include "fstabstorageaccess.h"
8#include "fstabwatcher.h"
9#include <QStringList>
10#include <solid/devices/backends/fstab/fstabdevice.h>
11#include <solid/devices/backends/fstab/fstabhandling.h>
12#include <solid/devices/backends/fstab/fstabservice.h>
13
14#include <QDir>
15#include <QProcess>
16#include <QTimer>
17
18#include <errno.h>
19
20using namespace Solid::Backends::Fstab;
21
22FstabStorageAccess::FstabStorageAccess(Solid::Backends::Fstab::FstabDevice *device)
23 : QObject(device)
24 , m_fstabDevice(device)
25{
26 QStringList currentMountPoints = FstabHandling::currentMountPoints(device->device());
27 if (currentMountPoints.isEmpty()) {
28 QStringList mountPoints = FstabHandling::mountPoints(device->device());
29 m_filePath = mountPoints.isEmpty() ? QString() : mountPoints.first();
30 m_isAccessible = false;
31 } else {
32 m_filePath = currentMountPoints.first();
33 m_isAccessible = true;
34 }
35
36 const bool inUserPath =
37 m_filePath.startsWith(QLatin1String("/media/")) || m_filePath.startsWith(QLatin1String("/run/media/")) || m_filePath.startsWith(QDir::homePath());
38
39 const bool gvfsHidden = FstabHandling::options(device->device()).contains(QLatin1String("x-gvfs-hide"));
40 const bool fsIsOverlay = FstabHandling::fstype(device->device()) == QLatin1String("overlay");
41
42 m_isIgnored = gvfsHidden ||
43 // ignore overlay fs not pointing to / or seemingly mounted by user
44 (fsIsOverlay && m_filePath != QLatin1String("/") && !inUserPath);
45
46 connect(device, &FstabDevice::mtabChanged, this, &FstabStorageAccess::onMtabChanged);
47 QTimer::singleShot(0, this, SLOT(connectDBusSignals()));
48}
49
50FstabStorageAccess::~FstabStorageAccess()
51{
52}
53
54void FstabStorageAccess::connectDBusSignals()
55{
56 m_fstabDevice->registerAction(QStringLiteral("setup"), this, SLOT(slotSetupRequested()), SLOT(slotSetupDone(int, QString)));
57
58 m_fstabDevice->registerAction(QStringLiteral("teardown"), this, SLOT(slotTeardownRequested()), SLOT(slotTeardownDone(int, QString)));
59}
60
61const Solid::Backends::Fstab::FstabDevice *FstabStorageAccess::fstabDevice() const
62{
63 return m_fstabDevice;
64}
65
66bool FstabStorageAccess::isAccessible() const
67{
68 return m_isAccessible;
69}
70
71QString FstabStorageAccess::filePath() const
72{
73 return m_filePath;
74}
75
76bool FstabStorageAccess::isIgnored() const
77{
78 return m_isIgnored;
79}
80
81bool FstabStorageAccess::isEncrypted() const
82{
83 return m_fstabDevice->isEncrypted();
84}
85
86bool FstabStorageAccess::setup()
87{
88 if (filePath().isEmpty()) {
89 return false;
90 }
91 m_fstabDevice->broadcastActionRequested(QStringLiteral("setup"));
92 return FstabHandling::callSystemCommand(QStringLiteral("mount"), {filePath()}, this, [this](QProcess *process) {
93 if (process->exitCode() == 0) {
94 m_fstabDevice->broadcastActionDone(QStringLiteral("setup"), Solid::NoError, QString());
95 } else {
96 m_fstabDevice->broadcastActionDone(QStringLiteral("setup"),
97 Solid::UnauthorizedOperation,
98 QString::fromUtf8(process->readAllStandardError().trimmed()));
99 }
100 });
101}
102
103void FstabStorageAccess::slotSetupRequested()
104{
105 Q_EMIT setupRequested(m_fstabDevice->udi());
106}
107
108bool FstabStorageAccess::teardown()
109{
110 if (filePath().isEmpty()) {
111 return false;
112 }
113 m_fstabDevice->broadcastActionRequested(QStringLiteral("teardown"));
114 return FstabHandling::callSystemCommand(QStringLiteral("umount"), {filePath()}, this, [this](QProcess *process) {
115 if (process->exitCode() == 0) {
116 m_fstabDevice->broadcastActionDone(QStringLiteral("teardown"), Solid::NoError);
117 } else if (process->exitCode() == EBUSY) {
118 m_fstabDevice->broadcastActionDone(QStringLiteral("teardown"), Solid::DeviceBusy);
119 } else if (process->exitCode() == EPERM) {
120 m_fstabDevice->broadcastActionDone(QStringLiteral("teardown"),
121 Solid::UnauthorizedOperation,
122 QString::fromUtf8(process->readAllStandardError().trimmed()));
123 } else {
124 m_fstabDevice->broadcastActionDone(QStringLiteral("teardown"),
125 Solid::OperationFailed,
126 QString::fromUtf8(process->readAllStandardError().trimmed()));
127 }
128 });
129}
130
131void FstabStorageAccess::slotTeardownRequested()
132{
133 Q_EMIT teardownRequested(m_fstabDevice->udi());
134}
135
136void FstabStorageAccess::slotSetupDone(int error, const QString &errorString)
137{
138 Q_EMIT setupDone(static_cast<Solid::ErrorType>(error), errorString, m_fstabDevice->udi());
139}
140
141void FstabStorageAccess::slotTeardownDone(int error, const QString &errorString)
142{
143 Q_EMIT teardownDone(static_cast<Solid::ErrorType>(error), errorString, m_fstabDevice->udi());
144}
145
146void FstabStorageAccess::onMtabChanged(const QString &device)
147{
148 QStringList currentMountPoints = FstabHandling::currentMountPoints(device);
149 if (currentMountPoints.isEmpty()) {
150 // device umounted
151 m_filePath = FstabHandling::mountPoints(device).first();
152 if (m_isAccessible) {
153 m_isAccessible = false;
154 Q_EMIT accessibilityChanged(false, QStringLiteral(FSTAB_UDI_PREFIX "/%1").arg(device));
155 }
156 } else {
157 // device added
158 m_filePath = currentMountPoints.first();
159 if (!m_isAccessible) {
160 m_isAccessible = true;
161 Q_EMIT accessibilityChanged(true, QStringLiteral(FSTAB_UDI_PREFIX "/%1").arg(device));
162 }
163 }
164}
165
166#include "moc_fstabstorageaccess.cpp"
void broadcastActionRequested(const QString &actionName) const
Allows to broadcast that an action just got requested on a device to all the corresponding devices in...
void broadcastActionDone(const QString &actionName, int error=Solid::NoError, const QString &errorString=QString()) const
Allows to broadcast that an action just completed in a device to all the corresponding devices in oth...
void registerAction(const QString &actionName, QObject *dest, const char *requestSlot, const char *doneSlot) const
Register an action for the given device.
QString homePath()
T & first()
bool isEmpty() const const
Q_EMITQ_EMIT
QString first(qsizetype n) const const
QString fromUtf8(QByteArrayView str)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:01:48 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.