diff --git a/INSTALL b/INSTALL index e1b7646..7abd18e 100644 --- a/INSTALL +++ b/INSTALL @@ -8,8 +8,8 @@ libparted: Either get it from http://www.gnu.org/software/parted/download.shtml and build it yourself or, preferably, install your distribution's packages (don't forget the dev-package). -libblkid: Part of the util-linux-ng project available at -http://userweb.kernel.org/~kzak/util-linux-ng/. +libblkid: Part of the util-linux project available at +https://github.com/karelzak/util-linux libatasmart: Available from http://0pointer.de/blog/projects/being-smart.html @@ -18,11 +18,11 @@ KDE Frameworks: The minimum required version is 5.0. 2. Configure -KDE Partition Manager is built with cmake. It is recommended to build out of tree: +KPMcore is built with cmake. It is recommended to build out of tree: After unpacking the source, create a separate build directory and run cmake there: $ tar xfj kpmcore-x.y.z.tar.bz2 -$ cd partitionmanager-x.y.z +$ cd kpmcore-x.y.z $ mkdir build $ cd build $ cmake .. diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c247027..bb5fb6b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -24,10 +24,6 @@ set(CORE_SRC ) set(CORE_LIB_HDRS - core/copysource.h - core/copysourcedevice.h - core/copytarget.h - core/copytargetdevice.h core/device.h core/devicescanner.h core/diskdevice.h diff --git a/src/core/partition.h b/src/core/partition.h index 91edd3f..31da284 100644 --- a/src/core/partition.h +++ b/src/core/partition.h @@ -213,6 +213,7 @@ public: void append(Partition* p) override { m_Children.append(p); + std::sort(m_Children.begin(), m_Children.end(), [] (const Partition *a, const Partition *b) -> bool {return a->firstSector() < b->firstSector();}); } void setDevicePath(const QString& s) { m_DevicePath = s; diff --git a/src/core/partitiontable.cpp b/src/core/partitiontable.cpp index 1c816ed..98c1d06 100644 --- a/src/core/partitiontable.cpp +++ b/src/core/partitiontable.cpp @@ -173,6 +173,7 @@ int PartitionTable::numPrimaries() const void PartitionTable::append(Partition* partition) { children().append(partition); + std::sort(children().begin(), children().end(), [] (const Partition *a, const Partition *b) -> bool {return a->firstSector() < b->firstSector();}); } /** @param f the flag to get the name for diff --git a/src/fs/CMakeLists.txt b/src/fs/CMakeLists.txt index ab0b0f9..b7ead6a 100644 --- a/src/fs/CMakeLists.txt +++ b/src/fs/CMakeLists.txt @@ -6,6 +6,7 @@ set(FS_SRC fs/ext4.cpp fs/extended.cpp fs/f2fs.cpp + fs/fat12.cpp fs/fat16.cpp fs/fat32.cpp fs/filesystem.cpp @@ -17,6 +18,7 @@ set(FS_SRC fs/jfs.cpp fs/linuxswap.cpp fs/luks.cpp + fs/luks2.cpp fs/lvm2_pv.cpp fs/nilfs2.cpp fs/ntfs.cpp @@ -39,6 +41,7 @@ set(FS_LIB_HDRS fs/ext4.h fs/extended.h fs/f2fs.h + fs/fat12.h fs/fat16.h fs/fat32.h fs/filesystem.h @@ -50,6 +53,7 @@ set(FS_LIB_HDRS fs/jfs.h fs/linuxswap.h fs/luks.h + fs/luks2.h fs/lvm2_pv.h fs/nilfs2.h fs/ntfs.h diff --git a/src/fs/fat12.cpp b/src/fs/fat12.cpp new file mode 100644 index 0000000..2bc0d5e --- /dev/null +++ b/src/fs/fat12.cpp @@ -0,0 +1,178 @@ +/************************************************************************* + * Copyright (C) 2008,2009,2011 by Volker Lanz * + * Copyright (C) 2017 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/fat12.h" + +#include "util/externalcommand.h" +#include "util/capacity.h" +#include "util/report.h" + +#include + +#include +#include +#include +#include + +#include + +namespace FS +{ +FileSystem::CommandSupportType fat12::m_GetUsed = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_GetLabel = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_SetLabel = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_Create = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_Grow = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_Shrink = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_Move = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_Check = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_Copy = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_Backup = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_UpdateUUID = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType fat12::m_GetUUID = FileSystem::cmdSupportNone; + +fat12::fat12(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t) : + FileSystem(firstsector, lastsector, sectorsused, label, t) +{ +} + +void fat12::init() +{ + m_Create = m_GetUsed = m_Check = findExternal(QStringLiteral("mkfs.fat"), {}, 1) ? cmdSupportFileSystem : cmdSupportNone; + m_GetLabel = cmdSupportCore; + m_SetLabel = findExternal(QStringLiteral("fatlabel")) ? cmdSupportFileSystem : cmdSupportNone; + m_Move = cmdSupportCore; + m_Copy = cmdSupportCore; + m_Backup = cmdSupportCore; + m_UpdateUUID = findExternal(QStringLiteral("dd")) ? cmdSupportFileSystem : cmdSupportNone; + m_GetUUID = cmdSupportCore; +} + +bool fat12::supportToolFound() const +{ + return + m_GetUsed != cmdSupportNone && + m_GetLabel != cmdSupportNone && + m_SetLabel != cmdSupportNone && + m_Create != cmdSupportNone && + m_Check != cmdSupportNone && + m_UpdateUUID != cmdSupportNone && + m_Copy != cmdSupportNone && + m_Move != cmdSupportNone && + m_Backup != cmdSupportNone && + m_GetUUID != cmdSupportNone; +} + +FileSystem::SupportTool fat12::supportToolName() const +{ + // also, dd for updating the UUID, but let's assume it's there ;-) + return SupportTool(QStringLiteral("dosfstools"), QUrl(QStringLiteral("http://www.daniel-baumann.ch/software/dosfstools/"))); +} + + +qint64 fat12::minCapacity() const +{ + return 1 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB); +} + +qint64 fat12::maxCapacity() const +{ + return 255 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB); +} + +int fat12::maxLabelLength() const +{ + return 11; +} + +QValidator* fat12::labelValidator(QObject *parent) const +{ + QRegularExpressionValidator *m_LabelValidator = new QRegularExpressionValidator(parent); + m_LabelValidator->setRegularExpression(QRegularExpression(QStringLiteral(R"(^[^\x{0000}-\x{001F}\x{007F}-\x{FFFF}*?.,;:\/\\|+=<>\[\]"]*$)"))); + return m_LabelValidator; +} + +qint64 fat12::readUsedCapacity(const QString& deviceNode) const +{ + ExternalCommand cmd(QStringLiteral("fsck.fat"), { QStringLiteral("-n"), QStringLiteral("-v"), deviceNode }); + + // Exit code 1 is returned when FAT dirty bit is set + if (cmd.run(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 1)) { + qint64 usedClusters = -1; + QRegularExpression re(QStringLiteral("files, (\\d+)/\\d+ ")); + QRegularExpressionMatch reClusters = re.match(cmd.output()); + + if (reClusters.hasMatch()) + usedClusters = reClusters.captured(1).toLongLong(); + + qint64 clusterSize = -1; + + re.setPattern(QStringLiteral("(\\d+) bytes per cluster")); + QRegularExpressionMatch reClusterSize = re.match(cmd.output()); + + if (reClusterSize.hasMatch()) + clusterSize = reClusterSize.captured(1).toLongLong(); + + if (usedClusters > -1 && clusterSize > -1) + return usedClusters * clusterSize; + } + + return -1; +} + +bool fat12::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) +{ + report.line() << xi18nc("@info:progress", "Setting label for partition %1 to %2", deviceNode, newLabel.toUpper()); + + ExternalCommand cmd(report, QStringLiteral("fatlabel"), { deviceNode, newLabel.toUpper() }); + return cmd.run(-1) && cmd.exitCode() == 0; +} + +bool fat12::check(Report& report, const QString& deviceNode) const +{ + ExternalCommand cmd(report, QStringLiteral("fsck.fat"), { QStringLiteral("-a"), QStringLiteral("-w"), QStringLiteral("-v"), deviceNode }); + return cmd.run(-1) && cmd.exitCode() == 0; +} + +bool fat12::create(Report& report, const QString& deviceNode) +{ + ExternalCommand cmd(report, QStringLiteral("mkfs.fat"), { QStringLiteral("-F12"), QStringLiteral("-I"), QStringLiteral("-v"), deviceNode }); + return cmd.run(-1) && cmd.exitCode() == 0; +} + +bool fat12::updateUUID(Report& report, const QString& deviceNode) const +{ + qint64 t = time(nullptr); + + char uuid[4]; + for (auto &u : uuid) { + u = static_cast(t & 0xff); + t >>= 8; + } + + ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=39") }); + + if (!cmd.write(QByteArray(uuid, sizeof(uuid)))) + return false; + + if (!cmd.start()) + return false; + + return cmd.waitFor(-1); +} +} diff --git a/src/fs/fat12.h b/src/fs/fat12.h new file mode 100644 index 0000000..a05dd67 --- /dev/null +++ b/src/fs/fat12.h @@ -0,0 +1,112 @@ +/************************************************************************* + * Copyright (C) 2008,2009 by Volker Lanz * + * Copyright (C) 2017 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 .* + *************************************************************************/ + +#if !defined(KPMCORE_FAT12_H) + +#define KPMCORE_FAT12_H + +#include "util/libpartitionmanagerexport.h" + +#include "fs/filesystem.h" + +#include + +class Report; + +class QString; + +namespace FS +{ +/** A fat12 file system. + @author Andrius Štikonas + */ +class LIBKPMCORE_EXPORT fat12 : public FileSystem +{ +public: + fat12(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Fat12); + +public: + void init() override; + + qint64 readUsedCapacity(const QString& deviceNode) const override; + bool check(Report& report, const QString& deviceNode) const override; + bool create(Report& report, const QString& deviceNode) override; + bool updateUUID(Report& report, const QString& deviceNode) const override; + bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; + + CommandSupportType supportGetUsed() const override { + return m_GetUsed; + } + CommandSupportType supportGetLabel() const override { + return m_GetLabel; + } + CommandSupportType supportSetLabel() const override { + return m_SetLabel; + } + CommandSupportType supportCreate() const override { + return m_Create; + } + CommandSupportType supportGrow() const override { + return m_Grow; + } + CommandSupportType supportShrink() const override { + return m_Shrink; + } + CommandSupportType supportMove() const override { + return m_Move; + } + CommandSupportType supportCheck() const override { + return m_Check; + } + CommandSupportType supportCopy() const override { + return m_Copy; + } + CommandSupportType supportBackup() const override { + return m_Backup; + } + CommandSupportType supportUpdateUUID() const override { + return m_UpdateUUID; + } + CommandSupportType supportGetUUID() const override { + return m_GetUUID; + } + + qint64 minCapacity() const override; + qint64 maxCapacity() const override; + int maxLabelLength() const override; + QValidator* labelValidator(QObject *parent) const override; + SupportTool supportToolName() const override; + bool supportToolFound() const override; + +public: + static CommandSupportType m_GetUsed; + static CommandSupportType m_GetLabel; + static CommandSupportType m_SetLabel; + static CommandSupportType m_Create; + static CommandSupportType m_Grow; + static CommandSupportType m_Shrink; + static CommandSupportType m_Move; + static CommandSupportType m_Check; + static CommandSupportType m_Copy; + static CommandSupportType m_Backup; + static CommandSupportType m_UpdateUUID; + static CommandSupportType m_GetUUID; +}; +} + +#endif diff --git a/src/fs/fat16.cpp b/src/fs/fat16.cpp index da01349..a287385 100644 --- a/src/fs/fat16.cpp +++ b/src/fs/fat16.cpp @@ -1,6 +1,6 @@ /************************************************************************* * Copyright (C) 2008,2009,2011 by Volker Lanz * - * Copyright (C) 2016 by Andrius Štikonas * + * Copyright (C) 2016-2017 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 * @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -33,21 +32,13 @@ namespace FS { -FileSystem::CommandSupportType fat16::m_GetUsed = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_GetLabel = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_SetLabel = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_Create = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_Grow = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_Shrink = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_Move = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_Check = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_Copy = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_Backup = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_UpdateUUID = FileSystem::cmdSupportNone; -FileSystem::CommandSupportType fat16::m_GetUUID = FileSystem::cmdSupportNone; +fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : + fat12(firstsector, lastsector, sectorsused, label, FileSystem::Fat16) +{ +} -fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t) : - FileSystem(firstsector, lastsector, sectorsused, label, t) +fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type) : + fat12(firstsector, lastsector, sectorsused, label, type) { } @@ -82,13 +73,6 @@ bool fat16::supportToolFound() const m_GetUUID != cmdSupportNone; } -FileSystem::SupportTool fat16::supportToolName() const -{ - // also, dd for updating the UUID, but let's assume it's there ;-) - return SupportTool(QStringLiteral("dosfstools"), QUrl(QStringLiteral("http://www.daniel-baumann.ch/software/dosfstools/"))); -} - - qint64 fat16::minCapacity() const { return 16 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB); @@ -99,60 +83,6 @@ qint64 fat16::maxCapacity() const return 4 * Capacity::unitFactor(Capacity::Byte, Capacity::GiB) - Capacity::unitFactor(Capacity::Byte, Capacity::MiB); } -int fat16::maxLabelLength() const -{ - return 11; -} - -QValidator* fat16::labelValidator(QObject *parent) const -{ - QRegularExpressionValidator *m_LabelValidator = new QRegularExpressionValidator(parent); - m_LabelValidator->setRegularExpression(QRegularExpression(QStringLiteral(R"(^[^\x{0000}-\x{001F}\x{007F}-\x{FFFF}*?.,;:\/\\|+=<>\[\]"]*$)"))); - return m_LabelValidator; -} - -qint64 fat16::readUsedCapacity(const QString& deviceNode) const -{ - ExternalCommand cmd(QStringLiteral("fsck.fat"), { QStringLiteral("-n"), QStringLiteral("-v"), deviceNode }); - - // Exit code 1 is returned when FAT dirty bit is set - if (cmd.run(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 1)) { - qint64 usedClusters = -1; - QRegularExpression re(QStringLiteral("files, (\\d+)/\\d+ ")); - QRegularExpressionMatch reClusters = re.match(cmd.output()); - - if (reClusters.hasMatch()) - usedClusters = reClusters.captured(1).toLongLong(); - - qint64 clusterSize = -1; - - re.setPattern(QStringLiteral("(\\d+) bytes per cluster")); - QRegularExpressionMatch reClusterSize = re.match(cmd.output()); - - if (reClusterSize.hasMatch()) - clusterSize = reClusterSize.captured(1).toLongLong(); - - if (usedClusters > -1 && clusterSize > -1) - return usedClusters * clusterSize; - } - - return -1; -} - -bool fat16::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) -{ - report.line() << xi18nc("@info:progress", "Setting label for partition %1 to %2", deviceNode, newLabel.toUpper()); - - ExternalCommand cmd(report, QStringLiteral("fatlabel"), { deviceNode, newLabel.toUpper() }); - return cmd.run(-1) && cmd.exitCode() == 0; -} - -bool fat16::check(Report& report, const QString& deviceNode) const -{ - ExternalCommand cmd(report, QStringLiteral("fsck.fat"), { QStringLiteral("-a"), QStringLiteral("-w"), QStringLiteral("-v"), deviceNode }); - return cmd.run(-1) && cmd.exitCode() == 0; -} - bool fat16::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.fat"), { QStringLiteral("-F16"), QStringLiteral("-I"), QStringLiteral("-v"), deviceNode }); @@ -165,24 +95,4 @@ bool fat16::resize(Report& report, const QString& deviceNode, qint64 length) con return cmd.run(-1) && cmd.exitCode() == 0; } -bool fat16::updateUUID(Report& report, const QString& deviceNode) const -{ - qint64 t = time(nullptr); - - char uuid[4]; - for (auto &u : uuid) { - u = static_cast(t & 0xff); - t >>= 8; - } - - ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=39") }); - - if (!cmd.write(QByteArray(uuid, sizeof(uuid)))) - return false; - - if (!cmd.start()) - return false; - - return cmd.waitFor(-1); -} } diff --git a/src/fs/fat16.h b/src/fs/fat16.h index c5a4f72..a654431 100644 --- a/src/fs/fat16.h +++ b/src/fs/fat16.h @@ -1,5 +1,6 @@ /************************************************************************* * Copyright (C) 2008,2009 by Volker Lanz * + * Copyright (C) 2017 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 * @@ -19,11 +20,7 @@ #define KPMCORE_FAT16_H -#include "util/libpartitionmanagerexport.h" - -#include "fs/filesystem.h" - -#include +#include "fs/fat12.h" class Report; @@ -34,78 +31,21 @@ namespace FS /** A fat16 file system. @author Volker Lanz */ -class LIBKPMCORE_EXPORT fat16 : public FileSystem +class LIBKPMCORE_EXPORT fat16 : public fat12 { public: - fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Fat16); + fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); + fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type); public: void init() override; - qint64 readUsedCapacity(const QString& deviceNode) const override; - bool check(Report& report, const QString& deviceNode) const override; bool create(Report& report, const QString& deviceNode) override; - bool updateUUID(Report& report, const QString& deviceNode) const override; - bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; - CommandSupportType supportGetUsed() const override { - return m_GetUsed; - } - CommandSupportType supportGetLabel() const override { - return m_GetLabel; - } - CommandSupportType supportSetLabel() const override { - return m_SetLabel; - } - CommandSupportType supportCreate() const override { - return m_Create; - } - CommandSupportType supportGrow() const override { - return m_Grow; - } - CommandSupportType supportShrink() const override { - return m_Shrink; - } - CommandSupportType supportMove() const override { - return m_Move; - } - CommandSupportType supportCheck() const override { - return m_Check; - } - CommandSupportType supportCopy() const override { - return m_Copy; - } - CommandSupportType supportBackup() const override { - return m_Backup; - } - CommandSupportType supportUpdateUUID() const override { - return m_UpdateUUID; - } - CommandSupportType supportGetUUID() const override { - return m_GetUUID; - } - qint64 minCapacity() const override; qint64 maxCapacity() const override; - int maxLabelLength() const override; - QValidator* labelValidator(QObject *parent) const override; - SupportTool supportToolName() const override; bool supportToolFound() const override; - -public: - static CommandSupportType m_GetUsed; - static CommandSupportType m_GetLabel; - static CommandSupportType m_SetLabel; - static CommandSupportType m_Create; - static CommandSupportType m_Grow; - static CommandSupportType m_Shrink; - static CommandSupportType m_Move; - static CommandSupportType m_Check; - static CommandSupportType m_Copy; - static CommandSupportType m_Backup; - static CommandSupportType m_UpdateUUID; - static CommandSupportType m_GetUUID; }; } diff --git a/src/fs/filesystem.cpp b/src/fs/filesystem.cpp index a3c6449..117dd26 100644 --- a/src/fs/filesystem.cpp +++ b/src/fs/filesystem.cpp @@ -40,34 +40,36 @@ const std::array< QColor, FileSystem::__lastType > FileSystem::defaultColorCode = { { - QColor( 220,205,175 ), - QColor( 187,249,207 ), - QColor( 102,121,150 ), - QColor( 122,145,180 ), - QColor( 143,170,210 ), - QColor( 155,155,130 ), - QColor( 204,179,215 ), - QColor( 229,201,240 ), - QColor( 244,214,255 ), - QColor( 216,220,135 ), - QColor( 251,255,157 ), - QColor( 200,255,254 ), - QColor( 137,200,198 ), - QColor( 210,136,142 ), - QColor( 240,165,171 ), - QColor( 151,220,134 ), - QColor( 220,205,175 ), - QColor( 173,205,255 ), - QColor( 176,155,185 ), - QColor( 170,30,77 ), - QColor( 96,140,85 ), - QColor( 33,137,108 ), - QColor( 250,230,255 ), - QColor( 242,155,104 ), - QColor( 160,210,180 ), - QColor( 255,170,0 ), - QColor( 170, 120, 255 ), - QColor( 177, 82, 69 ) + QColor( 220,205,175 ), // unknown + QColor( 187,249,207 ), // extended + QColor( 102,121,150 ), // ext2 + QColor( 122,145,180 ), // ext3 + QColor( 143,170,210 ), // ext4 + QColor( 155,155,130 ), // swap + QColor( 204,179,215 ), // fat16 + QColor( 229,201,240 ), // fat32 + QColor( 244,214,255 ), // ntfs + QColor( 216,220,135 ), // reiser + QColor( 251,255,157 ), // reiser4 + QColor( 200,255,254 ), // xfs + QColor( 137,200,198 ), // jfs + QColor( 210,136,142 ), // hfs + QColor( 240,165,171 ), // hfs+ + QColor( 151,220,134 ), // ufs + QColor( 220,205,175 ), // unformatted + QColor( 173,205,255 ), // btrfs + QColor( 176,155,185 ), // hpfs + QColor( 170,30,77 ), // luks + QColor( 96,140,85 ), // ocfs2 + QColor( 33,137,108 ), // zfs + QColor( 250,230,255 ), // exfat + QColor( 242,155,104 ), // nilfs2 + QColor( 160,210,180 ), // lvm2 pv + QColor( 255,170,0 ), // f2fs + QColor( 170,120,255 ), // udf + QColor( 177,82,69 ), // iso9660 + QColor( 223,39,104 ), // luks2 + QColor( 204,179,255 ) // fat12 } }; @@ -445,6 +447,8 @@ static const KLocalizedString* typeNames() kxi18nc("@item filesystem name", "f2fs"), kxi18nc("@item filesystem name", "udf"), kxi18nc("@item filesystem name", "iso9660"), + kxi18nc("@item filesystem name", "luks2"), + kxi18nc("@item filesystem name", "fat12") }; return s; diff --git a/src/fs/filesystem.h b/src/fs/filesystem.h index b4a7d0e..cdce228 100644 --- a/src/fs/filesystem.h +++ b/src/fs/filesystem.h @@ -87,8 +87,10 @@ public: F2fs = 25, Udf = 26, Iso9660 = 27, + Luks2 = 28, + Fat12 = 29, - __lastType = 28 + __lastType = 30 }; /** The type of support for a given FileSystem action */ diff --git a/src/fs/filesystemfactory.cpp b/src/fs/filesystemfactory.cpp index fcd1136..b17998f 100644 --- a/src/fs/filesystemfactory.cpp +++ b/src/fs/filesystemfactory.cpp @@ -26,6 +26,7 @@ #include "fs/ext4.h" #include "fs/extended.h" #include "fs/f2fs.h" +#include "fs/fat12.h" #include "fs/fat16.h" #include "fs/fat32.h" #include "fs/hfs.h" @@ -35,6 +36,7 @@ #include "fs/jfs.h" #include "fs/linuxswap.h" #include "fs/luks.h" +#include "fs/luks2.h" #include "fs/lvm2_pv.h" #include "fs/nilfs2.h" #include "fs/ntfs.h" @@ -66,6 +68,7 @@ void FileSystemFactory::init() m_FileSystems.insert(FileSystem::Ext4, new FS::ext4(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Extended, new FS::extended(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::F2fs, new FS::f2fs(-1, -1, -1, QString())); + m_FileSystems.insert(FileSystem::Fat12, new FS::fat12(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Fat16, new FS::fat16(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Fat32, new FS::fat32(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Hfs, new FS::hfs(-1, -1, -1, QString())); @@ -75,6 +78,7 @@ void FileSystemFactory::init() m_FileSystems.insert(FileSystem::Jfs, new FS::jfs(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::LinuxSwap, new FS::linuxswap(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Luks, new FS::luks(-1, -1, -1, QString())); + m_FileSystems.insert(FileSystem::Luks2, new FS::luks2(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Lvm2_PV, new FS::lvm2_pv(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Nilfs2, new FS::nilfs2(-1, -1, -1, QString())); m_FileSystems.insert(FileSystem::Ntfs, new FS::ntfs(-1, -1, -1, QString())); @@ -114,6 +118,7 @@ FileSystem* FileSystemFactory::create(FileSystem::Type t, qint64 firstsector, qi case FileSystem::Ext4: fs = new FS::ext4(firstsector, lastsector, sectorsused, label); break; case FileSystem::Extended: fs = new FS::extended(firstsector, lastsector, sectorsused, label); break; case FileSystem::F2fs: fs = new FS::f2fs(firstsector, lastsector, sectorsused, label); break; + case FileSystem::Fat12: fs = new FS::fat12(firstsector, lastsector, sectorsused, label); break; case FileSystem::Fat16: fs = new FS::fat16(firstsector, lastsector, sectorsused, label); break; case FileSystem::Fat32: fs = new FS::fat32(firstsector, lastsector, sectorsused, label); break; case FileSystem::Hfs: fs = new FS::hfs(firstsector, lastsector, sectorsused, label); break; @@ -123,6 +128,7 @@ FileSystem* FileSystemFactory::create(FileSystem::Type t, qint64 firstsector, qi case FileSystem::Jfs: fs = new FS::jfs(firstsector, lastsector, sectorsused, label); break; case FileSystem::LinuxSwap: fs = new FS::linuxswap(firstsector, lastsector, sectorsused, label); break; case FileSystem::Luks: fs = new FS::luks(firstsector, lastsector, sectorsused, label); break; + case FileSystem::Luks2: fs = new FS::luks2(firstsector, lastsector, sectorsused, label); break; case FileSystem::Lvm2_PV: fs = new FS::lvm2_pv(firstsector, lastsector, sectorsused, label); break; case FileSystem::Nilfs2: fs = new FS::nilfs2(firstsector, lastsector, sectorsused, label); break; case FileSystem::Ntfs: fs = new FS::ntfs(firstsector, lastsector, sectorsused, label); break; @@ -138,10 +144,11 @@ FileSystem* FileSystemFactory::create(FileSystem::Type t, qint64 firstsector, qi default: break; } - if (fs != nullptr) + if (fs != nullptr) { fs->setUUID(uuid); + fs->setSectorSize(sectorSize); + } - fs->setSectorSize(sectorSize); return fs; } diff --git a/src/fs/luks.cpp b/src/fs/luks.cpp index 57c309e..720ff68 100644 --- a/src/fs/luks.cpp +++ b/src/fs/luks.cpp @@ -61,8 +61,9 @@ FileSystem::CommandSupportType luks::m_GetUUID = FileSystem::cmdSupportNone; luks::luks(qint64 firstsector, qint64 lastsector, qint64 sectorsused, - const QString& label) - : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Luks) + const QString& label, + FileSystem::Type t) + : FileSystem(firstsector, lastsector, sectorsused, label, t) , m_innerFs(nullptr) , m_isCryptOpen(false) , m_cryptsetupFound(m_Create != cmdSupportNone) @@ -315,7 +316,7 @@ bool luks::cryptClose(const QString& deviceNode) m_innerFs = nullptr; m_passphrase.clear(); - setLabel({}); + setLabel(FileSystem::readLabel(deviceNode)); setUUID(readUUID(deviceNode)); setSectorsUsed(-1); @@ -468,11 +469,12 @@ QString luks::suggestedMapperName(const QString& deviceNode) const return QStringLiteral("luks-") + readOuterUUID(deviceNode); } -QString luks::readLabel(const QString&) const +QString luks::readLabel(const QString& deviceNode) const { if (m_isCryptOpen && m_innerFs) return m_innerFs->readLabel(mapperName()); - return QString(); + + return FileSystem::readLabel(deviceNode); } bool luks::writeLabel(Report& report, const QString&, const QString& newLabel) diff --git a/src/fs/luks.h b/src/fs/luks.h index 0e414a3..e7221c8 100644 --- a/src/fs/luks.h +++ b/src/fs/luks.h @@ -26,7 +26,7 @@ #include "fs/filesystem.h" #include -#include +#include class Report; @@ -40,7 +40,7 @@ namespace FS class LIBKPMCORE_EXPORT luks : public FileSystem { public: - luks(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); + luks(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Luks); ~luks() override; public: @@ -199,7 +199,7 @@ public: static CommandSupportType m_UpdateUUID; static CommandSupportType m_GetUUID; -private: +protected: mutable FileSystem* m_innerFs; mutable bool m_isCryptOpen; diff --git a/src/fs/luks2.cpp b/src/fs/luks2.cpp new file mode 100644 index 0000000..a895517 --- /dev/null +++ b/src/fs/luks2.cpp @@ -0,0 +1,39 @@ +/************************************************************************* + * Copyright (C) 2017 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/luks2.h" + +namespace FS +{ + +luks2::luks2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) + : luks(firstsector, lastsector, sectorsused, label, FileSystem::Luks2) +{ +} + +luks2::~luks2() +{ +} + +FileSystem::Type luks2::type() const +{ + if (m_isCryptOpen && m_innerFs) + return m_innerFs->type(); + return FileSystem::Luks2; +} + +} diff --git a/src/fs/luks2.h b/src/fs/luks2.h new file mode 100644 index 0000000..f8151cb --- /dev/null +++ b/src/fs/luks2.h @@ -0,0 +1,45 @@ +/************************************************************************* + * Copyright (C) 2017 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 .* + *************************************************************************/ + +#if !defined(KPMCORE_LUKS2_H) + +#define KPMCORE_LUKS2_H + +#include "util/libpartitionmanagerexport.h" + +#include "fs/luks.h" + +#include + +class QString; + +namespace FS +{ +/** A LUKS2 crypto file system. + @author Andrius Štikonas +*/ +class LIBKPMCORE_EXPORT luks2 : public luks +{ +public: + luks2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); + ~luks2() override; + + FileSystem::Type type() const override; +}; +} + +#endif diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index b0c4a2a..9849628 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -28,6 +28,7 @@ #include "fs/filesystemfactory.h" #include "fs/luks.h" +#include "fs/luks2.h" #include "util/globallog.h" #include "util/externalcommand.h" @@ -39,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -231,7 +233,7 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit QString mountPoint; bool mounted; // sfdisk does not handle LUKS partitions - if (fs->type() == FileSystem::Luks) { + if (fs->type() == FileSystem::Luks || fs->type() == FileSystem::Luks2) { r |= PartitionRole::Luks; FS::luks* luksFs = static_cast(fs); luksFs->initLUKS(); @@ -291,58 +293,66 @@ FileSystem::Type SfdiskBackend::detectFileSystem(const QString& partitionPath) { FileSystem::Type rval = FileSystem::Unknown; - ExternalCommand lsblkCommand(QStringLiteral("lsblk"), { - QStringLiteral("--json"), - QStringLiteral("--paths"), - QStringLiteral("--output=name,fstype"), + ExternalCommand udevCommand(QStringLiteral("udevadm"), { + QStringLiteral("info"), + QStringLiteral("--query=property"), partitionPath }); - if (lsblkCommand.run(-1) && lsblkCommand.exitCode() == 0) { - const QJsonArray partitionArray = QJsonDocument::fromJson(lsblkCommand.rawOutput()).object()[QLatin1String("blockdevices")].toArray(); + if (udevCommand.run(-1) && udevCommand.exitCode() == 0) { + QRegularExpression re(QStringLiteral("ID_FS_TYPE=(\\w+)")); + QRegularExpression re2(QStringLiteral("ID_FS_VERSION=(\\w+)")); + QRegularExpressionMatch reFileSystemType = re.match(udevCommand.output()); + QRegularExpressionMatch reFileSystemVersion = re2.match(udevCommand.output()); - for (const auto &partition : partitionArray) { - QJsonObject partitionObject = partition.toObject(); - QString node = partitionObject[QLatin1String("name")].toString(); - - QString s = partitionObject[QLatin1String("fstype")].toString(); - - if (s == QStringLiteral("ext2")) rval = FileSystem::Ext2; - else if (s == QStringLiteral("ext3")) rval = FileSystem::Ext3; - else if (s.startsWith(QStringLiteral("ext4"))) rval = FileSystem::Ext4; - else if (s == QStringLiteral("swap")) rval = FileSystem::LinuxSwap; - else if (s == QStringLiteral("ntfs-3g")) rval = FileSystem::Ntfs; - else if (s == QStringLiteral("reiserfs")) rval = FileSystem::ReiserFS; - else if (s == QStringLiteral("reiser4")) rval = FileSystem::Reiser4; - else if (s == QStringLiteral("xfs")) rval = FileSystem::Xfs; - else if (s == QStringLiteral("jfs")) rval = FileSystem::Jfs; - else if (s == QStringLiteral("hfs")) rval = FileSystem::Hfs; - else if (s == QStringLiteral("hfsplus")) rval = FileSystem::HfsPlus; - else if (s == QStringLiteral("ufs")) rval = FileSystem::Ufs; - else if (s == QStringLiteral("vfat")) { - ExternalCommand blkidCommand(QStringLiteral("blkid"), { - QStringLiteral("--output=value"), - QStringLiteral("--match-tag"), - QStringLiteral("SEC_TYPE"), - partitionPath }); - // blkid uses SEC_TYPE to distinguish between FAT16 and FAT32 - if (blkidCommand.run(-1) && blkidCommand.exitCode() == 0 && blkidCommand.output().trimmed() == QStringLiteral("msdos")) - rval = FileSystem::Fat16; - else - rval = FileSystem::Fat32; - } else if (s == QStringLiteral("btrfs")) rval = FileSystem::Btrfs; - else if (s == QStringLiteral("ocfs2")) rval = FileSystem::Ocfs2; - else if (s == QStringLiteral("zfs_member")) rval = FileSystem::Zfs; - else if (s == QStringLiteral("hpfs")) rval = FileSystem::Hpfs; - else if (s == QStringLiteral("crypto_LUKS")) rval = FileSystem::Luks; - else if (s == QStringLiteral("exfat")) rval = FileSystem::Exfat; - else if (s == QStringLiteral("nilfs2")) rval = FileSystem::Nilfs2; - else if (s == QStringLiteral("LVM2_member")) rval = FileSystem::Lvm2_PV; - else if (s == QStringLiteral("f2fs")) rval = FileSystem::F2fs; - else if (s == QStringLiteral("udf")) rval = FileSystem::Udf; - else if (s == QStringLiteral("iso9660")) rval = FileSystem::Iso9660; - else - qWarning() << "lsblk: unknown file system type " << s << " on " << partitionPath; + QString s; + if (reFileSystemType.hasMatch()) { + s = reFileSystemType.captured(1); } + + QString version; + if (reFileSystemVersion.hasMatch()) { + version = reFileSystemVersion.captured(1); + } + + if (s == QStringLiteral("ext2")) rval = FileSystem::Ext2; + else if (s == QStringLiteral("ext3")) rval = FileSystem::Ext3; + else if (s.startsWith(QStringLiteral("ext4"))) rval = FileSystem::Ext4; + else if (s == QStringLiteral("swap")) rval = FileSystem::LinuxSwap; + else if (s == QStringLiteral("ntfs-3g")) rval = FileSystem::Ntfs; + else if (s == QStringLiteral("reiserfs")) rval = FileSystem::ReiserFS; + else if (s == QStringLiteral("reiser4")) rval = FileSystem::Reiser4; + else if (s == QStringLiteral("xfs")) rval = FileSystem::Xfs; + else if (s == QStringLiteral("jfs")) rval = FileSystem::Jfs; + else if (s == QStringLiteral("hfs")) rval = FileSystem::Hfs; + else if (s == QStringLiteral("hfsplus")) rval = FileSystem::HfsPlus; + else if (s == QStringLiteral("ufs")) rval = FileSystem::Ufs; + else if (s == QStringLiteral("vfat")) { + if (version == QStringLiteral("FAT32")) + rval = FileSystem::Fat32; + else if (version == QStringLiteral("FAT16")) + rval = FileSystem::Fat16; + else if (version == QStringLiteral("FAT12")) + rval = FileSystem::Fat12; + } + else if (s == QStringLiteral("btrfs")) rval = FileSystem::Btrfs; + else if (s == QStringLiteral("ocfs2")) rval = FileSystem::Ocfs2; + else if (s == QStringLiteral("zfs_member")) rval = FileSystem::Zfs; + else if (s == QStringLiteral("hpfs")) rval = FileSystem::Hpfs; + else if (s == QStringLiteral("crypto_LUKS")) { + if (version == QStringLiteral("1")) + rval = FileSystem::Luks; + else if (version == QStringLiteral("2")) { + rval = FileSystem::Luks2; + } + } + else if (s == QStringLiteral("exfat")) rval = FileSystem::Exfat; + else if (s == QStringLiteral("nilfs2")) rval = FileSystem::Nilfs2; + else if (s == QStringLiteral("LVM2_member")) rval = FileSystem::Lvm2_PV; + else if (s == QStringLiteral("f2fs")) rval = FileSystem::F2fs; + else if (s == QStringLiteral("udf")) rval = FileSystem::Udf; + else if (s == QStringLiteral("iso9660")) rval = FileSystem::Iso9660; + else + qWarning() << "unknown file system type " << s << " on " << partitionPath; } return rval; diff --git a/src/plugins/sfdisk/sfdiskpartitiontable.cpp b/src/plugins/sfdisk/sfdiskpartitiontable.cpp index 9e06bff..de7f482 100644 --- a/src/plugins/sfdisk/sfdiskpartitiontable.cpp +++ b/src/plugins/sfdisk/sfdiskpartitiontable.cpp @@ -68,7 +68,7 @@ QString SfdiskPartitionTable::createPartition(Report& report, const Partition& p return QString(); } - QByteArray type = QByteArray(); // FIXME add map between fs types and default partition types + QByteArray type = QByteArray(); if (partition.roles().has(PartitionRole::Extended)) type = QByteArrayLiteral(" type=5"); @@ -212,6 +212,7 @@ bool SfdiskPartitionTable::setPartitionSystemType(Report& report, const Partitio bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, PartitionTable::Flag flag, bool state) { + // We only allow setting one active partition per device if (flag == PartitionTable::FlagBoot && state == true) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--activate"), m_device->deviceNode(), QString::number(partition.number()) } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0)