diff --git a/CMakeLists.txt b/CMakeLists.txt index 86a89da..70e8b44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2008 by Volker Lanz -# Copyright (C) 2014-2017 by Andrius Štikonas +# Copyright (C) 2014-2019 by Andrius Štikonas # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -23,7 +23,7 @@ set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) # Dependencies set(QT_MIN_VERSION "5.10.0") -set(KF5_MIN_VERSION "5.25") +set(KF5_MIN_VERSION "5.56") set(BLKID_MIN_VERSION "2.32") # Qca-qt5 (tested with botan and ossl backends) @@ -32,7 +32,7 @@ set(BLKID_MIN_VERSION "2.32") # Qca plugin (botan or ossl) set(VERSION_MAJOR "3") -set(VERSION_MINOR "50") +set(VERSION_MINOR "80") set(VERSION_RELEASE "0") set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}) set(SOVERSION "8") diff --git a/INSTALL.md b/INSTALL.md index 6b3a278..78235de 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -3,20 +3,20 @@ Building and installing KDE Partition Manager Core Library from source ## Dependencies -* [util-linux](https://github.com/karelzak/util-linux) 2.32 +* [util-linux](https://github.com/karelzak/util-linux) 2.34 * [Qt](https://www.qt.io/) 5.10 * QCA -* Tier 2 [KDE Frameworks](https://www.kde.org/products/frameworks/) 5.25 +* Tier 2 [KDE Frameworks](https://www.kde.org/products/frameworks/) 5.56 ## Configure KPMcore is built with [cmake](https://cmake.org/). It is recommended to build out of tree: After unpacking the source, create a separate build directory and run cmake there: -``` +```bash $ tar xf kpmcore-x.y.z.tar.xz $ cd kpmcore-x.y.z $ mkdir build @@ -35,7 +35,7 @@ configure a different install path by passing `-DCMAKE_INSTALL_PREFIX=` to cmake when configuring. To change the install path after configuring and building, run -``` +```bash $ ccmake . ``` diff --git a/README.md b/README.md index 9b16d66..bf21350 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ KPMcore supports CMake as (meta-)build system and installs suitable CMake support files. Typical use of of KPMcore in a `CMakeLists.txt` looks like this: -``` +```cmake find_package( KPMcore 3.2 REQUIRED ) include_directories( ${KPMCORE_INCLUDE_DIR} ) target_link_libraries( target kpmcore ) @@ -44,7 +44,7 @@ environment variable `KPMCORE_BACKEND` names a backend, and typical initialization code will look like this (or use the class `KPMCoreInitializer` from `test/helpers.h`): -``` +```cpp #include #include @@ -76,7 +76,7 @@ result in undefined behavior. After the backend is initialized you can scan for available devices. If you only want devices from the loaded backend you can call -``` +```cpp QList devices = backend->scanDevices( excludeReadOnly ); ``` @@ -87,7 +87,7 @@ read only devices. Alternatively, you can use KPMcore device scanner -``` +```cpp #include #include #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 500b9a8..e839af2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -49,7 +49,7 @@ target_link_libraries( kpmcore PUBLIC KF5::I18n KF5::CoreAddons KF5::WidgetsAddons - KF5::Auth + KF5::AuthCore ) install(TARGETS kpmcore EXPORT KPMcoreTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/backend/corebackend.h b/src/backend/corebackend.h index 386d67f..f9bc32f 100644 --- a/src/backend/corebackend.h +++ b/src/backend/corebackend.h @@ -36,6 +36,13 @@ class PartitionTable; class QString; +enum class ScanFlag : uint8_t { + includeReadOnly = 0x1, /**< devices that are read-only according to the kernel */ + includeLoopback = 0x2, +}; +Q_DECLARE_FLAGS(ScanFlags, ScanFlag) +Q_DECLARE_OPERATORS_FOR_FLAGS(ScanFlags) + /** * Interface class for backend plugins. * @author Volker Lanz @@ -86,8 +93,7 @@ public: /** * Scan for devices in the system. - * @param excludeReadOnly when true, devices that are read-only - * according to the kernel are left out of the list. + * @param excludeReadOnly when true, are left out of the list. * When false (the default) all devices, writable or * not, including CD ROM devices, are returned. * @return a QList of pointers to Device instances. The caller is responsible @@ -95,7 +101,17 @@ public: * @note A Device object is a description of the device, not * an object to operate on. See openDevice(). */ - virtual QList scanDevices(bool excludeReadOnly = false) = 0; + [[deprecated("port to scanDevices(ScanFlags)")]] virtual QList scanDevices(bool excludeReadOnly = false) = 0; + + /** + * Scan for devices in the system. + * @param scanFlags can be used to expand the list of scanned devices. + * @return a QList of pointers to Device instances. The caller is responsible + * for deleting these objects. + * @note A Device object is a description of the device, not + * an object to operate on. See openDevice(). + */ + virtual QList scanDevices(const ScanFlags scanFlags) = 0; /** * Scan a single device in the system. diff --git a/src/core/devicescanner.cpp b/src/core/devicescanner.cpp index 7024290..bff979b 100644 --- a/src/core/devicescanner.cpp +++ b/src/core/devicescanner.cpp @@ -63,7 +63,7 @@ void DeviceScanner::scan() clear(); - const QList deviceList = CoreBackendManager::self()->backend()->scanDevices(); + const QList deviceList = CoreBackendManager::self()->backend()->scanDevices(ScanFlag::includeLoopback); for (const auto &d : deviceList) operationStack().addDevice(d); diff --git a/src/core/fstab.cpp b/src/core/fstab.cpp index 6bdc7f2..650c96f 100644 --- a/src/core/fstab.cpp +++ b/src/core/fstab.cpp @@ -19,6 +19,7 @@ #include "core/fstab.h" #include "util/externalcommand.h" +#include "util/report.h" #if defined(Q_OS_LINUX) #include @@ -228,9 +229,8 @@ static void parseFsSpec(const QString& m_fsSpec, FstabEntry::Type& m_entryType, } } -static void writeEntry(QFile& output, const FstabEntry& entry) +static void writeEntry(QTextStream& s, const FstabEntry& entry) { - QTextStream s(&output); if (entry.entryType() == FstabEntry::Type::comment) { s << entry.comment() << "\n"; return; @@ -256,32 +256,13 @@ static void writeEntry(QFile& output, const FstabEntry& entry) bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename) { - QTemporaryFile out; - out.setAutoRemove(false); + Report report(nullptr); + QByteArray fstabContents; + QTextStream out(&fstabContents); - if (!out.open()) { - qWarning() << "could not open output file " << out.fileName(); - return false; - } else { - for (const auto &e : fstabEntries) - writeEntry(out, e); + for (const auto &e : fstabEntries) + writeEntry(out, e); - out.close(); - const QString bakFilename = QStringLiteral("%1.bak").arg(filename); - ExternalCommand mvCmd(QStringLiteral("mv"), { filename, bakFilename } ); - - if ( !(mvCmd.run(-1) && mvCmd.exitCode() == 0) ) { - qWarning() << "could not backup " << filename << " to " << bakFilename; - return false; - } - - ExternalCommand mvCmd2(QStringLiteral("mv"), { out.fileName(), filename } ); - - if ( !(mvCmd2.run(-1) && mvCmd2.exitCode() == 0) ) { - qWarning() << "could not move " << out.fileName() << " to " << filename; - return false; - } - } - - return true; + ExternalCommand cmd; + return cmd.writeData(report, fstabContents, filename, 0); } diff --git a/src/core/lvmdevice.cpp b/src/core/lvmdevice.cpp index c6c05d4..64ff0f3 100644 --- a/src/core/lvmdevice.cpp +++ b/src/core/lvmdevice.cpp @@ -192,7 +192,7 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl startSector, endSector, lvPath, - PartitionTable::Flag::FlagNone, + PartitionTable::Flag::None, mountPoint, mounted); return part; diff --git a/src/core/lvmdevice.h b/src/core/lvmdevice.h index 5b6b2ac..86cea4e 100644 --- a/src/core/lvmdevice.h +++ b/src/core/lvmdevice.h @@ -45,6 +45,8 @@ class LIBKPMCORE_EXPORT LvmDevice : public VolumeManagerDevice { Q_DISABLE_COPY(LvmDevice) + friend class VolumeManagerDevice; + public: LvmDevice(const QString& name, const QString& iconName = QString()); ~LvmDevice(); @@ -57,8 +59,6 @@ public: static QVector s_DirtyPVs; static QVector s_OrphanPVs; - static void scanSystemLVM(QList& devices); - static const QStringList getVGs(); static const QStringList getLVs(const QString& vgName); @@ -103,6 +103,9 @@ public: protected: std::unique_ptr>& LVSizeMap() const; + +private: + static void scanSystemLVM(QList& devices); }; #endif diff --git a/src/core/operationrunner.h b/src/core/operationrunner.h index f91468d..d22dfe2 100644 --- a/src/core/operationrunner.h +++ b/src/core/operationrunner.h @@ -44,7 +44,7 @@ public: OperationRunner(QObject* parent, OperationStack& ostack); public: - void run(); + void run() override; qint32 numJobs() const; qint32 numOperations() const; qint32 numProgressSub() const; diff --git a/src/core/partition.h b/src/core/partition.h index 5b46afc..7b6c0f8 100644 --- a/src/core/partition.h +++ b/src/core/partition.h @@ -86,7 +86,7 @@ public: StateRestore [[deprecated("Use Partition::State::Restore")]] = Restore }; - Partition(PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem* fs, qint64 sectorStart, qint64 sectorEnd, QString partitionPath, PartitionTable::Flags availableFlags = PartitionTable::FlagNone, const QString& mountPoint = QString(), bool mounted = false, PartitionTable::Flags activeFlags = PartitionTable::FlagNone, State state = State::None); + Partition(PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem* fs, qint64 sectorStart, qint64 sectorEnd, QString partitionPath, PartitionTable::Flags availableFlags = PartitionTable::Flag::None, const QString& mountPoint = QString(), bool mounted = false, PartitionTable::Flags activeFlags = PartitionTable::Flag::None, State state = State::None); ~Partition() override; Partition(const Partition& other, PartitionNode* parent = nullptr); @@ -238,10 +238,10 @@ public: void setMounted(bool b); void setFlag(PartitionTable::Flag f) { - m_ActiveFlags |= f; + m_ActiveFlags = m_ActiveFlags.setFlag(f); } void unsetFlag(PartitionTable::Flag f) { - m_ActiveFlags &= ~f; + m_ActiveFlags = m_ActiveFlags.setFlag(f, false); } void setParent(PartitionNode* p) { m_Parent = p; diff --git a/src/core/partitiontable.cpp b/src/core/partitiontable.cpp index dd0b4be..2dee90e 100644 --- a/src/core/partitiontable.cpp +++ b/src/core/partitiontable.cpp @@ -182,39 +182,39 @@ void PartitionTable::append(Partition* partition) QString PartitionTable::flagName(Flag f) { switch (f) { - case PartitionTable::FlagBoot: + case PartitionTable::Flag::Boot: return xi18nc("@item partition flag", "boot"); - case PartitionTable::FlagRoot: + case PartitionTable::Flag::Root: return xi18nc("@item partition flag", "root"); - case PartitionTable::FlagSwap: + case PartitionTable::Flag::Swap: return xi18nc("@item partition flag", "swap"); - case PartitionTable::FlagHidden: + case PartitionTable::Flag::Hidden: return xi18nc("@item partition flag", "hidden"); - case PartitionTable::FlagRaid: + case PartitionTable::Flag::Raid: return xi18nc("@item partition flag", "raid"); - case PartitionTable::FlagLvm: + case PartitionTable::Flag::Lvm: return xi18nc("@item partition flag", "lvm"); - case PartitionTable::FlagLba: + case PartitionTable::Flag::Lba: return xi18nc("@item partition flag", "lba"); - case PartitionTable::FlagHpService: + case PartitionTable::Flag::HpService: return xi18nc("@item partition flag", "hpservice"); - case PartitionTable::FlagPalo: + case PartitionTable::Flag::Palo: return xi18nc("@item partition flag", "palo"); - case PartitionTable::FlagPrep: + case PartitionTable::Flag::Prep: return xi18nc("@item partition flag", "prep"); - case PartitionTable::FlagMsftReserved: + case PartitionTable::Flag::MsftReserved: return xi18nc("@item partition flag", "msft-reserved"); - case PartitionTable::FlagBiosGrub: + case PartitionTable::Flag::BiosGrub: return xi18nc("@item partition flag", "bios-grub"); - case PartitionTable::FlagAppleTvRecovery: + case PartitionTable::Flag::AppleTvRecovery: return xi18nc("@item partition flag", "apple-tv-recovery"); - case PartitionTable::FlagDiag: + case PartitionTable::Flag::Diag: return xi18nc("@item partition flag", "diag"); - case PartitionTable::FlagLegacyBoot: + case PartitionTable::Flag::LegacyBoot: return xi18nc("@item partition flag", "legacy-boot"); - case PartitionTable::FlagMsftData: + case PartitionTable::Flag::MsftData: return xi18nc("@item partition flag", "msft-data"); - case PartitionTable::FlagIrst: + case PartitionTable::Flag::Irst: return xi18nc("@item partition flag", "irst"); default: break; @@ -228,23 +228,23 @@ const QList PartitionTable::flagList() { QList rval; - rval.append(PartitionTable::FlagBoot); - rval.append(PartitionTable::FlagRoot); - rval.append(PartitionTable::FlagSwap); - rval.append(PartitionTable::FlagHidden); - rval.append(PartitionTable::FlagRaid); - rval.append(PartitionTable::FlagLvm); - rval.append(PartitionTable::FlagLba); - rval.append(PartitionTable::FlagHpService); - rval.append(PartitionTable::FlagPalo); - rval.append(PartitionTable::FlagPrep); - rval.append(PartitionTable::FlagMsftReserved); - rval.append(PartitionTable::FlagBiosGrub); - rval.append(PartitionTable::FlagAppleTvRecovery); - rval.append(PartitionTable::FlagDiag); - rval.append(PartitionTable::FlagLegacyBoot); - rval.append(PartitionTable::FlagMsftData); - rval.append(PartitionTable::FlagIrst); + rval.append(PartitionTable::Flag::Boot); + rval.append(PartitionTable::Flag::Root); + rval.append(PartitionTable::Flag::Swap); + rval.append(PartitionTable::Flag::Hidden); + rval.append(PartitionTable::Flag::Raid); + rval.append(PartitionTable::Flag::Lvm); + rval.append(PartitionTable::Flag::Lba); + rval.append(PartitionTable::Flag::HpService); + rval.append(PartitionTable::Flag::Palo); + rval.append(PartitionTable::Flag::Prep); + rval.append(PartitionTable::Flag::MsftReserved); + rval.append(PartitionTable::Flag::BiosGrub); + rval.append(PartitionTable::Flag::AppleTvRecovery); + rval.append(PartitionTable::Flag::Diag); + rval.append(PartitionTable::Flag::LegacyBoot); + rval.append(PartitionTable::Flag::MsftData); + rval.append(PartitionTable::Flag::Irst); return rval; } @@ -269,6 +269,20 @@ QStringList PartitionTable::flagNames(Flags flags) return rval; } +/** @param list QStringList of the flags' names + @returns flags corresponding to names +*/ +PartitionTable::Flags PartitionTable::flagsFromList(const QStringList list) +{ + Flags flags; + + for (const auto &flag : flagList()) + if (list.contains(flagName(flag))) + flags.setFlag(flag); + + return flags; +} + bool PartitionTable::getUnallocatedRange(const Device& d, PartitionNode& parent, qint64& start, qint64& end) { if (d.type() == Device::Type::Disk_Device) { diff --git a/src/core/partitiontable.h b/src/core/partitiontable.h index de5f3ef..92bed82 100644 --- a/src/core/partitiontable.h +++ b/src/core/partitiontable.h @@ -16,8 +16,7 @@ * along with this program. If not, see .* *************************************************************************/ -#if !defined(KPMCORE_PARTITIONTABLE_H) - +#ifndef KPMCORE_PARTITIONTABLE_H #define KPMCORE_PARTITIONTABLE_H #include "util/libpartitionmanagerexport.h" @@ -50,7 +49,7 @@ class LIBKPMCORE_EXPORT PartitionTable : public PartitionNode friend LIBKPMCORE_EXPORT QTextStream& operator<<(QTextStream& stream, const PartitionTable& ptable); public: - enum TableType : qint8 { + enum TableType : int8_t { unknownTableType = -1, aix, @@ -69,30 +68,47 @@ public: }; /** Partition flags */ - enum Flag : qint32 { - FlagNone = 0, - FlagBoot = 1, - FlagRoot = 2, - FlagSwap = 4, - FlagHidden = 8, - FlagRaid = 16, - FlagLvm = 32, - FlagLba = 64, - FlagHpService = 128, - FlagPalo = 256, - FlagPrep = 512, - FlagMsftReserved = 1024, - FlagBiosGrub = 2048, - FlagAppleTvRecovery = 4096, - FlagDiag = 8192, - FlagLegacyBoot = 16384, - FlagMsftData = 32768, - FlagIrst = 65536, - FlagEsp [[deprecated]] = FlagBoot + enum Flag : uint32_t { + None = 0x0, + Boot = 0x1, + Root = 0x2, + Swap = 0x4, + Hidden = 0x8, + Raid = 0x10, + Lvm = 0x20, + Lba = 0x40, + HpService = 0x80, + Palo = 0x100, + Prep = 0x200, + MsftReserved = 0x400, + BiosGrub = 0x800, + AppleTvRecovery = 0x1000, + Diag = 0x2000, + LegacyBoot = 0x4000, + MsftData = 0x8000, + Irst = 0x100000, + FlagNone [[deprecated("Use PartitionTable::Flag::None")]] = None, + FlagBoot [[deprecated("Use PartitionTable::Flag::Boot")]] = Boot, + FlagRoot [[deprecated("Use PartitionTable::Flag::Root")]] = Root, + FlagSwap [[deprecated("Use PartitionTable::Flag::Swap")]] = Swap, + FlagHidden [[deprecated("Use PartitionTable::Flag::Hidden")]] = Hidden, + FlagRaid [[deprecated("Use PartitionTable::Flag::Raid")]] = Raid, + FlagLvm [[deprecated("Use PartitionTable::Flag::Lvm")]] = Lvm, + FlagLba [[deprecated("Use PartitionTable::Flag::Lba")]] = Lba, + FlagHpService [[deprecated("Use PartitionTable::Flag::HpService")]] = HpService, + FlagPalo [[deprecated("Use PartitionTable::Flag::Palo")]] = Palo, + FlagPrep [[deprecated("Use PartitionTable::Flag::Prep")]] = Prep, + FlagMsftReserved [[deprecated("Use PartitionTable::Flag::MsftReserved")]] = MsftReserved, + FlagBiosGrub [[deprecated("Use PartitionTable::Flag::BiosGrub")]] = BiosGrub, + FlagAppleTvRecovery [[deprecated("Use PartitionTable::Flag::AppleTvRecovery")]] = AppleTvRecovery, + FlagDiag [[deprecated("Use PartitionTable::Flag::Diag")]] = Diag, + FlagLegacyBoot [[deprecated("Use PartitionTable::Flag::LegacyBoot")]] = LegacyBoot, + FlagMsftData [[deprecated("Use PartitionTable::Flag::MsftData")]] = MsftData, + FlagIrst [[deprecated("Use PartitionTable::Flag::Irst")]] = Irst, + FlagEsp [[deprecated("Use PartitionTable::Flag::Boot")]] = Boot }; Q_DECLARE_FLAGS(Flags, Flag) - Q_FLAG(Flag) public: PartitionTable(TableType type, qint64 firstUsable, qint64 lastUsable); @@ -168,6 +184,7 @@ public: static const QList flagList(); static QString flagName(Flag f); static QStringList flagNames(Flags f); + static PartitionTable::Flags flagsFromList(const QStringList list); static bool getUnallocatedRange(const Device& device, PartitionNode& parent, qint64& start, qint64& end); diff --git a/src/core/raid/softwareraid.h b/src/core/raid/softwareraid.h index 37f351a..dceb395 100644 --- a/src/core/raid/softwareraid.h +++ b/src/core/raid/softwareraid.h @@ -26,6 +26,8 @@ class LIBKPMCORE_EXPORT SoftwareRAID : public VolumeManagerDevice { Q_DISABLE_COPY(SoftwareRAID) + friend class VolumeManagerDevice; + public: enum class Status { Active, @@ -60,8 +62,6 @@ public: void setStatus(SoftwareRAID::Status status); public: - static void scanSoftwareRAID(QList& devices); - static qint32 getRaidLevel(const QString& path); static qint64 getChunkSize(const QString& path); static qint64 getTotalChunk(const QString& path); @@ -109,6 +109,8 @@ private: static bool eraseDeviceMDSuperblock(const QString& path); static bool updateConfigurationFile(const QString& path); + + static void scanSoftwareRAID(QList& devices); static QString getDetail(const QString& path); diff --git a/src/core/volumemanagerdevice.cpp b/src/core/volumemanagerdevice.cpp index aadc660..185c18f 100644 --- a/src/core/volumemanagerdevice.cpp +++ b/src/core/volumemanagerdevice.cpp @@ -20,6 +20,8 @@ #include "core/partition.h" #include "core/volumemanagerdevice.h" #include "core/volumemanagerdevice_p.h" +#include "core/lvmdevice.h" +#include "core/raid/softwareraid.h" #define d_ptr std::static_pointer_cast(d) @@ -40,6 +42,12 @@ VolumeManagerDevice::VolumeManagerDevice(std::shared_ptr& devices) +{ + SoftwareRAID::scanSoftwareRAID(devices); + LvmDevice::scanSystemLVM(devices); // LVM scanner needs all other devices, so should be last +} + QString VolumeManagerDevice::prettyDeviceNodeList() const { return deviceNodes().join(QStringLiteral(", ")); diff --git a/src/core/volumemanagerdevice.h b/src/core/volumemanagerdevice.h index 6f3aa69..c107d42 100644 --- a/src/core/volumemanagerdevice.h +++ b/src/core/volumemanagerdevice.h @@ -81,6 +81,8 @@ protected: public: + static void scanDevices(QList& devices); + /** join deviceNodes together into comma-separated list * * @return comma-separated list of deviceNodes diff --git a/src/fs/CMakeLists.txt b/src/fs/CMakeLists.txt index 93661a6..fd050b5 100644 --- a/src/fs/CMakeLists.txt +++ b/src/fs/CMakeLists.txt @@ -1,4 +1,6 @@ set(FS_SRC + fs/apfs.cpp + fs/bitlocker.cpp fs/btrfs.cpp fs/exfat.cpp fs/ext2.cpp @@ -35,6 +37,8 @@ set(FS_SRC ) set(FS_LIB_HDRS + fs/apfs.h + fs/bitlocker.h fs/btrfs.h fs/exfat.h fs/ext2.h diff --git a/src/fs/apfs.cpp b/src/fs/apfs.cpp new file mode 100644 index 0000000..984cef2 --- /dev/null +++ b/src/fs/apfs.cpp @@ -0,0 +1,30 @@ +/************************************************************************* + * Copyright (C) 2019 by Andrius Štikonas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 3 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see .* + *************************************************************************/ + +#include "fs/apfs.h" + +namespace FS +{ +FileSystem::CommandSupportType apfs::m_Move = FileSystem::cmdSupportCore; +FileSystem::CommandSupportType apfs::m_Copy = FileSystem::cmdSupportCore; +FileSystem::CommandSupportType apfs::m_Backup = FileSystem::cmdSupportCore; + +apfs::apfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : + FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Apfs) +{ +} +} diff --git a/src/fs/apfs.h b/src/fs/apfs.h new file mode 100644 index 0000000..2af3a40 --- /dev/null +++ b/src/fs/apfs.h @@ -0,0 +1,61 @@ +/************************************************************************* + * Copyright (C) 2019 by Andrius Štikonas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 3 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see .* + *************************************************************************/ + +#ifndef KPMCORE_APFS_H +#define KPMCORE_APFS_H + +#include "util/libpartitionmanagerexport.h" + +#include "fs/filesystem.h" + +#include + +class QString; + +namespace FS +{ +/** An APFS file system. + @author Andrius Štikonas + */ +class LIBKPMCORE_EXPORT apfs : public FileSystem +{ +public: + apfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); + +public: + CommandSupportType supportMove() const override { + return m_Move; + } + CommandSupportType supportCopy() const override { + return m_Copy; + } + CommandSupportType supportBackup() const override { + return m_Backup; + } + + bool supportToolFound() const override { + return true; + } + +public: + static CommandSupportType m_Move; + static CommandSupportType m_Copy; + static CommandSupportType m_Backup; +}; +} + +#endif diff --git a/src/fs/bitlocker.cpp b/src/fs/bitlocker.cpp new file mode 100644 index 0000000..15280cf --- /dev/null +++ b/src/fs/bitlocker.cpp @@ -0,0 +1,30 @@ +/************************************************************************* + * Copyright (C) 2019 by Andrius Štikonas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 3 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see .* + *************************************************************************/ + +#include "fs/bitlocker.h" + +namespace FS +{ +FileSystem::CommandSupportType bitlocker::m_Move = FileSystem::cmdSupportCore; +FileSystem::CommandSupportType bitlocker::m_Copy = FileSystem::cmdSupportCore; +FileSystem::CommandSupportType bitlocker::m_Backup = FileSystem::cmdSupportCore; + +bitlocker::bitlocker(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : + FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::BitLocker) +{ +} +} diff --git a/src/fs/bitlocker.h b/src/fs/bitlocker.h new file mode 100644 index 0000000..493eb4d --- /dev/null +++ b/src/fs/bitlocker.h @@ -0,0 +1,61 @@ +/************************************************************************* + * Copyright (C) 2019 by Andrius Štikonas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 3 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see .* + *************************************************************************/ + +#ifndef KPMCORE_BITLOCKER_H +#define KPMCORE_BITLOCKER_H + +#include "util/libpartitionmanagerexport.h" + +#include "fs/filesystem.h" + +#include + +class QString; + +namespace FS +{ +/** A Bitlocker encrypted file system. + @author Andrius Štikonas + */ +class LIBKPMCORE_EXPORT bitlocker : public FileSystem +{ +public: + bitlocker(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); + +public: + CommandSupportType supportMove() const override { + return m_Move; + } + CommandSupportType supportCopy() const override { + return m_Copy; + } + CommandSupportType supportBackup() const override { + return m_Backup; + } + + bool supportToolFound() const override { + return true; + } + +public: + static CommandSupportType m_Move; + static CommandSupportType m_Copy; + static CommandSupportType m_Backup; +}; +} + +#endif diff --git a/src/fs/filesystem.cpp b/src/fs/filesystem.cpp index 62164c4..2a3be13 100644 --- a/src/fs/filesystem.cpp +++ b/src/fs/filesystem.cpp @@ -69,8 +69,10 @@ const std::vector FileSystem::defaultColorCode = QColor( 170,120,255 ), // udf QColor( 177,82,69 ), // iso9660 QColor( 223,39,104 ), // luks2 - QColor( 204,179,255 ), // fat12 - QColor( 255,100,100 ) // linux_raid_member + QColor( 204,179,255 ), // fat12 + QColor( 255,100,100 ), // linux_raid_member + QColor( 110,20,50 ), // bitlocker + QColor( 255,155,174 ), // apfs } }; @@ -451,6 +453,8 @@ static const KLocalizedString* typeNames() kxi18nc("@item filesystem name", "luks2"), kxi18nc("@item filesystem name", "fat12"), kxi18nc("@item filesystem name", "linux_raid_member"), + kxi18nc("@item filesystem name", "BitLocker"), + kxi18nc("@item filesystem name", "apfs"), }; return s; diff --git a/src/fs/filesystem.h b/src/fs/filesystem.h index a411b24..7007d60 100644 --- a/src/fs/filesystem.h +++ b/src/fs/filesystem.h @@ -92,6 +92,8 @@ public: Luks2, Fat12, LinuxRaidMember, + BitLocker, + Apfs, __lastType }; diff --git a/src/fs/filesystemfactory.cpp b/src/fs/filesystemfactory.cpp index 6f99054..77ba066 100644 --- a/src/fs/filesystemfactory.cpp +++ b/src/fs/filesystemfactory.cpp @@ -19,6 +19,8 @@ #include "fs/filesystemfactory.h" #include "fs/filesystem.h" +#include "fs/apfs.h" +#include "fs/bitlocker.h" #include "fs/btrfs.h" #include "fs/exfat.h" #include "fs/ext2.h" @@ -62,6 +64,8 @@ void FileSystemFactory::init() qDeleteAll(m_FileSystems); m_FileSystems.clear(); + m_FileSystems.insert(FileSystem::Type::Apfs, new FS::apfs(-1, -1, -1, QString())); + m_FileSystems.insert(FileSystem::Type::BitLocker, new FS::bitlocker(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Type::Btrfs, new FS::btrfs(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Type::Exfat, new FS::exfat(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Type::Ext2, new FS::ext2(-1, -1, -1, QString())); @@ -113,37 +117,39 @@ FileSystem* FileSystemFactory::create(FileSystem::Type t, qint64 firstsector, qi FileSystem* fs = nullptr; switch (t) { - case FileSystem::Type::Btrfs: fs = new FS::btrfs(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Exfat: fs = new FS::exfat(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Ext2: fs = new FS::ext2(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Ext3: fs = new FS::ext3(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Ext4: fs = new FS::ext4(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Extended: fs = new FS::extended(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::F2fs: fs = new FS::f2fs(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Fat12: fs = new FS::fat12(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Fat16: fs = new FS::fat16(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Fat32: fs = new FS::fat32(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Hfs: fs = new FS::hfs(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::HfsPlus: fs = new FS::hfsplus(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Hpfs: fs = new FS::hpfs(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Iso9660: fs = new FS::iso9660(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Jfs: fs = new FS::jfs(firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Apfs: fs = new FS::apfs (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::BitLocker: fs = new FS::bitlocker (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Btrfs: fs = new FS::btrfs (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Exfat: fs = new FS::exfat (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Ext2: fs = new FS::ext2 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Ext3: fs = new FS::ext3 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Ext4: fs = new FS::ext4 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Extended: fs = new FS::extended (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::F2fs: fs = new FS::f2fs (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Fat12: fs = new FS::fat12 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Fat16: fs = new FS::fat16 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Fat32: fs = new FS::fat32 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Hfs: fs = new FS::hfs (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::HfsPlus: fs = new FS::hfsplus (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Hpfs: fs = new FS::hpfs (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Iso9660: fs = new FS::iso9660 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Jfs: fs = new FS::jfs (firstsector, lastsector, sectorsused, label); break; case FileSystem::Type::LinuxRaidMember: fs = new FS::linuxraidmember(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::LinuxSwap: fs = new FS::linuxswap(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Luks: fs = new FS::luks(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Luks2: fs = new FS::luks2(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Lvm2_PV: fs = new FS::lvm2_pv(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Nilfs2: fs = new FS::nilfs2(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Ntfs: fs = new FS::ntfs(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Ocfs2: fs = new FS::ocfs2(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::ReiserFS: fs = new FS::reiserfs(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Reiser4: fs = new FS::reiser4(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Udf: fs = new FS::udf(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Ufs: fs = new FS::ufs(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Unformatted: fs = new FS::unformatted(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Unknown: fs = new FS::unknown(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Xfs: fs = new FS::xfs(firstsector, lastsector, sectorsused, label); break; - case FileSystem::Type::Zfs: fs = new FS::zfs(firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::LinuxSwap: fs = new FS::linuxswap (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Luks: fs = new FS::luks (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Luks2: fs = new FS::luks2 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Lvm2_PV: fs = new FS::lvm2_pv (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Nilfs2: fs = new FS::nilfs2 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Ntfs: fs = new FS::ntfs (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Ocfs2: fs = new FS::ocfs2 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::ReiserFS: fs = new FS::reiserfs (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Reiser4: fs = new FS::reiser4 (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Udf: fs = new FS::udf (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Ufs: fs = new FS::ufs (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Unformatted: fs = new FS::unformatted (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Unknown: fs = new FS::unknown (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Xfs: fs = new FS::xfs (firstsector, lastsector, sectorsused, label); break; + case FileSystem::Type::Zfs: fs = new FS::zfs (firstsector, lastsector, sectorsused, label); break; default: break; } diff --git a/src/fs/unknown.cpp b/src/fs/unknown.cpp index 3f6e27f..173d596 100644 --- a/src/fs/unknown.cpp +++ b/src/fs/unknown.cpp @@ -19,6 +19,9 @@ namespace FS { + +FileSystem::CommandSupportType unknown::m_Move = FileSystem::cmdSupportNone; + unknown::unknown(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Unknown) { diff --git a/src/fs/unknown.h b/src/fs/unknown.h index 3d20d67..cf87ca4 100644 --- a/src/fs/unknown.h +++ b/src/fs/unknown.h @@ -15,8 +15,7 @@ * along with this program. If not, see .* *************************************************************************/ -#if !defined(KPMCORE_UNKNOWN_H) - +#ifndef KPMCORE_UNKNOWN_H #define KPMCORE_UNKNOWN_H #include "util/libpartitionmanagerexport.h" @@ -40,6 +39,12 @@ public: return true; } bool canMount(const QString & deviceNode, const QString & mountPoint) const override; + + CommandSupportType supportMove() const override { + return m_Move; + } + + static CommandSupportType m_Move; }; } diff --git a/src/gui/partresizerwidget.h b/src/gui/partresizerwidget.h index 7265ae6..929223b 100644 --- a/src/gui/partresizerwidget.h +++ b/src/gui/partresizerwidget.h @@ -142,11 +142,11 @@ protected: m_Device = &d; } - void paintEvent(QPaintEvent* event); - void resizeEvent(QResizeEvent* event); - void mousePressEvent(QMouseEvent* event); - void mouseMoveEvent(QMouseEvent* event); - void mouseReleaseEvent(QMouseEvent* event); + void paintEvent(QPaintEvent* event) override; + void resizeEvent(QResizeEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; PartWidget& partWidget() { Q_ASSERT(m_PartWidget); diff --git a/src/gui/partwidget.h b/src/gui/partwidget.h index 8275483..dde4500 100644 --- a/src/gui/partwidget.h +++ b/src/gui/partwidget.h @@ -64,8 +64,8 @@ public: void setFileSystemColorCode( const std::vector& colorCode ); protected: - void paintEvent(QPaintEvent* event); - void resizeEvent(QResizeEvent* event); + void paintEvent(QPaintEvent* event) override; + void resizeEvent(QResizeEvent* event) override; QColor activeColor(const QColor& col) const; diff --git a/src/ops/copyoperation.cpp b/src/ops/copyoperation.cpp index 08e670c..e3e9d37 100644 --- a/src/ops/copyoperation.cpp +++ b/src/ops/copyoperation.cpp @@ -267,7 +267,7 @@ Partition* CopyOperation::createCopy(const Partition& target, const Partition& s p->fileSystem().setFirstSector(p->firstSector()); p->fileSystem().setLastSector(p->lastSector()); - p->setFlags(PartitionTable::FlagNone); + p->setFlags(PartitionTable::Flag::None); return p; } diff --git a/src/ops/newoperation.cpp b/src/ops/newoperation.cpp index fb4fcce..40bdc62 100644 --- a/src/ops/newoperation.cpp +++ b/src/ops/newoperation.cpp @@ -66,7 +66,7 @@ NewOperation::NewOperation(Device& d, Partition* p) : addJob(createFileSystemJob()); if (fs.type() == FileSystem::Type::Lvm2_PV) { - m_SetPartFlagsJob = new SetPartFlagsJob(targetDevice(), newPartition(), PartitionTable::FlagLvm); + m_SetPartFlagsJob = new SetPartFlagsJob(targetDevice(), newPartition(), PartitionTable::Flag::Lvm); addJob(setPartFlagsJob()); } diff --git a/src/plugins/dummy/dummybackend.cpp b/src/plugins/dummy/dummybackend.cpp index ae6f938..cd527cb 100644 --- a/src/plugins/dummy/dummybackend.cpp +++ b/src/plugins/dummy/dummybackend.cpp @@ -46,15 +46,21 @@ void DummyBackend::initFSSupport() { } -QList DummyBackend::scanDevices(bool excludeLoop) +QList DummyBackend::scanDevices(bool excludeReadOnly) { - Q_UNUSED(excludeLoop) + Q_UNUSED(excludeReadOnly) + return scanDevices(ScanFlags()); +} + +QList DummyBackend::scanDevices(const ScanFlags scanFlags) +{ + Q_UNUSED(scanFlags) QList result; result.append(scanDevice(QStringLiteral("/dev/sda"))); emitScanProgress(QStringLiteral("/dev/sda"), 100); - return result; + return scanDevices(false); } Device* DummyBackend::scanDevice(const QString& deviceNode) diff --git a/src/plugins/dummy/dummybackend.h b/src/plugins/dummy/dummybackend.h index a9f8fb3..aa73d7f 100644 --- a/src/plugins/dummy/dummybackend.h +++ b/src/plugins/dummy/dummybackend.h @@ -45,6 +45,7 @@ public: void initFSSupport() override; QList scanDevices(bool excludeReadOnly = false) override; + QList scanDevices(const ScanFlags scanFlags) override; std::unique_ptr openDevice(const Device& d) override; std::unique_ptr openDeviceExclusive(const Device& d) override; bool closeDevice(std::unique_ptr coreDevice) override; diff --git a/src/plugins/dummy/pmdummybackendplugin.json b/src/plugins/dummy/pmdummybackendplugin.json index 93919b3..df950d4 100644 --- a/src/plugins/dummy/pmdummybackendplugin.json +++ b/src/plugins/dummy/pmdummybackendplugin.json @@ -8,6 +8,7 @@ "Name[ca@valencia]": "Volker Lanz", "Name[ca]": "Volker Lanz", "Name[cs]": "Volker Lanz", + "Name[da]": "Volker Lanz", "Name[de]": "Volker Lanz", "Name[el]": "Volker Lanz", "Name[en_GB]": "Volker Lanz", @@ -15,6 +16,7 @@ "Name[fi]": "Volker Lanz", "Name[fr]": "Volker Lanz", "Name[gl]": "Volker Lanz", + "Name[id]": "Volker Lanz", "Name[it]": "Volker Lanz", "Name[ko]": "Volker Lanz", "Name[lt]": "Volker Lanz", @@ -22,11 +24,13 @@ "Name[pl]": "Volker Lanz", "Name[pt]": "Volker Lanz", "Name[pt_BR]": "Volker Lanz", + "Name[ru]": "Volker Lanz", "Name[sk]": "Volker Lanz", "Name[sv]": "Volker Lanz", "Name[uk]": "Volker Lanz", "Name[x-test]": "xxVolker Lanzxx", - "Name[zh_CN]": "Volker Lanz" + "Name[zh_CN]": "Volker Lanz", + "Name[zh_TW]": "Volker Lanz" } ], "Category": "BackendPlugin", @@ -34,6 +38,7 @@ "Description[ca@valencia]": "Un dorsal fals del gestor de particions del KDE amb la finalitat de fer proves.", "Description[ca]": "Un dorsal fals del gestor de particions del KDE amb la finalitat de fer proves.", "Description[cs]": "Falešná podpůrná vrstva pro správce diskových oddílů KDE pro testovací účely.", + "Description[da]": "En KDE-partitionshåndtering med attrap-backend til testformål.", "Description[de]": "Ein Dummy-Backend für die KDE-Partitionsverwaltung zu Testzwecken.", "Description[el]": "Ένα εικονικό σύστημα υποστήριξης διαχειριστή κατατμήσεων του KDE για δοκιμές.", "Description[en_GB]": "A KDE Partition Manager dummy backend for testing purposes.", @@ -41,6 +46,7 @@ "Description[fi]": "KDE:n osionhallinnan valetaustaosa testaustarkoituksiin.", "Description[fr]": "Un moteur de test pour le gestionnaire de partitions de KDE pour faire des essais.", "Description[gl]": "Unha infraestrutura de probas para o xestor de particións de KDE.", + "Description[id]": "Sebuah backend dumi Pengelola Partisi KDE untuk tujuan pengujian.", "Description[it]": "Un motore fittizio del gestore delle partizioni di KDE per scopi di prova.", "Description[ko]": "테스트를 위한 KDE 파티션 관리자 더미 백엔드입니다.", "Description[lt]": "KDE skaidinių tvarkyklės netikra galinė sąsaja skirta testavimui.", @@ -52,6 +58,7 @@ "Description[uk]": "Тестовий додаток сервера Керування розділами KDE.", "Description[x-test]": "xxA KDE Partition Manager dummy backend for testing purposes.xx", "Description[zh_CN]": "测试用的 KDE 分区管理器的虚拟后端", + "Description[zh_TW]": "使用虛設後端的 KDE 磁碟分割區管理員,可用來測試。", "EnabledByDefault": true, "Icon": "preferences-plugin", "Id": "pmdummybackendplugin", @@ -60,6 +67,7 @@ "Name[ca@valencia]": "Dorsal fals del gestor de particions del KDE", "Name[ca]": "Dorsal fals del gestor de particions del KDE", "Name[cs]": "Podpůrná vrstva pro správce diskových oddílů pro KDE", + "Name[da]": "KDE-partitionshåndtering med attrap-backend", "Name[de]": "KDE-Partitionsverwaltung Dummy-Backend", "Name[el]": "KDE Εικονικό σύστημα υποστήριξης διαχειριστή κατατμήσεων", "Name[en_GB]": "KDE Partition Manager Dummy Backend", @@ -67,7 +75,7 @@ "Name[fi]": "KDE:n osionhallinnan valetaustaosa", "Name[fr]": "Moteur de test pour le gestionnaire de partitions de KDE", "Name[gl]": "Infraestrutura de probas para o xestor de particións de KDE", - "Name[id]": "Backend Tiruan Pengelola Partisi KDE", + "Name[id]": "Backend Dumi Pengelola Partisi KDE", "Name[it]": "Motore fittizio del gestore delle partizioni di KDE", "Name[ko]": "KDE 파티션 관리자 더미 백엔드", "Name[lt]": "KDE skaidinių tvarkyklės netikra galinė sąsaja", @@ -80,6 +88,7 @@ "Name[uk]": "Тестовий додаток сервера Керування розділами KDE", "Name[x-test]": "xxKDE Partition Manager Dummy Backendxx", "Name[zh_CN]": "KDE 分区管理器虚拟后端", + "Name[zh_TW]": "KDE 磁碟分割區管理員 (虛設後端)", "ServiceTypes": [ "PartitionManager/Plugin" ], diff --git a/src/plugins/sfdisk/pmsfdiskbackendplugin.json b/src/plugins/sfdisk/pmsfdiskbackendplugin.json index 4ccb803..b70aa73 100644 --- a/src/plugins/sfdisk/pmsfdiskbackendplugin.json +++ b/src/plugins/sfdisk/pmsfdiskbackendplugin.json @@ -8,6 +8,7 @@ "Name[ca@valencia]": "Andrius Štikonas", "Name[ca]": "Andrius Štikonas", "Name[cs]": "Andrius Štikonas", + "Name[da]": "Andrius Štikonas", "Name[de]": "Andrius Štikonas", "Name[el]": "Andrius Štikonas", "Name[en_GB]": "Andrius Štikonas", @@ -15,6 +16,7 @@ "Name[fi]": "Andrius Štikonas", "Name[fr]": "Andrius Štikonas", "Name[gl]": "Andrius Štikonas", + "Name[id]": "Andrius Štikonas", "Name[it]": "Andrius Štikonas", "Name[ko]": "Andrius Štikonas", "Name[lt]": "Andrius Štikonas", @@ -22,11 +24,13 @@ "Name[pl]": "Andrius Štikonas", "Name[pt]": "Andrius Štikonas", "Name[pt_BR]": "Andrius Štikonas", + "Name[ru]": "Andrius Štikonas", "Name[sk]": "Andrius Štikonas", "Name[sv]": "Andrius Štikonas", "Name[uk]": "Andrius Štikonas", "Name[x-test]": "xxAndrius Štikonasxx", - "Name[zh_CN]": "Andrius Štikonas" + "Name[zh_CN]": "Andrius Štikonas", + "Name[zh_TW]": "Andrius Štikonas" } ], "Category": "BackendPlugin", @@ -34,6 +38,7 @@ "Description[ca@valencia]": "Un dorsal «sfdisk» del gestor de particions del KDE.", "Description[ca]": "Un dorsal «sfdisk» del gestor de particions del KDE.", "Description[cs]": "Podpůrná vrstva sfdisk pro správce diskových oddílů pro KDE.", + "Description[da]": "En KDE-partitionshåndtering med sfdisk-backend.", "Description[de]": "Ein sfdisk-Backend für die KDE-Partitionsverwaltung.", "Description[el]": "Σύστημα υποστήριξης sfdisk διαχειριστή κατατμήσεων του KDE.", "Description[en_GB]": "A KDE Partition Manager sfdisk backend.", @@ -41,6 +46,7 @@ "Description[fi]": "KDE:n osionhallinnan sfdisk-taustaosa", "Description[fr]": "Moteur sfdisk pour le gestionnaire de partitions de KDE.", "Description[gl]": "Unha infraestrutura de sfdisk para o xestor de particións de KDE.", + "Description[id]": "Sebuah backend sfdisk Pengelola Partisi KDE", "Description[it]": "Un motore sfdisk del gestore delle partizioni di KDE.", "Description[ko]": "KDE 파티션 관리자 sfdisk 백엔드입니다.", "Description[lt]": "KDE skaidinių tvarkyklės sfdisk galinė sąsaja.", @@ -51,6 +57,7 @@ "Description[sv]": "Ett sfdisk bakgrundsprogram till KDE:s partitionshanterare", "Description[uk]": "Додаток sfdisk сервера Керування розділами KDE.", "Description[x-test]": "xxA KDE Partition Manager sfdisk backend.xx", + "Description[zh_TW]": "使用 sfdisk 作為後端的 KDE 磁碟分割區管理員。", "EnabledByDefault": true, "Icon": "preferences-plugin", "Id": "pmsfdiskbackendplugin", @@ -59,6 +66,7 @@ "Name[ca@valencia]": "Dorsal «sfdisk» del gestor de particions del KDE", "Name[ca]": "Dorsal «sfdisk» del gestor de particions del KDE", "Name[cs]": "Podpůrná vrstva sfdisk pro správce diskových oddílů pro KDE", + "Name[da]": "KDE-partitionshåndtering med sfdisk-backend", "Name[de]": "KDE-Partitionsverwaltung sfdisk-Backend", "Name[el]": "KDE Σύστημα υποστήριξης sfdisk διαχειριστή κατατμήσεων", "Name[en_GB]": "KDE Partition Manager sfdisk Backend", @@ -66,6 +74,7 @@ "Name[fi]": "KDE:n osionhallinnan sfdisk-taustaosa", "Name[fr]": "Moteur sfdisk pour le gestionnaire de partitions de KDE", "Name[gl]": "Infraestrutura de sfdisk para o xestor de particións de KDE", + "Name[id]": "Backend sfdisk Pengelola Partisi KDE", "Name[it]": "Motore sfdisk del gestore delle partizioni di KDE", "Name[ko]": "KDE 파티션 관리자 sfdisk 백엔드", "Name[lt]": "KDE skaidinių tvarkyklės sfdisk galinė sąsaja", @@ -76,6 +85,7 @@ "Name[sv]": "KDE:s partitionshanterare sfdisk bakgrundsprogram", "Name[uk]": "Додаток sfdisk сервера Керування розділами KDE", "Name[x-test]": "xxKDE Partition Manager sfdisk Backendxx", + "Name[zh_TW]": "KDE 磁碟分割區管理員 (sfdisk 後端)", "ServiceTypes": [ "PartitionManager/Plugin" ], diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index b544bf5..a4458cf 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -64,7 +64,14 @@ void SfdiskBackend::initFSSupport() QList SfdiskBackend::scanDevices(bool excludeReadOnly) { -// TODO: add another bool option for loopDevices + return scanDevices(excludeReadOnly ? ScanFlags() : ScanFlag::includeReadOnly); +} + +QList SfdiskBackend::scanDevices(const ScanFlags scanFlags) +{ + const bool includeReadOnly = scanFlags.testFlag(ScanFlag::includeReadOnly); + const bool includeLoopback = scanFlags.testFlag(ScanFlag::includeLoopback); + QList result; QStringList deviceNodes; @@ -82,11 +89,14 @@ QList SfdiskBackend::scanDevices(bool excludeReadOnly) const QJsonArray jsonArray = jsonObject[QLatin1String("blockdevices")].toArray(); for (const auto &deviceLine : jsonArray) { QJsonObject deviceObject = deviceLine.toObject(); - if (deviceObject[QLatin1String("type")].toString() != QLatin1String("disk")) + if (! (deviceObject[QLatin1String("type")].toString() == QLatin1String("disk") + || (includeLoopback && deviceObject[QLatin1String("type")].toString() == QLatin1String("loop")) )) + { continue; + } const QString deviceNode = deviceObject[QLatin1String("name")].toString(); - if (excludeReadOnly) { + if (!includeReadOnly) { QString deviceName = deviceNode; deviceName.remove(QStringLiteral("/dev/")); QFile f(QStringLiteral("/sys/block/%1/ro").arg(deviceName)); @@ -107,14 +117,15 @@ QList SfdiskBackend::scanDevices(bool excludeReadOnly) result.append(device); } } - - SoftwareRAID::scanSoftwareRAID(result); - LvmDevice::scanSystemLVM(result); // LVM scanner needs all other devices, so should be last + } + VolumeManagerDevice::scanDevices(result); // scan all types of VolumeManagerDevices + return result; } + /** Create a Device for the given device_node and scan it for partitions. @param deviceNode the device node (e.g. "/dev/sda") @return the created Device object. callers need to free this. @@ -151,26 +162,21 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) QRegularExpressionMatchIterator i = re.globalMatch(content); while (i.hasNext()) { - QRegularExpressionMatch reMatch = i.next(); - QString name = reMatch.captured(1); if ((QStringLiteral("/dev/md") + name) == deviceNode) { Log(Log::Level::information) << xi18nc("@info:status", "Software RAID Device found: %1", deviceNode); - d = new SoftwareRAID( QStringLiteral("md") + name, SoftwareRAID::Status::Active ); - break; } - } } if ( d == nullptr && modelCommand.run(-1) && modelCommand.exitCode() == 0 ) { QString name = modelCommand.output(); - name = name.left(name.length() - 1); + name = name.left(name.length() - 1).replace(QLatin1Char('_'), QLatin1Char(' ')); if (name.trimmed().isEmpty()) { // Get 'lsblk --output kname' in the cases where the model name is not available. @@ -218,8 +224,6 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) { QList availableDevices = scanDevices(); - LvmDevice::scanSystemLVM(availableDevices); - for (Device *device : qAsConst(availableDevices)) if (device && device->deviceNode() == deviceNode) return device; @@ -245,18 +249,19 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit const qint64 start = partitionObject[QLatin1String("start")].toVariant().toLongLong(); const qint64 size = partitionObject[QLatin1String("size")].toVariant().toLongLong(); const QString partitionType = partitionObject[QLatin1String("type")].toString(); - PartitionTable::Flags activeFlags = partitionObject[QLatin1String("bootable")].toBool() ? PartitionTable::FlagBoot : PartitionTable::FlagNone; + PartitionTable::Flags activeFlags = partitionObject[QLatin1String("bootable")].toBool() ? PartitionTable::Flag::Boot : PartitionTable::Flag::None; if (partitionType == QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B")) - activeFlags |= PartitionTable::FlagBoot; + activeFlags |= PartitionTable::Flag::Boot; else if (partitionType == QStringLiteral("21686148-6449-6E6F-744E-656564454649")) - activeFlags |= PartitionTable::FlagBiosGrub; + activeFlags |= PartitionTable::Flag::BiosGrub; FileSystem::Type type = FileSystem::Type::Unknown; type = detectFileSystem(partitionNode); PartitionRole::Roles r = PartitionRole::Primary; - if ( (d.partitionTable()->type() == PartitionTable::msdos || d.partitionTable()->type() == PartitionTable::msdos_sectorbased) && partitionType.toInt() == 5 ) { + if ( (d.partitionTable()->type() == PartitionTable::msdos || d.partitionTable()->type() == PartitionTable::msdos_sectorbased) && + ( partitionType == QStringLiteral("5") || partitionType == QStringLiteral("f") ) ) { r = PartitionRole::Extended; type = FileSystem::Type::Extended; } @@ -322,16 +327,15 @@ bool SfdiskBackend::updateDevicePartitionTable(Device &d, const QJsonObject &jso QString tableType = jsonPartitionTable[QLatin1String("label")].toString(); const PartitionTable::TableType type = PartitionTable::nameToTableType(tableType); - qint64 firstUsableSector = 0, lastUsableSector; + qint64 firstUsableSector = 0; + qint64 lastUsableSector; - if ( d.type() == Device::Type::Disk_Device ) - { + if (d.type() == Device::Type::Disk_Device) { const DiskDevice* diskDevice = static_cast(&d); lastUsableSector = diskDevice->totalSectors(); } - else if ( d.type() == Device::Type::SoftwareRAID_Device ) - { + else if (d.type() == Device::Type::SoftwareRAID_Device) { const SoftwareRAID* raidDevice = static_cast(&d); lastUsableSector = raidDevice->totalLogical() - 1; @@ -366,6 +370,7 @@ bool SfdiskBackend::updateDevicePartitionTable(Device &d, const QJsonObject &jso else maxEntries = 128; CoreBackend::setPartitionTableMaxPrimaries(*d.partitionTable(), maxEntries); + break; } default: break; @@ -454,6 +459,8 @@ FileSystem::Type SfdiskBackend::detectFileSystem(const QString& partitionPath) else if (s == QStringLiteral("udf")) rval = FileSystem::Type::Udf; else if (s == QStringLiteral("iso9660")) rval = FileSystem::Type::Iso9660; else if (s == QStringLiteral("linux_raid_member")) rval = FileSystem::Type::LinuxRaidMember; + else if (s == QStringLiteral("BitLocker")) rval = FileSystem::Type::BitLocker; + else if (s == QStringLiteral("apfs")) rval = FileSystem::Type::Apfs; else qWarning() << "unknown file system type " << s << " on " << partitionPath; } @@ -497,11 +504,11 @@ PartitionTable::Flags SfdiskBackend::availableFlags(PartitionTable::TableType ty if (type == PartitionTable::gpt) { // These are not really flags but for now keep them for compatibility // We should implement changing partition type - flags = PartitionTable::Flag::FlagBiosGrub | - PartitionTable::Flag::FlagBoot; + flags = PartitionTable::Flag::BiosGrub | + PartitionTable::Flag::Boot; } else if (type == PartitionTable::msdos || type == PartitionTable::msdos_sectorbased) - flags = PartitionTable::FlagBoot; + flags = PartitionTable::Flag::Boot; return flags; } diff --git a/src/plugins/sfdisk/sfdiskbackend.h b/src/plugins/sfdisk/sfdiskbackend.h index dcc7952..9a659c8 100644 --- a/src/plugins/sfdisk/sfdiskbackend.h +++ b/src/plugins/sfdisk/sfdiskbackend.h @@ -47,6 +47,7 @@ public: void initFSSupport() override; QList scanDevices(bool excludeReadOnly = false) override; + QList scanDevices(const ScanFlags scanFlags) override; std::unique_ptr openDevice(const Device& d) override; std::unique_ptr openDeviceExclusive(const Device& d) override; bool closeDevice(std::unique_ptr coreDevice) override; diff --git a/src/plugins/sfdisk/sfdiskpartitiontable.cpp b/src/plugins/sfdisk/sfdiskpartitiontable.cpp index 3d13efd..fa420bf 100644 --- a/src/plugins/sfdisk/sfdiskpartitiontable.cpp +++ b/src/plugins/sfdisk/sfdiskpartitiontable.cpp @@ -230,13 +230,13 @@ bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, P if (m_device->partitionTable()->type() == PartitionTable::TableType::msdos || m_device->partitionTable()->type() == PartitionTable::TableType::msdos_sectorbased) { // We only allow setting one active partition per device - if (flag == PartitionTable::Flag::FlagBoot && state == true) { + if (flag == PartitionTable::Flag::Boot && state == true) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--activate"), m_device->deviceNode(), QString::number(partition.number()) } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) return true; else return false; - } else if (flag == PartitionTable::Flag::FlagBoot && state == false) { + } else if (flag == PartitionTable::Flag::Boot && state == false) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--activate"), m_device->deviceNode(), QStringLiteral("-") } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) return true; @@ -245,7 +245,7 @@ bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, P } } - if (flag == PartitionTable::Flag::FlagBoot && state == true) { + if (flag == PartitionTable::Flag::Boot && state == true) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--part-type"), m_device->deviceNode(), QString::number(partition.number()), QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B") } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) @@ -253,10 +253,10 @@ bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, P else return false; } - if (flag == PartitionTable::Flag::FlagBoot && state == false) + if (flag == PartitionTable::Flag::Boot && state == false) setPartitionSystemType(report, partition); - if (flag == PartitionTable::Flag::FlagBiosGrub && state == true) { + if (flag == PartitionTable::Flag::BiosGrub && state == true) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--part-type"), m_device->deviceNode(), QString::number(partition.number()), QStringLiteral("21686148-6449-6E6F-744E-656564454649") } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) @@ -264,7 +264,7 @@ bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, P else return false; } - if (flag == PartitionTable::Flag::FlagBiosGrub && state == false) + if (flag == PartitionTable::Flag::BiosGrub && state == false) setPartitionSystemType(report, partition); return true; diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 34dcbb9..c761f92 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -53,7 +53,7 @@ target_link_libraries(kpmcore_externalcommand qca-qt5 Qt5::Core Qt5::DBus - KF5::Auth + KF5::AuthCore KF5::I18n ) diff --git a/src/util/capacity.h b/src/util/capacity.h index 1346080..215d822 100644 --- a/src/util/capacity.h +++ b/src/util/capacity.h @@ -36,11 +36,11 @@ class LIBKPMCORE_EXPORT Capacity { public: /** Units we can deal with */ - enum Unit : uint { Byte, KiB, MiB, GiB, TiB, PiB, EiB, ZiB, YiB }; + enum class Unit : uint8_t {Byte, KiB, MiB, GiB, TiB, PiB, EiB, ZiB, YiB }; /** Type of capacity to print */ - enum class Type { Used, Available, Total }; + enum class Type : uint8_t { Used, Available, Total }; /** Flags for printing */ - enum class Flag { NoFlags = 0, AppendUnit = 1, AppendBytes = 2 }; + enum class Flag : uint8_t { NoFlags = 0, AppendUnit = 1, AppendBytes = 2 }; Q_DECLARE_FLAGS(Flags, Flag) public: diff --git a/src/util/externalcommand.cpp b/src/util/externalcommand.cpp index 72b1b14..75a2459 100644 --- a/src/util/externalcommand.cpp +++ b/src/util/externalcommand.cpp @@ -293,6 +293,8 @@ bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer, bool ExternalCommand::write(const QByteArray& input) { + if ( qEnvironmentVariableIsSet( "KPMCORE_DEBUG" )) + qDebug() << "Command input:" << QString::fromLocal8Bit(input); d->m_Input = input; return true; } @@ -375,7 +377,7 @@ void ExternalCommand::setExitCode(int i) bool ExternalCommand::startHelper() { if (!QDBusConnection::systemBus().isConnected()) { - qWarning() << "Could not connect to DBus session bus"; + qWarning() << "Could not connect to DBus system bus"; return false; } QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); @@ -448,7 +450,7 @@ quint64 ExternalCommand::getNonce(QDBusInterface& iface) QDBusPendingCall pcall = iface.asyncCall(QStringLiteral("getNonce")); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall); QEventLoop loop; - unsigned long long rval = 0; + quint64 rval = 0; auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) { loop.exit(); @@ -456,7 +458,7 @@ quint64 ExternalCommand::getNonce(QDBusInterface& iface) if (watcher->isError()) qWarning() << watcher->error(); else { - QDBusPendingReply reply = *watcher; + QDBusPendingReply reply = *watcher; rval = reply; } }; diff --git a/src/util/externalcommand_whitelist.h b/src/util/externalcommand_whitelist.h index 12207d0..7d81719 100644 --- a/src/util/externalcommand_whitelist.h +++ b/src/util/externalcommand_whitelist.h @@ -18,10 +18,7 @@ #ifndef KPMCORE_EXTERNALCOMMAND_WHITELIST_H #define KPMCORE_EXTERNALCOMMAND_WHITELIST_H -const QString allowedCommands[] = { -// TODO try to remove these later -QStringLiteral("mv"), - +QString allowedCommands[] = { // TODO no root needed QStringLiteral("lsblk"), QStringLiteral("udevadm"), diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp index 008c4c9..7330232 100644 --- a/src/util/externalcommandhelper.cpp +++ b/src/util/externalcommandhelper.cpp @@ -102,7 +102,7 @@ quint64 ExternalCommandHelper::getNonce() @param size the number of bytes to read @return true on success */ -bool ExternalCommandHelper::readData(const QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size) +bool ExternalCommandHelper::readData(const QString& sourceDevice, QByteArray& buffer, const qint64 offset, const qint64 size) { QFile device(sourceDevice); @@ -132,7 +132,7 @@ bool ExternalCommandHelper::readData(const QString& sourceDevice, QByteArray& bu @param offset offset where to begin writing @return true on success */ -bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteArray& buffer, qint64 offset) +bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteArray& buffer, const qint64 offset) { QFile device(targetDevice); if (!device.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered)) { diff --git a/src/util/externalcommandhelper.h b/src/util/externalcommandhelper.h index 6cb14c8..508dd23 100644 --- a/src/util/externalcommandhelper.h +++ b/src/util/externalcommandhelper.h @@ -42,8 +42,8 @@ Q_SIGNALS: void quit(); public: - bool readData(const QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size); - bool writeData(const QString& targetDevice, const QByteArray& buffer, qint64 offset); + bool readData(const QString& sourceDevice, QByteArray& buffer, const qint64 offset, const qint64 size); + bool writeData(const QString& targetDevice, const QByteArray& buffer, const qint64 offset); public Q_SLOTS: ActionReply init(const QVariantMap& args); diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions index 4117d5f..8ef3251 100644 --- a/src/util/org.kde.kpmcore.externalcommand.actions +++ b/src/util/org.kde.kpmcore.externalcommand.actions @@ -6,6 +6,7 @@ Name=Start external command daemon Name[ca]=Inicia el dimoni d'ordres externes Name[ca@valencia]=Inicia el dimoni d'ordres externes Name[cs]=Spustit démona externích příkazů +Name[da]=Start ekstern kommando-dæmon Name[de]=Externen Befehlsdienst starten Name[el]=Εκκίνηση διεργασίας με εξωτερική εντολή Name[en_GB]=Start external command daemon @@ -19,15 +20,18 @@ Name[lt]=Paleisti išorinių komandų tarnybą Name[nl]=Start externe opdrachtdaemon Name[pl]=Rozpocznij usługę zewnętrznego polecenia Name[pt]=Iniciar o servidor de comandos externos +Name[pt_BR]=Iniciar comando externo do daemon Name[sk]=Spustiť externé démony príkazov Name[sv]=Starta extern kommandodemon Name[uk]=Запуск фонової служби зовнішньої команди Name[x-test]=xxStart external command daemonxx +Name[zh_TW]=啟動外部指令守護程式 Description=Administrative privileges are required to manage disks Description[ast]=Ríquense los privilexos alministrativos pa xestionar discos Description[ca]=Es requereixen privilegis d'administrador per gestionar discs Description[ca@valencia]=Es requereixen privilegis d'administrador per gestionar discs Description[cs]=Pro správu disků jsou potřeba práva administrátora +Description[da]=Der kræves administrative rettigheder for at håndtere diske Description[de]=Systemverwalterrechte sind zur Verwaltung von Festplatten erforderlich Description[el]=Απαιτούνται δικαιώματα διαχειριστή για τη διαχείριση δίσκων Description[en_GB]=Administrative privileges are required to manage disks @@ -45,5 +49,6 @@ Description[pt_BR]=São necessários privilégios administrativos para gerenciar Description[sv]=Administratörsprivilegier krävs för att hantera diskar Description[uk]=Для керування дисками потрібні права доступу адміністратора (root) Description[x-test]=xxAdministrative privileges are required to manage disksxx +Description[zh_TW]=管理硬碟需要管理員權限 Policy=auth_admin Persistence=session diff --git a/test/testexternalcommand.cpp b/test/testexternalcommand.cpp index aec3d31..a8d48f9 100644 --- a/test/testexternalcommand.cpp +++ b/test/testexternalcommand.cpp @@ -29,7 +29,7 @@ class runcmd : public QThread { public: -void run() +void run() override { ExternalCommand blkidCmd(QStringLiteral("blkid"), {}); blkidCmd.run(); @@ -41,7 +41,7 @@ void run() class runcmd2 : public QThread { public: -void run() +void run() override { ExternalCommand lsblkCmd(QStringLiteral("lsblk"), { QStringLiteral("--nodeps"), QStringLiteral("--json") }); lsblkCmd.run(); diff --git a/test/testlist.cpp b/test/testlist.cpp index 1960e00..703283b 100644 --- a/test/testlist.cpp +++ b/test/testlist.cpp @@ -86,7 +86,7 @@ int main( int argc, char **argv ) return 1; } - const auto devices = backend->scanDevices(); + const auto devices = backend->scanDevices(ScanFlag::includeLoopback); qDebug() << "Found" << devices.length() << "devices."; for (const auto pdev : devices) {