diff --git a/src/fs/btrfs.cpp b/src/fs/btrfs.cpp index 34336ca..bf3f8cf 100644 --- a/src/fs/btrfs.cpp +++ b/src/fs/btrfs.cpp @@ -1,176 +1,177 @@ /************************************************************************* * Copyright (C) 2012 by Volker Lanz * * Copyright (C) 2016 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/btrfs.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/report.h" #include #include #include #include namespace FS { FileSystem::CommandSupportType btrfs::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType btrfs::m_GetUUID = FileSystem::cmdSupportNone; btrfs::btrfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Btrfs) { } void btrfs::init() { m_Create = findExternal(QStringLiteral("mkfs.btrfs")) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("btrfsck"), QStringList(), 1) ? cmdSupportFileSystem : cmdSupportNone; m_Grow = (m_Check != cmdSupportNone && findExternal(QStringLiteral("btrfs"))) ? cmdSupportFileSystem : cmdSupportNone; m_GetUsed = findExternal(QStringLiteral("btrfs-debug-tree")) ? cmdSupportFileSystem : cmdSupportNone; m_Shrink = (m_Grow != cmdSupportNone && m_GetUsed != cmdSupportNone) ? cmdSupportFileSystem : cmdSupportNone; m_SetLabel = findExternal(QStringLiteral("btrfs")) ? cmdSupportFileSystem : cmdSupportNone; m_UpdateUUID = cmdSupportNone; m_Copy = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_GetLabel = cmdSupportCore; m_Backup = cmdSupportCore; m_GetUUID = cmdSupportCore; } bool btrfs::supportToolFound() const { return m_GetUsed != cmdSupportNone && m_GetLabel != cmdSupportNone && m_SetLabel != cmdSupportNone && m_Create != cmdSupportNone && m_Check != cmdSupportNone && // m_UpdateUUID != cmdSupportNone && m_Grow != cmdSupportNone && m_Shrink != cmdSupportNone && m_Copy != cmdSupportNone && m_Move != cmdSupportNone && m_Backup != cmdSupportNone && m_GetUUID != cmdSupportNone; } FileSystem::SupportTool btrfs::supportToolName() const { return SupportTool(QStringLiteral("btrfs-tools"), QUrl(QStringLiteral("http://btrfs.wiki.kernel.org/"))); } qint64 btrfs::minCapacity() const { return 256 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB); } qint64 btrfs::maxCapacity() const { return Capacity::unitFactor(Capacity::Byte, Capacity::EiB); } qint64 btrfs::maxLabelLength() const { return 255; } qint64 btrfs::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("btrfs"), QStringList() << QStringLiteral("filesystem") << QStringLiteral("show") << QStringLiteral("--raw") << deviceNode); if (cmd.run()) { QRegExp rxBytesUsed(QStringLiteral(" used (\\d+) path ") + deviceNode); if (rxBytesUsed.indexIn(cmd.output()) != -1) return rxBytesUsed.cap(1).toLongLong(); } return -1; } bool btrfs::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("btrfsck"), QStringList() << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } bool btrfs::create(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("mkfs.btrfs"), QStringList() << QStringLiteral("-f") << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } bool btrfs::resize(Report& report, const QString& deviceNode, qint64 length) const { QTemporaryDir tempDir; if (!tempDir.isValid()) { report.line() << xi18nc("@info/plain", "Resizing Btrfs file system on partition %1 failed: Could not create temp dir.", deviceNode); return false; } bool rval = false; ExternalCommand mountCmd(report, QStringLiteral("mount"), QStringList() << QStringLiteral("-v") << QStringLiteral("-t") << QStringLiteral("btrfs") << deviceNode << tempDir.path()); if (mountCmd.run(-1) && mountCmd.exitCode() == 0) { - ExternalCommand resizeCmd(report, QStringLiteral("btrfs"), QStringList() << QStringLiteral("filesystem") << QStringLiteral("resize") << QString::number(length) << tempDir.path()); + QString len = length == -1 ? QStringLiteral("max") : QString::number(length); + ExternalCommand resizeCmd(report, QStringLiteral("btrfs"), QStringList() << QStringLiteral("filesystem") << QStringLiteral("resize") << len << tempDir.path()); if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0) rval = true; else report.line() << xi18nc("@info/plain", "Resizing Btrfs file system on partition %1 failed: btrfs file system resize failed.", deviceNode); ExternalCommand unmountCmd(report, QStringLiteral("umount"), QStringList() << tempDir.path()); if (!unmountCmd.run(-1) && unmountCmd.exitCode() == 0) report.line() << xi18nc("@info/plain", "Warning: Resizing Btrfs file system on partition %1: Unmount failed.", deviceNode); } else report.line() << xi18nc("@info/plain", "Resizing Btrfs file system on partition %1 failed: Initial mount failed.", deviceNode); return rval; } bool btrfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("btrfs"), QStringList() << QStringLiteral("filesystem") << QStringLiteral("label") << deviceNode << newLabel); return cmd.run(-1) && cmd.exitCode() == 0; } bool btrfs::updateUUID(Report& report, const QString& deviceNode) const { Q_UNUSED(report); Q_UNUSED(deviceNode); return false; } } diff --git a/src/fs/ext2.cpp b/src/fs/ext2.cpp index ad318be..6c9603f 100644 --- a/src/fs/ext2.cpp +++ b/src/fs/ext2.cpp @@ -1,155 +1,157 @@ /************************************************************************* * Copyright (C) 2008,2009 by Volker Lanz * * Copyright (C) 2016 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/ext2.h" #include "util/externalcommand.h" #include "util/capacity.h" #include #include namespace FS { FileSystem::CommandSupportType ext2::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ext2::m_GetUUID = FileSystem::cmdSupportNone; ext2::ext2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t) : FileSystem(firstsector, lastsector, sectorsused, label, t) { } void ext2::init() { m_GetUsed = findExternal(QStringLiteral("dumpe2fs")) ? cmdSupportFileSystem : cmdSupportNone; m_GetLabel = cmdSupportCore; m_SetLabel = findExternal(QStringLiteral("e2label")) ? cmdSupportFileSystem : cmdSupportNone; m_Create = findExternal(QStringLiteral("mkfs.ext2")) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("e2fsck"), QStringList() << QStringLiteral("-V")) ? cmdSupportFileSystem : cmdSupportNone; m_UpdateUUID = findExternal(QStringLiteral("tune2fs")) ? cmdSupportFileSystem : cmdSupportNone; m_Grow = (m_Check != cmdSupportNone && findExternal(QStringLiteral("resize2fs"))) ? cmdSupportFileSystem : cmdSupportNone; m_Shrink = (m_Grow != cmdSupportNone && m_GetUsed) != cmdSupportNone ? cmdSupportFileSystem : cmdSupportNone; m_Copy = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Backup = cmdSupportCore; m_GetUUID = cmdSupportCore; } bool ext2::supportToolFound() const { return m_GetUsed != cmdSupportNone && m_GetLabel != cmdSupportNone && m_SetLabel != cmdSupportNone && m_Create != cmdSupportNone && m_Check != cmdSupportNone && m_UpdateUUID != cmdSupportNone && m_Grow != cmdSupportNone && m_Shrink != cmdSupportNone && m_Copy != cmdSupportNone && m_Move != cmdSupportNone && m_Backup != cmdSupportNone && m_GetUUID != cmdSupportNone; } FileSystem::SupportTool ext2::supportToolName() const { return SupportTool(QStringLiteral("e2fsprogs"), QUrl(QStringLiteral("http://e2fsprogs.sf.net"))); } qint64 ext2::maxCapacity() const { return 32 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB); } qint64 ext2::maxLabelLength() const { return 16; } qint64 ext2::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("dumpe2fs"), QStringList() << QStringLiteral("-h") << deviceNode); if (cmd.run()) { qint64 blockCount = -1; QRegExp rxBlockCount(QStringLiteral("Block count:\\s*(\\d+)")); if (rxBlockCount.indexIn(cmd.output()) != -1) blockCount = rxBlockCount.cap(1).toLongLong(); qint64 freeBlocks = -1; QRegExp rxFreeBlocks(QStringLiteral("Free blocks:\\s*(\\d+)")); if (rxFreeBlocks.indexIn(cmd.output()) != -1) freeBlocks = rxFreeBlocks.cap(1).toLongLong(); qint64 blockSize = -1; QRegExp rxBlockSize(QStringLiteral("Block size:\\s*(\\d+)")); if (rxBlockSize.indexIn(cmd.output()) != -1) blockSize = rxBlockSize.cap(1).toLongLong(); if (blockCount > -1 && freeBlocks > -1 && blockSize > -1) return (blockCount - freeBlocks) * blockSize; } return -1; } bool ext2::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("e2fsck"), QStringList() << QStringLiteral("-f") << QStringLiteral("-y") << QStringLiteral("-v") << deviceNode); return cmd.run(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 1 || cmd.exitCode() == 2 || cmd.exitCode() == 256); } bool ext2::create(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("mkfs.ext2"), QStringList() << QStringLiteral("-qF") << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } bool ext2::resize(Report& report, const QString& deviceNode, qint64 length) const { const QString len = QString::number(length / 512) + QStringLiteral("s"); - ExternalCommand cmd(report, QStringLiteral("resize2fs"), QStringList() << deviceNode << len); + const QStringList command = length == -1 ? QStringList() << deviceNode : QStringList() << deviceNode << len; + + ExternalCommand cmd(report, QStringLiteral("resize2fs"), command); return cmd.run(-1) && cmd.exitCode() == 0; } bool ext2::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("e2label"), QStringList() << deviceNode << newLabel); return cmd.run(-1) && cmd.exitCode() == 0; } bool ext2::updateUUID(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("tune2fs"), QStringList() << QStringLiteral("-U") << QStringLiteral("random") << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/filesystem.cpp b/src/fs/filesystem.cpp index b3e233c..8f87611 100644 --- a/src/fs/filesystem.cpp +++ b/src/fs/filesystem.cpp @@ -1,484 +1,484 @@ /************************************************************************* * Copyright (C) 2012 by Volker Lanz * * Copyright (C) 2015 by Teo Mrnjavac * * Copyright (C) 2016 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/filesystem.h" #include "util/externalcommand.h" #include "util/capacity.h" #include #include #include 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 ) }; /** Creates a new FileSystem object @param firstsector the first sector used by this FileSystem on the Device @param lastsector the last sector used by this FileSystem on the Device @param sectorsused the number of sectors in use on the FileSystem @param l the FileSystem label @param t the FileSystem type */ FileSystem::FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& l, FileSystem::Type t) : m_Type(t), m_FirstSector(firstsector), m_LastSector(lastsector), m_SectorsUsed(sectorsused), m_Label(l), m_UUID() { } /** Reads the capacity in use on this FileSystem @param deviceNode the device node for the Partition the FileSystem is on @return the used capacity in bytes or -1 in case of an error */ qint64 FileSystem::readUsedCapacity(const QString& deviceNode) const { Q_UNUSED(deviceNode); return -1; } static QString readBlkIdValue(const QString& deviceNode, const QString& tag) { blkid_cache cache; QString rval; if (blkid_get_cache(&cache, nullptr) == 0) { blkid_dev dev; char* label = nullptr; if ((dev = blkid_get_dev(cache, deviceNode.toLocal8Bit().constData(), BLKID_DEV_NORMAL)) != nullptr && (label = blkid_get_tag_value(cache, tag.toLocal8Bit().constData(), deviceNode.toLocal8Bit().constData()))) { rval = QString::fromUtf8(label); free(label); } blkid_put_cache(cache); } return rval; } FileSystem::Type FileSystem::detectFileSystem(const QString& partitionPath) { FileSystem::Type rval = FileSystem::Unknown; blkid_cache cache; if (blkid_get_cache(&cache, nullptr) == 0) { blkid_dev dev; if ((dev = blkid_get_dev(cache, partitionPath.toLocal8Bit().constData(), BLKID_DEV_NORMAL)) != nullptr) { QString s = QString::fromUtf8(blkid_get_tag_value(cache, "TYPE", partitionPath.toLocal8Bit().constData())); 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")) 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")) { // libblkid uses SEC_TYPE to distinguish between FAT16 and FAT32 QString st = QString::fromUtf8(blkid_get_tag_value(cache, "SEC_TYPE", partitionPath.toLocal8Bit().constData())); if (st == 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 qWarning() << "blkid: unknown file system type " << s << " on " << partitionPath; } blkid_put_cache(cache); } return rval; } /** Reads the label for this FileSystem @param deviceNode the device node for the Partition the FileSystem is on @return the FileSystem label or an empty string in case of error */ QString FileSystem::readLabel(const QString& deviceNode) const { return readBlkIdValue(deviceNode, QStringLiteral("LABEL")); } /** Creates a new FileSystem @param report Report to write status information to @param deviceNode the device node for the Partition to create the FileSystem on @return true if successful */ bool FileSystem::create(Report& report, const QString& deviceNode) const { Q_UNUSED(report); Q_UNUSED(deviceNode); return true; } -/** Resized a FileSystem to a given new length +/** Resize a FileSystem to a given new length @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @param newLength the new length for the FileSystem in bytes @return true on success */ bool FileSystem::resize(Report& report, const QString& deviceNode, qint64 newLength) const { Q_UNUSED(report); Q_UNUSED(deviceNode); Q_UNUSED(newLength); return true; } /** Move a FileSystem to a new start sector @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @param newLength the new start sector for the FileSystem @return true on success */ bool FileSystem::move(Report& report, const QString& deviceNode, qint64 newStartSector) const { Q_UNUSED(report); Q_UNUSED(deviceNode); Q_UNUSED(newStartSector); return true; } /** Writes a label for the FileSystem to disk @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @param newLabel the new label for the FileSystem @return true on success */ bool FileSystem::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { Q_UNUSED(report); Q_UNUSED(deviceNode); Q_UNUSED(newLabel); return true; } /** Copies a FileSystem from one Partition to another @param report Report to write status information to @param targetDeviceNode device node of the target Partition @param sourceDeviceNode device node of the source Partition @return true on success */ bool FileSystem::copy(Report& report, const QString& targetDeviceNode, const QString& sourceDeviceNode) const { Q_UNUSED(report); Q_UNUSED(targetDeviceNode); Q_UNUSED(sourceDeviceNode); return true; } /** Backs up a FileSystem to a file @param report Report to write status information to @param sourceDevice Device the source FileSystem is on @param deviceNode device node of the source Partition @param filename name of the file to backup to @return true on success */ bool FileSystem::backup(Report& report, const Device& sourceDevice, const QString& deviceNode, const QString& filename) const { Q_UNUSED(report); Q_UNUSED(sourceDevice); Q_UNUSED(deviceNode); Q_UNUSED(filename); return false; } /** Removes a FileSystem @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @return true if FileSystem is removed */ bool FileSystem::remove(Report& report, const QString& deviceNode) const { Q_UNUSED(report); Q_UNUSED(deviceNode); return true; } /** Checks a FileSystem for errors @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @return true if FileSystem is error-free */ bool FileSystem::check(Report& report, const QString& deviceNode) const { Q_UNUSED(report); Q_UNUSED(deviceNode); return true; } /** Updates a FileSystem UUID on disk @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @return true on success */ bool FileSystem::updateUUID(Report& report, const QString& deviceNode) const { Q_UNUSED(report); Q_UNUSED(deviceNode); return true; } /** Returns the FileSystem UUID by calling a FileSystem-specific helper program @param deviceNode the device node for the Partition the FileSystem is on @return the UUID or an empty string if the FileSystem does not support UUIDs */ QString FileSystem::readUUID(const QString& deviceNode) const { return readBlkIdValue(deviceNode, QStringLiteral("UUID")); } /** Give implementations of FileSystem a chance to update the boot sector after the file system has been moved or copied. @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @return true on success */ bool FileSystem::updateBootSector(Report& report, const QString& deviceNode) const { Q_UNUSED(report); Q_UNUSED(deviceNode); return true; } /** @return the minimum capacity valid for this FileSystem in bytes */ qint64 FileSystem::minCapacity() const { return 8 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB); } /** @return the maximum capacity valid for this FileSystem in bytes */ qint64 FileSystem::maxCapacity() const { return Capacity::unitFactor(Capacity::Byte, Capacity::EiB); } /** @return the maximum label length valid for this FileSystem */ qint64 FileSystem::maxLabelLength() const { return 16; } /** @return this FileSystem's type as printable name */ QString FileSystem::name() const { return nameForType(type()); } /** @return a pointer to a QString C array with all FileSystem names */ static const QString* typeNames() { static const QString s[] = { i18nc("@item filesystem name", "unknown"), i18nc("@item filesystem name", "extended"), i18nc("@item filesystem name", "ext2"), i18nc("@item filesystem name", "ext3"), i18nc("@item filesystem name", "ext4"), i18nc("@item filesystem name", "linuxswap"), i18nc("@item filesystem name", "fat16"), i18nc("@item filesystem name", "fat32"), i18nc("@item filesystem name", "ntfs"), i18nc("@item filesystem name", "reiser"), i18nc("@item filesystem name", "reiser4"), i18nc("@item filesystem name", "xfs"), i18nc("@item filesystem name", "jfs"), i18nc("@item filesystem name", "hfs"), i18nc("@item filesystem name", "hfsplus"), i18nc("@item filesystem name", "ufs"), i18nc("@item filesystem name", "unformatted"), i18nc("@item filesystem name", "btrfs"), i18nc("@item filesystem name", "hpfs"), i18nc("@item filesystem name", "luks"), i18nc("@item filesystem name", "ocfs2"), i18nc("@item filesystem name", "zfs"), i18nc("@item filesystem name", "exfat"), i18nc("@item filesystem name", "nilfs2"), i18nc("@item filesystem name", "lvm2 pv"), i18nc("@item filesystem name", "f2fs"), }; return s; } /** @param t the type to get the name for @return the printable name for the given type */ QString FileSystem::nameForType(FileSystem::Type t) { Q_ASSERT(t >= 0); Q_ASSERT(t < __lastType); return typeNames()[t]; } /** @param s the name to get the type for @return the type for the name or FileSystem::Unknown if not found */ FileSystem::Type FileSystem::typeForName(const QString& s) { for (quint32 i = 0; i < __lastType; i++) if (typeNames()[i] == s) return static_cast(i); return Unknown; } /** @return a QList of all known types */ QList FileSystem::types() { QList result; int i = Ext2; // first "real" filesystem while (i != __lastType) result.append(static_cast(i++)); return result; } /** @return printable menu title for mounting this FileSystem */ QString FileSystem::mountTitle() const { return i18nc("@title:menu", "Mount"); } /** @return printable menu title for unmounting this FileSystem */ QString FileSystem::unmountTitle() const { return i18nc("@title:menu", "Unmount"); } /** Moves a FileSystem to a new start sector. @param newStartSector where the FileSystem should be moved to */ void FileSystem::move(qint64 newStartSector) { const qint64 savedLength = length(); setFirstSector(newStartSector); setLastSector(newStartSector + savedLength - 1); } /** Attempt to mount this FileSystem on a given mount point @param mountPoint the mount point to mount the FileSystem on @return true on success */ bool FileSystem::mount(const QString &deviceNode, const QString &mountPoint) { Q_UNUSED(deviceNode); Q_UNUSED(mountPoint); return false; } /** Attempt to unmount this FileSystem @param mountPoint the mount point the FileSystem is mounted on @return true on success */ bool FileSystem::unmount(const QString& mountPoint) { Q_UNUSED(mountPoint); return false; } bool FileSystem::findExternal(const QString& cmdName, const QStringList& args, int expectedCode) { ExternalCommand cmd(cmdName, args); if (!cmd.run()) return false; return cmd.exitCode() == 0 || cmd.exitCode() == expectedCode; } bool FileSystem::supportToolFound() const { return false; } FileSystem::SupportTool FileSystem::supportToolName() const { return SupportTool(); } diff --git a/src/fs/linuxswap.cpp b/src/fs/linuxswap.cpp index ddabaa9..29674da 100644 --- a/src/fs/linuxswap.cpp +++ b/src/fs/linuxswap.cpp @@ -1,161 +1,162 @@ /************************************************************************* * Copyright (C) 2008,2009 by Volker Lanz * * Copyright (C) 2016 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/linuxswap.h" #include "util/externalcommand.h" #include namespace FS { FileSystem::CommandSupportType linuxswap::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType linuxswap::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType linuxswap::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType linuxswap::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType linuxswap::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType linuxswap::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType linuxswap::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType linuxswap::m_GetUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType linuxswap::m_UpdateUUID = FileSystem::cmdSupportNone; linuxswap::linuxswap(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::LinuxSwap) { } void linuxswap::init() { m_SetLabel = m_Shrink = m_Grow = m_Create = m_UpdateUUID = (findExternal(QStringLiteral("mkswap"))) ? cmdSupportFileSystem : cmdSupportNone; m_GetLabel = cmdSupportCore; m_Copy = cmdSupportFileSystem; m_Move = cmdSupportCore; m_GetUUID = cmdSupportCore; } bool linuxswap::supportToolFound() const { return // m_GetUsed != cmdSupportNone && m_GetLabel != cmdSupportNone && m_SetLabel != cmdSupportNone && m_Create != cmdSupportNone && // m_Check != cmdSupportNone && m_UpdateUUID != cmdSupportNone && m_Grow != cmdSupportNone && m_Shrink != cmdSupportNone && m_Copy != cmdSupportNone && m_Move != cmdSupportNone && // m_Backup != cmdSupportNone && m_GetUUID != cmdSupportNone; } FileSystem::SupportTool linuxswap::supportToolName() const { return SupportTool(QStringLiteral("util-linux"), QUrl(QStringLiteral("http://www.kernel.org/pub/linux/utils/util-linux-ng/"))); } qint64 linuxswap::maxLabelLength() const { return 15; } bool linuxswap::create(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("mkswap"), QStringList() << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } bool linuxswap::resize(Report& report, const QString& deviceNode, qint64 length) const { + Q_UNUSED(length); const QString label = readLabel(deviceNode); const QString uuid = readUUID(deviceNode); QStringList args; if (!label.isEmpty()) args << QStringLiteral("-L") << label; if (!uuid.isEmpty()) args << QStringLiteral("-U") << uuid; - args << deviceNode << QString::number(length / 1024); + args << deviceNode; ExternalCommand cmd(report, QStringLiteral("mkswap"), args); return cmd.run(-1) && cmd.exitCode() == 0; } bool linuxswap::copy(Report& report, const QString& targetDeviceNode, const QString& sourceDeviceNode) const { const QString label = readLabel(sourceDeviceNode); const QString uuid = readUUID(sourceDeviceNode); QStringList args; if (!label.isEmpty()) args << QStringLiteral("-L") << label; if (!uuid.isEmpty()) args << QStringLiteral("-U") << uuid; args << targetDeviceNode; ExternalCommand cmd(report, QStringLiteral("mkswap"), args); return cmd.run(-1) && cmd.exitCode() == 0; } bool linuxswap::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("mkswap"), QStringList() << QStringLiteral("-L") << newLabel << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } QString linuxswap::mountTitle() const { return i18nc("@title:menu", "Activate swap"); } QString linuxswap::unmountTitle() const { return i18nc("@title:menu", "Deactivate swap"); } bool linuxswap::mount(const QString& deviceNode, const QString& mountPoint) { Q_UNUSED(mountPoint); ExternalCommand cmd(QStringLiteral("swapon"), QStringList() << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } bool linuxswap::unmount(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("swapoff"), QStringList() << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } bool linuxswap::updateUUID(Report& report, const QString& deviceNode) const { const QString label = readLabel(deviceNode); QStringList args; if (!label.isEmpty()) args << QStringLiteral("-L") << label; args << deviceNode; ExternalCommand cmd(report, QStringLiteral("mkswap"), args); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/luks.cpp b/src/fs/luks.cpp index 54ff999..ae5864d 100644 --- a/src/fs/luks.cpp +++ b/src/fs/luks.cpp @@ -1,543 +1,567 @@ /************************************************************************* * Copyright (C) 2012 by Volker Lanz * * Copyright (C) 2013 by Andrius Štikonas * * Copyright (C) 2015-2016 by Teo Mrnjavac * * * * 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/luks.h" #include "fs/filesystemfactory.h" #include "gui/decryptluksdialog.h" #include "util/capacity.h" #include "util/externalcommand.h" +#include "util/report.h" #include #include #include #include #include #include namespace FS { FileSystem::CommandSupportType luks::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType luks::m_UpdateUUID = FileSystem::cmdSupportNone; 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) , m_innerFs(nullptr) , m_isCryptOpen(false) , m_isMounted(false) { } luks::~luks() { delete m_innerFs; } void luks::init() { m_Create = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone; m_UpdateUUID = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone; + m_Grow = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone; m_Copy = cmdSupportCore; m_Move = cmdSupportCore; m_Backup = cmdSupportCore; m_GetUUID = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone; } bool luks::create(Report& report, const QString& deviceNode) const { Q_ASSERT(m_innerFs); Q_ASSERT(!m_passphrase.isEmpty()); std::vector commands; commands.push_back(QStringLiteral("echo")); commands.push_back(QStringLiteral("cryptsetup")); std::vector args; args.push_back({ m_passphrase }); args.push_back({ QStringLiteral("-s"), QStringLiteral("512"), QStringLiteral("luksFormat"), deviceNode }); ExternalCommand createCmd(commands, args); if (!(createCmd.run(-1) && createCmd.exitCode() == 0)) return false; commands.clear(); commands.push_back(QStringLiteral("echo")); commands.push_back(QStringLiteral("cryptsetup")); args.clear(); args.push_back({ m_passphrase }); args.push_back({ QStringLiteral("luksOpen"), deviceNode, QStringLiteral("luks-") + readUUID(deviceNode) }); ExternalCommand openCmd(commands, args); if (!(openCmd.run(-1) && openCmd.exitCode() == 0)) return false; QString mapperNode = mapperName(deviceNode); if (mapperNode.isEmpty()) return false; m_innerFs->create(report, mapperNode); m_isCryptOpen = (m_innerFs != nullptr); if (m_isCryptOpen) return true; return false; } bool luks::supportToolFound() const { return // m_GetUsed != cmdSupportNone && // m_GetLabel != cmdSupportNone && // m_SetLabel != cmdSupportNone && m_Create != cmdSupportNone && // m_Check != cmdSupportNone && m_UpdateUUID != cmdSupportNone && -// m_Grow != cmdSupportNone && + m_Grow != cmdSupportNone && // m_Shrink != cmdSupportNone && m_Copy != cmdSupportNone && m_Move != cmdSupportNone && m_Backup != cmdSupportNone && m_GetUUID != cmdSupportNone; } FileSystem::SupportTool luks::supportToolName() const { return SupportTool(QStringLiteral("cryptsetup"), QUrl(QStringLiteral("https://code.google.com/p/cryptsetup/"))); } qint64 luks::minCapacity() const { return 3 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB); } QString luks::mountTitle() const { return i18nc("@title:menu", "Mount"); } QString luks::unmountTitle() const { return i18nc("@title:menu", "Unmount"); } QString luks::cryptOpenTitle() const { return i18nc("@title:menu", "Decrypt"); } QString luks::cryptCloseTitle() const { return i18nc("@title:menu", "Deactivate"); } void luks::setPassphrase(const QString& passphrase) { m_passphrase = passphrase; } bool luks::canMount(const QString& deviceNode) const { return m_isCryptOpen && !m_isMounted && m_innerFs && m_innerFs->canMount(mapperName(deviceNode)); } bool luks::canUnmount(const QString& deviceNode) const { return m_isCryptOpen && m_isMounted && m_innerFs && m_innerFs->canUnmount(mapperName(deviceNode)); } bool luks::isMounted() const { return m_isCryptOpen && m_isMounted; } void luks::setMounted(bool mounted) { m_isMounted = mounted; } bool luks::canCryptOpen(const QString&) const { return !m_isCryptOpen && !m_isMounted; } bool luks::canCryptClose(const QString&) const { return m_isCryptOpen && !m_isMounted; } bool luks::isCryptOpen() const { return m_isCryptOpen; } void luks::setCryptOpen(bool cryptOpen) { m_isCryptOpen = cryptOpen; } bool luks::cryptOpen(const QString& deviceNode) { if (m_isCryptOpen) { if (!mapperName(deviceNode).isEmpty()) { qWarning() << "LUKS device" << deviceNode << "already decrypted." << "Cannot decrypt again."; return false; } else { qWarning() << "LUKS device" << deviceNode << "reportedly decrypted but mapper node not found." << "Marking device as NOT decrypted and trying to " "decrypt again anyway."; m_isCryptOpen = false; } } QPointer dlg = new DecryptLuksDialog(0, deviceNode); //TODO: parent widget instead of 0 if (dlg->exec() != QDialog::Accepted) { delete dlg; return false; } std::vector commands; commands.push_back(QStringLiteral("echo")); commands.push_back(QStringLiteral("cryptsetup")); std::vector args; args.push_back({ dlg->luksPassphrase().text() }); args.push_back({ QStringLiteral("luksOpen"), deviceNode, QStringLiteral("luks-") + readUUID(deviceNode) }); delete dlg; ExternalCommand cmd(commands, args); if (!(cmd.run(-1) && cmd.exitCode() == 0)) return false; if (m_innerFs) { delete m_innerFs; m_innerFs = nullptr; } QString mapperNode = mapperName(deviceNode); if (mapperNode.isEmpty()) return false; loadInnerFileSystem(mapperNode); m_isCryptOpen = (m_innerFs != nullptr); if (m_isCryptOpen) return true; return false; } bool luks::cryptClose(const QString& deviceNode) { if (!m_isCryptOpen) { qWarning() << "Cannot close LUKS device" << deviceNode << "because it's not open."; return false; } if (m_isMounted) { qWarning() << "Cannot close LUKS device" << deviceNode << "because the filesystem is mounted."; return false; } ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksClose"), mapperName(deviceNode) }); if (!(cmd.run(-1) && cmd.exitCode() == 0)) return false; delete m_innerFs; m_innerFs = nullptr; m_isCryptOpen = (m_innerFs != nullptr); if (!m_isCryptOpen) return true; return false; } void luks::loadInnerFileSystem(const QString& mapperNode) { Q_ASSERT(!m_innerFs); FileSystem::Type innerFsType = detectFileSystem(mapperNode); m_innerFs = FileSystemFactory::cloneWithNewType(innerFsType, *this); } void luks::createInnerFileSystem(FileSystem::Type type) { Q_ASSERT(!m_innerFs); m_innerFs = FileSystemFactory::cloneWithNewType(type, *this); } bool luks::mount(const QString& deviceNode, const QString& mountPoint) { if (!m_isCryptOpen) { qWarning() << "Cannot mount device" << deviceNode << "before decrypting it first."; return false; } if (m_isMounted) { qWarning() << "Cannot mount device" << deviceNode << "because it's already mounted."; return false; } Q_ASSERT(m_innerFs); QString mapperNode = mapperName(deviceNode); if (mapperNode.isEmpty()) return false; if (m_innerFs->canMount(mapperNode)) { if (m_innerFs->mount(mapperNode, mountPoint)) { m_isMounted = true; return true; } } else { ExternalCommand mountCmd( QStringLiteral("mount"), { QStringLiteral("-v"), mapperNode, mountPoint }); if (mountCmd.run() && mountCmd.exitCode() == 0) { m_isMounted = true; return true; } } return false; } bool luks::unmount(const QString& deviceNode) { if (!m_isCryptOpen) { qWarning() << "Cannot unmount device" << deviceNode << "before decrypting it first."; return false; } if (!m_isMounted) { qWarning() << "Cannot unmount device" << deviceNode << "because it's not mounted."; return false; } Q_ASSERT(m_innerFs); QString mapperNode = mapperName(deviceNode); if (mapperNode.isEmpty()) return false; if (m_innerFs->canUnmount(mapperNode)) { if (m_innerFs->unmount(mapperNode)) { m_isMounted = false; return true; } } else { ExternalCommand unmountCmd( QStringLiteral("mount"), { QStringLiteral("-v"), QStringLiteral("-A"), mapperNode }); if (unmountCmd.run() && unmountCmd.exitCode() == 0) { m_isMounted = false; return true; } } return false; } FileSystem::Type luks::type() const { if (m_isCryptOpen && m_innerFs) return m_innerFs->type(); return FileSystem::Luks; } +bool luks::resize(Report& report, const QString& deviceNode, qint64) const +{ + Q_ASSERT(m_innerFs); + + QString mapperNode = mapperName(deviceNode); + if (mapperNode.isEmpty()) + return false; + + ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), QStringList() << QStringLiteral("resize") << mapperNode); + report.line() << xi18nc("@info/plain", "Resizing LUKS crypt on partition %1.", deviceNode); + + bool rval = false; + if (cryptResizeCmd.run(-1)) + { + rval = m_innerFs->resize(report, mapperNode, -1); + } + else + report.line() << xi18nc("@info/plain", "Resizing encrypted file system on partition %1 failed.", deviceNode); + + return rval; +} + QString luks::readUUID(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksUUID"), deviceNode }); if (cmd.run()) { return cmd.output().simplified(); } return QStringLiteral("---"); } bool luks::updateUUID(Report& report, const QString& deviceNode) const { QUuid uuid = QUuid::createUuid(); ExternalCommand cmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("luksUUID"), deviceNode, QStringLiteral("--uuid"), uuid.toString() }); return cmd.run(-1) && cmd.exitCode() == 0; } QString luks::mapperName(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("find"), { QStringLiteral("/dev/mapper/"), QStringLiteral("-exec"), QStringLiteral("cryptsetup"), QStringLiteral("status"), QStringLiteral("{}"), QStringLiteral(";") }); if (cmd.run()) { QRegExp rxDeviceName(QStringLiteral("(/dev/mapper/[A-Za-z0-9-/]+) is " "active[A-Za-z0-9- \\.\n]+[A-Za-z0-9-: \n]+") + deviceNode); if (rxDeviceName.indexIn(cmd.output()) > -1) return rxDeviceName.cap(1); } return QString(); } QString luks::getCipherName(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksDump"), deviceNode }); if (cmd.run()) { QRegExp rxCipherName(QStringLiteral("(?:Cipher name:\\s+)([A-Za-z0-9-]+)")); if (rxCipherName.indexIn(cmd.output()) > -1) return rxCipherName.cap(1); } return QStringLiteral("---"); } QString luks::getCipherMode(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksDump"), deviceNode }); if (cmd.run()) { QRegExp rxCipherMode(QStringLiteral("(?:Cipher mode:\\s+)([A-Za-z0-9-]+)")); if (rxCipherMode.indexIn(cmd.output()) > -1) return rxCipherMode.cap(1); } return QStringLiteral("---"); } QString luks::getHashName(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksDump"), deviceNode }); if (cmd.run()) { QRegExp rxHash(QStringLiteral("(?:Hash spec:\\s+)([A-Za-z0-9-]+)")); if (rxHash.indexIn(cmd.output()) > -1) return rxHash.cap(1); } return QStringLiteral("---"); } QString luks::getKeySize(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksDump"), deviceNode }); if (cmd.run()) { QRegExp rxKeySize(QStringLiteral("(?:MK bits:\\s+)(\\d+)")); if (rxKeySize.indexIn(cmd.output()) > -1) return rxKeySize.cap(1); } return QStringLiteral("---"); } QString luks::getPayloadOffset(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksDump"), deviceNode }); if (cmd.run()) { QRegExp rxPayloadOffset(QStringLiteral("(?:Payload offset:\\s+)(\\d+)")); if (rxPayloadOffset.indexIn(cmd.output()) > -1) return rxPayloadOffset.cap(1); } return QStringLiteral("---"); } bool luks::canEncryptType(FileSystem::Type type) { switch (type) { case Ext2: case Ext3: case Ext4: case LinuxSwap: case ReiserFS: case Reiser4: case Xfs: case Jfs: case Btrfs: case Zfs: case Lvm2_PV: return true; default: return false; } } } diff --git a/src/fs/luks.h b/src/fs/luks.h index 11eaf21..4cc142e 100644 --- a/src/fs/luks.h +++ b/src/fs/luks.h @@ -1,153 +1,154 @@ /************************************************************************* * Copyright (C) 2012 by Volker Lanz * * Copyright (C) 2013 by Andrius Štikonas * * Copyright (C) 2015-2016 by Teo Mrnjavac * * * * 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(LUKS__H) #define LUKS__H #include "../util/libpartitionmanagerexport.h" #include "../fs/filesystem.h" #include #include class Report; class QString; namespace FS { /** A LUKS crypto file system. @author Andrius Štikonas */ class LIBKPMCORE_EXPORT luks : public FileSystem { public: luks(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); virtual ~luks(); public: static void init(); virtual CommandSupportType supportGetUsed() const { return m_GetUsed; } virtual CommandSupportType supportGetLabel() const { return m_GetLabel; } virtual CommandSupportType supportCreate() const { return m_Create; } virtual CommandSupportType supportGrow() const { return m_Grow; } virtual CommandSupportType supportShrink() const { return m_Shrink; } virtual CommandSupportType supportMove() const { return m_Move; } virtual CommandSupportType supportCheck() const { return m_Check; } virtual CommandSupportType supportCopy() const { return m_Copy; } virtual CommandSupportType supportBackup() const { return m_Backup; } virtual CommandSupportType supportSetLabel() const { return m_SetLabel; } virtual CommandSupportType supportUpdateUUID() const { return m_UpdateUUID; } virtual CommandSupportType supportGetUUID() const { return m_GetUUID; } virtual bool create(Report &report, const QString &deviceNode) const override; virtual qint64 minCapacity() const; virtual SupportTool supportToolName() const; virtual bool supportToolFound() const; virtual QString readUUID(const QString& deviceNode) const; virtual bool updateUUID(Report& report, const QString& deviceNode) const; + virtual bool resize(Report& report, const QString& deviceNode, qint64 length) const; virtual QString mountTitle() const override; virtual QString unmountTitle() const override; QString cryptOpenTitle() const; QString cryptCloseTitle() const; void setPassphrase(const QString&); virtual bool canMount(const QString&) const; virtual bool canUnmount(const QString&) const; bool isMounted() const; void setMounted(bool mounted); bool canCryptOpen(const QString& deviceNode) const; bool canCryptClose(const QString& deviceNode) const; bool isCryptOpen() const; void setCryptOpen(bool cryptOpen); bool cryptOpen(const QString& deviceNode); bool cryptClose(const QString& deviceNode); void loadInnerFileSystem(const QString& mapperNode); void createInnerFileSystem(Type type); virtual bool mount(const QString& deviceNode, const QString& mountPoint) override; virtual bool unmount(const QString& deviceNode) override; virtual FileSystem::Type type() const override; static QString mapperName(const QString& deviceNode); static QString getCipherName(const QString& deviceNode); static QString getCipherMode(const QString& deviceNode); static QString getHashName(const QString& deviceNode); static QString getKeySize(const QString& deviceNode); static QString getPayloadOffset(const QString& deviceNode); static bool canEncryptType(FileSystem::Type type); public: static CommandSupportType m_GetUsed; static CommandSupportType m_GetLabel; 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_SetLabel; static CommandSupportType m_UpdateUUID; static CommandSupportType m_GetUUID; private: mutable FileSystem* m_innerFs; mutable bool m_isCryptOpen; QString m_passphrase; bool m_isMounted; }; } #endif