diff --git a/src/fs/apfs.h b/src/fs/apfs.h index 2af3a40..94710d4 100644 --- a/src/fs/apfs.h +++ b/src/fs/apfs.h @@ -1,61 +1,57 @@ /************************************************************************* * 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.h b/src/fs/bitlocker.h index 493eb4d..36123d4 100644 --- a/src/fs/bitlocker.h +++ b/src/fs/bitlocker.h @@ -1,61 +1,57 @@ /************************************************************************* * 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/btrfs.cpp b/src/fs/btrfs.cpp index c7c1edb..1d84802 100644 --- a/src/fs/btrfs.cpp +++ b/src/fs/btrfs.cpp @@ -1,197 +1,196 @@ /************************************************************************* * 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::Type::Btrfs) { } void btrfs::init() { m_Create = findExternal(QStringLiteral("mkfs.btrfs")) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("btrfs")) ? cmdSupportFileSystem : cmdSupportNone; m_Grow = m_Check; m_GetUsed = m_Check; m_Shrink = (m_Grow != cmdSupportNone && m_GetUsed != cmdSupportNone) ? cmdSupportFileSystem : cmdSupportNone; m_SetLabel = m_Check; m_UpdateUUID = findExternal(QStringLiteral("btrfstune")) ? cmdSupportFileSystem : 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::Unit::Byte, Capacity::Unit::MiB); } qint64 btrfs::maxCapacity() const { return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } int btrfs::maxLabelLength() const { return 255; } qint64 btrfs::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("btrfs"), { QStringLiteral("filesystem"), QStringLiteral("show"), QStringLiteral("--raw"), deviceNode }); if (cmd.run(-1) && cmd.exitCode() == 0) { QRegularExpression re(QStringLiteral(" used (\\d+) path ") + deviceNode); QRegularExpressionMatch reBytesUsed = re.match(cmd.output()); if (reBytesUsed.hasMatch()) return reBytesUsed.captured(1).toLongLong(); } return -1; } bool btrfs::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("btrfs"), { QStringLiteral("check"), QStringLiteral("--repair"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool btrfs::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.btrfs"), { QStringLiteral("--force"), 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:progress", "Resizing Btrfs file system on partition %1 failed: Could not create temp dir.", deviceNode); return false; } bool rval = false; ExternalCommand mountCmd(report, QStringLiteral("mount"), { QStringLiteral("--verbose"), QStringLiteral("--types"), QStringLiteral("btrfs"), deviceNode, tempDir.path() }); if (mountCmd.run(-1) && mountCmd.exitCode() == 0) { ExternalCommand resizeCmd(report, QStringLiteral("btrfs"), { QStringLiteral("filesystem"), QStringLiteral("resize"), QString::number(length), tempDir.path() }); if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0) rval = true; else report.line() << xi18nc("@info:progress", "Resizing Btrfs file system on partition %1 failed: btrfs file system resize failed.", deviceNode); ExternalCommand unmountCmd(report, QStringLiteral("umount"), { tempDir.path() }); if (!unmountCmd.run(-1) && unmountCmd.exitCode() == 0) report.line() << xi18nc("@info:progress", "Resizing Btrfs file system on partition %1: Unmount failed.", deviceNode); } else report.line() << xi18nc("@info:progress", "Resizing Btrfs file system on partition %1 failed: Initial mount failed.", deviceNode); return rval; } bool btrfs::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const { ExternalCommand resizeCmd(report, QStringLiteral("btrfs"), { QStringLiteral("filesystem"), QStringLiteral("resize"), QString::number(length), mountPoint }); if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0) return true; report.line() << xi18nc("@info:progress", "Resizing Btrfs file system on partition %1 failed: btrfs file system resize failed.", deviceNode); return false; } bool btrfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("btrfs"), { QStringLiteral("filesystem"), QStringLiteral("label"), deviceNode, newLabel }); return cmd.run(-1) && cmd.exitCode() == 0; } bool btrfs::writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel) { Q_UNUSED(deviceNode) ExternalCommand cmd(report, QStringLiteral("btrfs"), { QStringLiteral("filesystem"), QStringLiteral("label"), mountPoint, newLabel }); return cmd.run(-1) && cmd.exitCode() == 0; } bool btrfs::updateUUID(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("btrfstune"), { QStringLiteral("-f"), QStringLiteral("-u"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/btrfs.h b/src/fs/btrfs.h index 694f8c8..2d7402d 100644 --- a/src/fs/btrfs.h +++ b/src/fs/btrfs.h @@ -1,123 +1,118 @@ /************************************************************************* * 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 .* *************************************************************************/ -#if !defined(KPMCORE_BTRFS_H) - +#ifndef KPMCORE_BTRFS_H #define KPMCORE_BTRFS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A btrfs file system. @author Andrius Štikonas */ class LIBKPMCORE_EXPORT btrfs : public FileSystem { public: btrfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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 resize(Report& report, const QString& deviceNode, qint64 length) const override; bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel) override; bool updateUUID(Report& report, const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportCreate() const override { return m_Create; } CommandSupportType supportGrow() const override { return m_Grow; } CommandSupportType supportGrowOnline() const override { return m_Grow; } CommandSupportType supportShrink() const override { return m_Shrink; } CommandSupportType supportShrinkOnline() 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 supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportSetLabelOnline() const override { return m_SetLabel; } 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; SupportTool supportToolName() const override; bool supportToolFound() const override; 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; }; } #endif diff --git a/src/fs/exfat.cpp b/src/fs/exfat.cpp index 3173450..2880c3e 100644 --- a/src/fs/exfat.cpp +++ b/src/fs/exfat.cpp @@ -1,120 +1,118 @@ /************************************************************************* * 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/exfat.h" #include "util/externalcommand.h" #include "util/capacity.h" -#include - namespace FS { FileSystem::CommandSupportType exfat::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType exfat::m_GetUUID = FileSystem::cmdSupportNone; exfat::exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Exfat) { } void exfat::init() { m_Create = findExternal(QStringLiteral("mkfs.exfat")) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("exfatfsck"), QStringList(), 1) ? cmdSupportFileSystem : cmdSupportNone; m_GetLabel = cmdSupportCore; m_SetLabel = findExternal(QStringLiteral("exfatlabel")) ? 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 exfat::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 exfat::supportToolName() const { return SupportTool(QStringLiteral("exfat-utils"), QUrl(QStringLiteral("http://code.google.com/p/exfat/"))); } qint64 exfat::maxCapacity() const { return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } int exfat::maxLabelLength() const { return 15; } bool exfat::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("exfatfsck"), { deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool exfat::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.exfat"), { deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool exfat::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("exfatlabel"), { deviceNode, newLabel }); return cmd.run(-1) && cmd.exitCode() == 0; } bool exfat::updateUUID(Report& report, const QString& deviceNode) const { Q_UNUSED(report) Q_UNUSED(deviceNode) return false; } } diff --git a/src/fs/exfat.h b/src/fs/exfat.h index 55940b0..07238ea 100644 --- a/src/fs/exfat.h +++ b/src/fs/exfat.h @@ -1,111 +1,106 @@ /************************************************************************* * Copyright (C) 2012 by Volker Lanz * * * * 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_EXFAT_H) - +#ifndef KPMCORE_EXFAT_H #define KPMCORE_EXFAT_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** An exfat file system. @author Andrius Štikonas */ class LIBKPMCORE_EXPORT exfat : public FileSystem { public: exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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 resize(Report& report, const QString& deviceNode, qint64 length) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool updateUUID(Report& report, const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } 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 supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportUpdateUUID() const override { return m_UpdateUUID; } CommandSupportType supportGetUUID() const override { return m_GetUUID; } // qint64 minCapacity() const; qint64 maxCapacity() const override; int maxLabelLength() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; 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; }; } #endif diff --git a/src/fs/ext2.cpp b/src/fs/ext2.cpp index fce9274..431c14c 100644 --- a/src/fs/ext2.cpp +++ b/src/fs/ext2.cpp @@ -1,165 +1,164 @@ /************************************************************************* * 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"), { 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 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } int ext2::maxLabelLength() const { return 16; } qint64 ext2::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("dumpe2fs"), { QStringLiteral("-h"), deviceNode }); if (cmd.run()) { qint64 blockCount = -1; QRegularExpression re(QStringLiteral("Block count:\\s+(\\d+)")); QRegularExpressionMatch reBlockCount = re.match(cmd.output()); if (reBlockCount.hasMatch()) blockCount = reBlockCount.captured(1).toLongLong(); qint64 freeBlocks = -1; re.setPattern(QStringLiteral("Free blocks:\\s+(\\d+)")); QRegularExpressionMatch reFreeBlocks = re.match(cmd.output()); if (reFreeBlocks.hasMatch()) freeBlocks = reFreeBlocks.captured(1).toLongLong(); qint64 blockSize = -1; re.setPattern(QStringLiteral("Block size:\\s+(\\d+)")); QRegularExpressionMatch reBlockSize = re.match(cmd.output()); if (reBlockSize.hasMatch()) blockSize = reBlockSize.captured(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"), { 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) { ExternalCommand cmd(report, QStringLiteral("mkfs.ext2"), { 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"), { deviceNode, len }); return cmd.run(-1) && cmd.exitCode() == 0; } bool ext2::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("e2label"), { deviceNode, newLabel }); return cmd.run(-1) && cmd.exitCode() == 0; } bool ext2::writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel) { Q_UNUSED(mountPoint) return writeLabel(report, deviceNode, newLabel); } bool ext2::updateUUID(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("tune2fs"), { QStringLiteral("-U"), QStringLiteral("random"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/ext2.h b/src/fs/ext2.h index ec2ca59..3ab2ac8 100644 --- a/src/fs/ext2.h +++ b/src/fs/ext2.h @@ -1,114 +1,109 @@ /************************************************************************* * Copyright (C) 2008,2009 by Volker Lanz * * * * 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_EXT2_H) - +#ifndef KPMCORE_EXT2_H #define KPMCORE_EXT2_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** An ext2 file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT ext2 : public FileSystem { public: ext2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Type::Ext2); 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 resize(Report& report, const QString& deviceNode, qint64 length) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel) override; bool updateUUID(Report& report, const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } 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 supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportSetLabelOnline() const override { return m_SetLabel; } CommandSupportType supportUpdateUUID() const override { return m_UpdateUUID; } CommandSupportType supportGetUUID() const override { return m_GetUUID; } qint64 maxCapacity() const override; int maxLabelLength() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; 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; }; } #endif diff --git a/src/fs/ext3.cpp b/src/fs/ext3.cpp index 7fa67c9..07d3342 100644 --- a/src/fs/ext3.cpp +++ b/src/fs/ext3.cpp @@ -1,47 +1,45 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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/ext3.h" #include "util/externalcommand.h" #include "util/capacity.h" -#include - namespace FS { ext3::ext3(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : ext2(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ext3) { } qint64 ext3::maxCapacity() const { return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } bool ext3::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.ext3"), QStringList() << QStringLiteral("-qF") << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } bool ext3::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const { return resize(report, deviceNode, length); } } diff --git a/src/fs/ext3.h b/src/fs/ext3.h index 23ac4df..1eb5b2b 100644 --- a/src/fs/ext3.h +++ b/src/fs/ext3.h @@ -1,56 +1,52 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_EXT3_H) +#ifndef KPMCORE_EXT3_H #define KPMCORE_EXT3_H #include "util/libpartitionmanagerexport.h" #include "fs/ext2.h" -#include - class Report; -class QString; - namespace FS { /** An ext3 file system. Basically the same as ext2. @author Volker Lanz */ class LIBKPMCORE_EXPORT ext3 : public ext2 { public: ext3(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: bool create(Report& report, const QString& deviceNode) override; bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override; qint64 maxCapacity() const override; CommandSupportType supportGrowOnline() const override { return m_Grow; } }; } #endif diff --git a/src/fs/ext4.cpp b/src/fs/ext4.cpp index 0fa3811..0c98520 100644 --- a/src/fs/ext4.cpp +++ b/src/fs/ext4.cpp @@ -1,47 +1,45 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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/ext4.h" #include "util/externalcommand.h" #include "util/capacity.h" -#include - namespace FS { ext4::ext4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : ext2(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ext4) { } qint64 ext4::maxCapacity() const { return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } bool ext4::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.ext4"), QStringList() << QStringLiteral("-qF") << deviceNode); return cmd.run(-1) && cmd.exitCode() == 0; } bool ext4::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const { return resize(report, deviceNode, length); } } diff --git a/src/fs/ext4.h b/src/fs/ext4.h index 8050413..7badd71 100644 --- a/src/fs/ext4.h +++ b/src/fs/ext4.h @@ -1,56 +1,51 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_EXT4_H) - +#ifndef KPMCORE_EXT4_H #define KPMCORE_EXT4_H #include "util/libpartitionmanagerexport.h" #include "fs/ext2.h" -#include - class Report; -class QString; - namespace FS { /** An ext4 file system. Basically the same as ext2. @author Volker Lanz */ class LIBKPMCORE_EXPORT ext4 : public ext2 { public: ext4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: bool create(Report& report, const QString& deviceNode) override; bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override; qint64 maxCapacity() const override; CommandSupportType supportGrowOnline() const override { return m_Grow; } }; } #endif diff --git a/src/fs/extended.h b/src/fs/extended.h index ef00a7c..f5a426b 100644 --- a/src/fs/extended.h +++ b/src/fs/extended.h @@ -1,74 +1,69 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_EXTENDED_H) - +#ifndef KPMCORE_EXTENDED_H #define KPMCORE_EXTENDED_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - -class QString; - namespace FS { /** An extended file system. A FileSystem for an extended Partition. Of course, extended partitions do not actually have a file system, but we need this to be able to create, grow, shrink or move them. @author Volker Lanz */ class LIBKPMCORE_EXPORT extended : public FileSystem { public: extended(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: bool create(Report&, const QString&) override; 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; } bool supportToolFound() const override { return true; } public: static CommandSupportType m_Create; static CommandSupportType m_Grow; static CommandSupportType m_Shrink; static CommandSupportType m_Move; }; } #endif diff --git a/src/fs/f2fs.cpp b/src/fs/f2fs.cpp index f8c62cb..0d132f6 100644 --- a/src/fs/f2fs.cpp +++ b/src/fs/f2fs.cpp @@ -1,145 +1,144 @@ /************************************************************************* * 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/f2fs.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/report.h" #include -#include #include #include #include namespace FS { FileSystem::CommandSupportType f2fs::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType f2fs::m_GetUUID = FileSystem::cmdSupportNone; bool f2fs::oldVersion = false; // 1.8.x or older f2fs::f2fs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::F2fs) { } void f2fs::init() { m_Create = findExternal(QStringLiteral("mkfs.f2fs")) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("fsck.f2fs")) ? cmdSupportFileSystem : cmdSupportNone; if (m_Create == cmdSupportFileSystem) { ExternalCommand cmd(QStringLiteral("mkfs.f2fs"), {}); oldVersion = cmd.run(-1) && !cmd.output().contains(QStringLiteral("-f")); } m_GetLabel = cmdSupportCore; // m_SetLabel = findExternal(QStringLiteral("nilfs-tune")) ? cmdSupportFileSystem : cmdSupportNone; // m_UpdateUUID = findExternal(QStringLiteral("nilfs-tune")) ? cmdSupportFileSystem : cmdSupportNone; m_Grow = (m_Check != cmdSupportNone && findExternal(QStringLiteral("resize.f2fs"))) ? cmdSupportFileSystem : cmdSupportNone; // m_GetUsed = findExternal(QStringLiteral("nilfs-tune")) ? 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_GetLabel = cmdSupportCore; m_Backup = cmdSupportCore; m_GetUUID = cmdSupportCore; } bool f2fs::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 f2fs::supportToolName() const { return SupportTool(QStringLiteral("f2fs-tools"), QUrl(QStringLiteral("https://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs-tools.git"))); } qint64 f2fs::minCapacity() const { return 30 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } qint64 f2fs::maxCapacity() const { return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB); } int f2fs::maxLabelLength() const { return 80; } bool f2fs::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("fsck.f2fs"), { deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool f2fs::create(Report& report, const QString& deviceNode) { return createWithLabel(report, deviceNode, QString()); } bool f2fs::createWithLabel(Report& report, const QString& deviceNode, const QString& label) { QStringList args; if (oldVersion) args << QStringLiteral("-l") << label << deviceNode; else args << QStringLiteral("-f") << QStringLiteral("-l") << label << deviceNode; ExternalCommand cmd(report, QStringLiteral("mkfs.f2fs"), args); return cmd.run(-1) && cmd.exitCode() == 0; } bool f2fs::resize(Report& report, const QString& deviceNode, qint64 length) const { Q_UNUSED(length) ExternalCommand cmd(report, QStringLiteral("resize.f2fs"), { deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/f2fs.h b/src/fs/f2fs.h index 4d2d92b..8577791 100644 --- a/src/fs/f2fs.h +++ b/src/fs/f2fs.h @@ -1,119 +1,115 @@ /************************************************************************* * 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 .* *************************************************************************/ #ifndef KPMCORE_F2FS_H #define KPMCORE_F2FS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A f2fs file system. @author Andrius Štikonas */ class LIBKPMCORE_EXPORT f2fs : public FileSystem { public: f2fs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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 createWithLabel(Report& report, const QString& deviceNode, const QString& label) override; // qint64 readUsedCapacity(const QString& deviceNode) const override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; // bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; // bool updateUUID(Report& report, const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportCreate() const override { return m_Create; } CommandSupportType supportCreateWithLabel() 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 supportSetLabel() const override { return m_SetLabel; } 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; SupportTool supportToolName() const override; bool supportToolFound() const override; 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: static bool oldVersion; }; } #endif diff --git a/src/fs/fat12.cpp b/src/fs/fat12.cpp index b4917fe..977babb 100644 --- a/src/fs/fat12.cpp +++ b/src/fs/fat12.cpp @@ -1,171 +1,169 @@ /************************************************************************* * 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 = cmdSupportCore; 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::Unit::Byte, Capacity::Unit::MiB); } qint64 fat12::maxCapacity() const { return 255 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::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 { long int t = time(nullptr); char uuid[4]; for (auto &u : uuid) { u = static_cast(t & 0xff); t >>= 8; } ExternalCommand cmd; return cmd.writeData(report, QByteArray(uuid, sizeof(uuid)), deviceNode, 39); } } diff --git a/src/fs/fat12.h b/src/fs/fat12.h index 5a02895..a42f6a7 100644 --- a/src/fs/fat12.h +++ b/src/fs/fat12.h @@ -1,111 +1,107 @@ /************************************************************************* * 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 .* *************************************************************************/ #ifndef 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::Type::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 cmdSupportNone; } CommandSupportType supportShrink() const override { return cmdSupportNone; } 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 69962de..946bac0 100644 --- a/src/fs/fat16.cpp +++ b/src/fs/fat16.cpp @@ -1,97 +1,94 @@ /************************************************************************* * Copyright (C) 2008,2009,2011 by Volker Lanz * * 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 * * 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/fat16.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/report.h" #include -#include -#include - #include namespace FS { fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : fat12(firstsector, lastsector, sectorsused, label, FileSystem::Type::Fat16) { } fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type) : fat12(firstsector, lastsector, sectorsused, label, type) { } void fat16::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 = cmdSupportCore; m_Grow = findExternal(QStringLiteral("fatresize")) ? cmdSupportFileSystem : cmdSupportNone; m_Shrink = findExternal(QStringLiteral("fatresize")) ? cmdSupportFileSystem : cmdSupportNone; m_GetUUID = cmdSupportCore; } bool fat16::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; } qint64 fat16::minCapacity() const { return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } qint64 fat16::maxCapacity() const { return 4 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::GiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } bool fat16::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.fat"), { QStringLiteral("-F16"), QStringLiteral("-I"), QStringLiteral("-v"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool fat16::resize(Report& report, const QString& deviceNode, qint64 length) const { ExternalCommand cmd(report, QStringLiteral("fatresize"), { QStringLiteral("--verbose"), QStringLiteral("--size"), QString::number(length), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/fat16.h b/src/fs/fat16.h index ea988a5..686805e 100644 --- a/src/fs/fat16.h +++ b/src/fs/fat16.h @@ -1,58 +1,56 @@ /************************************************************************* * 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 .* *************************************************************************/ #ifndef KPMCORE_FAT16_H #define KPMCORE_FAT16_H #include "fs/fat12.h" class Report; -class QString; - namespace FS { /** A fat16 file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT fat16 : public fat12 { public: 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; bool create(Report& report, const QString& deviceNode) override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; CommandSupportType supportGrow() const override { return m_Grow; } CommandSupportType supportShrink() const override { return m_Shrink; } qint64 minCapacity() const override; qint64 maxCapacity() const override; bool supportToolFound() const override; }; } #endif diff --git a/src/fs/fat32.cpp b/src/fs/fat32.cpp index 2bb6b34..0c915f7 100644 --- a/src/fs/fat32.cpp +++ b/src/fs/fat32.cpp @@ -1,64 +1,62 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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/fat32.h" #include "util/externalcommand.h" #include "util/capacity.h" -#include - #include namespace FS { fat32::fat32(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : fat16(firstsector, lastsector, sectorsused, label, FileSystem::Type::Fat32) { } qint64 fat32::minCapacity() const { return 32 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } qint64 fat32::maxCapacity() const { return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } bool fat32::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.fat"), { QStringLiteral("-F32"), QStringLiteral("-I"), QStringLiteral("-v"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool fat32::updateUUID(Report& report, const QString& deviceNode) const { // HACK: replace this hack with fatlabel "-i" (dosfstools 4.2) long int t = time(nullptr); char uuid[4]; for (auto &u : uuid) { u = static_cast(t & 0xff); t >>= 8; } ExternalCommand cmd; return cmd.writeData(report, QByteArray(uuid, sizeof(uuid)), deviceNode, 67); } } diff --git a/src/fs/fat32.h b/src/fs/fat32.h index a356bf7..e5bf351 100644 --- a/src/fs/fat32.h +++ b/src/fs/fat32.h @@ -1,54 +1,49 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_FAT32_H) - +#ifndef KPMCORE_FAT32_H #define KPMCORE_FAT32_H #include "util/libpartitionmanagerexport.h" #include "fs/fat16.h" -#include - class Report; -class QString; - namespace FS { /** A fat32 file system. Basically the same as a fat16 file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT fat32 : public fat16 { public: fat32(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: bool create(Report& report, const QString& deviceNode) override; bool updateUUID(Report& report, const QString& deviceNode) const override; qint64 minCapacity() const override; qint64 maxCapacity() const override; }; } #endif diff --git a/src/fs/filesystem.h b/src/fs/filesystem.h index 052a391..c7001f1 100644 --- a/src/fs/filesystem.h +++ b/src/fs/filesystem.h @@ -1,295 +1,293 @@ /************************************************************************* * Copyright (C) 2012 by Volker Lanz * * Copyright (C) 2015 by Teo Mrnjavac * * Copyright (C) 2016-2018 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_FILESYSTEM_H #define KPMCORE_FILESYSTEM_H #include "util/libpartitionmanagerexport.h" #include -#include -#include #include #include #include #include class QColor; class QValidator; class Device; class Report; struct FileSystemPrivate; /** Base class for all FileSystems. Represents a file system and handles support for various types of operations that can be performed on those. @author Volker Lanz */ class LIBKPMCORE_EXPORT FileSystem { Q_DISABLE_COPY(FileSystem) public: class SupportTool { public: explicit SupportTool(const QString& n = QString(), const QUrl& u = QUrl()) : name(n), url(u) {} const QString name; const QUrl url; }; /** Supported FileSystem types */ enum Type : int { Unknown, Extended, Ext2, Ext3, Ext4, LinuxSwap, Fat16, Fat32, Ntfs, ReiserFS, Reiser4, Xfs, Jfs, Hfs, HfsPlus, Ufs, Unformatted, Btrfs, Hpfs, Luks, Ocfs2, Zfs, Exfat, Nilfs2, Lvm2_PV, F2fs, Udf, Iso9660, Luks2, Fat12, LinuxRaidMember, BitLocker, Apfs, Minix, __lastType }; /** The type of support for a given FileSystem action */ enum CommandSupportType { cmdSupportNone = 0, /**< no support */ cmdSupportCore = 1, /**< internal support */ cmdSupportFileSystem = 2, /**< supported by some external command */ cmdSupportBackend = 4 /**< supported by the backend */ }; static const std::vector defaultColorCode; Q_DECLARE_FLAGS(CommandSupportTypes, CommandSupportType) protected: FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type); public: virtual ~FileSystem(); public: virtual void init() {} virtual void scan(const QString& deviceNode); virtual qint64 readUsedCapacity(const QString& deviceNode) const; virtual QString readLabel(const QString& deviceNode) const; virtual bool create(Report& report, const QString& deviceNode); virtual bool createWithLabel(Report& report, const QString& deviceNode, const QString& label); virtual bool resize(Report& report, const QString& deviceNode, qint64 newLength) const; virtual bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 newLength) const; virtual bool move(Report& report, const QString& deviceNode, qint64 newStartSector) const; virtual bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel); virtual bool writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel); virtual bool copy(Report& report, const QString& targetDeviceNode, const QString& sourceDeviceNode) const; virtual bool backup(Report& report, const Device& sourceDevice, const QString& deviceNode, const QString& filename) const; virtual bool remove(Report& report, const QString& deviceNode) const; virtual bool check(Report& report, const QString& deviceNode) const; virtual bool updateUUID(Report& report, const QString& deviceNode) const; virtual QString readUUID(const QString& deviceNode) const; virtual bool updateBootSector(Report& report, const QString& deviceNode) const; virtual CommandSupportType supportGetUsed() const { return cmdSupportNone; /**< @return CommandSupportType for getting used capacity */ } virtual CommandSupportType supportGetLabel() const { return cmdSupportNone; /**< @return CommandSupportType for reading label*/ } virtual CommandSupportType supportCreate() const { return cmdSupportNone; /**< @return CommandSupportType for creating */ } virtual CommandSupportType supportCreateWithLabel() const { return cmdSupportNone; /**< @return CommandSupportType for creating */ } virtual CommandSupportType supportGrow() const { return cmdSupportNone; /**< @return CommandSupportType for growing */ } virtual CommandSupportType supportGrowOnline() const { return cmdSupportNone; /**< @return CommandSupportType for online growing */ } virtual CommandSupportType supportShrink() const { return cmdSupportNone; /**< @return CommandSupportType for shrinking */ } virtual CommandSupportType supportShrinkOnline() const { return cmdSupportNone; /**< @return CommandSupportType for shrinking */ } virtual CommandSupportType supportMove() const { return cmdSupportNone; /**< @return CommandSupportType for moving */ } virtual CommandSupportType supportCheck() const { return cmdSupportNone; /**< @return CommandSupportType for checking */ } virtual CommandSupportType supportCheckOnline() const { return cmdSupportNone; /**< @return CommandSupportType for checking */ } virtual CommandSupportType supportCopy() const { return cmdSupportNone; /**< @return CommandSupportType for copying */ } virtual CommandSupportType supportBackup() const { return cmdSupportNone; /**< @return CommandSupportType for backing up */ } virtual CommandSupportType supportSetLabel() const { return cmdSupportNone; /**< @return CommandSupportType for setting label */ } virtual CommandSupportType supportSetLabelOnline() const { return cmdSupportNone; /**< @return CommandSupportType for setting label of mounted file systems */ } virtual CommandSupportType supportUpdateUUID() const { return cmdSupportNone; /**< @return CommandSupportType for updating the UUID */ } virtual CommandSupportType supportGetUUID() const { return cmdSupportNone; /**< @return CommandSupportType for reading the UUID */ } virtual qint64 minCapacity() const; virtual qint64 maxCapacity() const; virtual int maxLabelLength() const; virtual QValidator* labelValidator(QObject *parent = nullptr) const; virtual SupportTool supportToolName() const; virtual bool supportToolFound() const; /** * Returns the (possibly translated) name of the type of this filesystem. * @see nameForType() */ virtual QString name(const QStringList& languages = {}) const; /** * @return the FileSystem's type */ virtual FileSystem::Type type() const; /** * Returns the name of the given filesystem type. If @p languages * is an empty list, uses the translated name of the filesystem, * in the default locale. If languages is {"C"}, an untranslated * string is returned. Passing other lists of language identifiers * may yield unpredicatable results -- see the documentation of * KLocalizedString() for details on the way toString() is used. * Returns a single QString with the name. */ static QString nameForType(FileSystem::Type t, const QStringList& languages = {}); static QList types(); static FileSystem::Type typeForName(const QString& s, const QStringList& languages = {}); static FileSystem::Type detectFileSystem(const QString& partitionPath); static QString detectMountPoint(FileSystem* fs, const QString& partitionPath); static bool detectMountStatus(FileSystem* fs, const QString& partitionPath); /**< @return true if this FileSystem can be mounted */ virtual bool canMount(const QString& deviceNode, const QString& mountPoint) const; virtual bool canUnmount(const QString&) const { return true; /**< @return true if this FileSystem can be unmounted */ } virtual QString mountTitle() const; virtual QString unmountTitle() const; virtual bool mount(Report& report, const QString& deviceNode, const QString& mountPoint); virtual bool unmount(Report& report, const QString& deviceNode); /**< @return the FileSystem's first sector */ qint64 firstSector() const; /**< @return the FileSystem's last sector */ qint64 lastSector() const; qint64 length() const { return lastSector() - firstSector() + 1; /**< @return the FileSystem's length */ } qint64 firstByte() const { return firstSector() * sectorSize(); /**< @return the FileSystem's first byte */ } qint64 lastByte() const { return firstByte() + length() * sectorSize() - 1; /**< @return the FileSystem's last byte */ } /**< @param s the new first sector */ void setFirstSector(qint64 s); /**< @param s the new last sector */ void setLastSector(qint64 s); void move(qint64 newStartSector); /**< @return the FileSystem's label */ const QString& label() const; /**< @return the sector size in the underlying Device */ qint64 sectorSize() const; /**< @return the sectors in use on the FileSystem */ qint64 sectorsUsed() const; /**< @return the FileSystem's UUID */ const QString& uuid() const; /**< @param s the new value for sector size */ void setSectorSize(qint64 s); /**< @param s the new value for sectors in use */ void setSectorsUsed(qint64 s); /**< @param s the new label */ void setLabel(const QString& s); /**< @param s the new UUID */ void setUUID(const QString& s); protected: static bool findExternal(const QString& cmdName, const QStringList& args = QStringList(), int exptectedCode = 1); std::unique_ptr d; }; Q_DECLARE_OPERATORS_FOR_FLAGS(FileSystem::CommandSupportTypes) #endif diff --git a/src/fs/filesystem_p.h b/src/fs/filesystem_p.h index ed410ba..3c8b8cf 100644 --- a/src/fs/filesystem_p.h +++ b/src/fs/filesystem_p.h @@ -1,36 +1,34 @@ /************************************************************************* * Copyright (C) 2018 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_FILESYSTEM_P_H #define KPMCORE_FILESYSTEM_P_H #include "fs/filesystem.h" -#include - class FileSystemPrivate { public: FileSystem::Type m_Type; qint64 m_FirstSector; qint64 m_LastSector; qint64 m_SectorSize; qint64 m_SectorsUsed; QString m_Label; QString m_UUID; }; #endif diff --git a/src/fs/filesystemfactory.h b/src/fs/filesystemfactory.h index 6679bbc..5d4ce18 100644 --- a/src/fs/filesystemfactory.h +++ b/src/fs/filesystemfactory.h @@ -1,53 +1,50 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_FILESYSTEMFACTORY_H #define KPMCORE_FILESYSTEMFACTORY_H #include "fs/filesystem.h" #include "util/libpartitionmanagerexport.h" #include -#include - -class QString; /** Factory to create instances of FileSystem. @author Volker Lanz */ class LIBKPMCORE_EXPORT FileSystemFactory { public: /** map of FileSystem::Types to pointers of FileSystem */ typedef QMap FileSystems; private: FileSystemFactory(); public: static void init(); static FileSystem* create(FileSystem::Type t, qint64 firstsector, qint64 lastsector, qint64 sectorSize, qint64 sectorsused = -1, const QString& label = QString(), const QString& uuid = QString()); static FileSystem* create(const FileSystem& other); static FileSystem* cloneWithNewType(FileSystem::Type newType, const FileSystem& other); static const FileSystems& map(); private: static FileSystems m_FileSystems; }; #endif diff --git a/src/fs/hfs.cpp b/src/fs/hfs.cpp index 15677fc..96e2d5a 100644 --- a/src/fs/hfs.cpp +++ b/src/fs/hfs.cpp @@ -1,95 +1,93 @@ /************************************************************************* * Copyright (C) 2008,2011 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/hfs.h" #include "util/externalcommand.h" #include "util/capacity.h" -#include - namespace FS { FileSystem::CommandSupportType hfs::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfs::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfs::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfs::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfs::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfs::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfs::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfs::m_Backup = FileSystem::cmdSupportNone; hfs::hfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Hfs) { } void hfs::init() { m_GetLabel = cmdSupportCore; m_Create = findExternal(QStringLiteral("hformat")) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("hfsck")) ? cmdSupportFileSystem : cmdSupportNone; m_Move = m_Copy = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Backup = cmdSupportCore; } bool hfs::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 hfs::supportToolName() const { return SupportTool(QStringLiteral("hfsutils"), QUrl(QStringLiteral("http://www.mars.org/home/rob/proj/hfs/"))); } qint64 hfs::maxCapacity() const { return 2 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB); } int hfs::maxLabelLength() const { return 27; } bool hfs::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("hfsck"), { QStringLiteral("-v"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool hfs::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("hformat"), { deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/hfs.h b/src/fs/hfs.h index 780dc72..8650aeb 100644 --- a/src/fs/hfs.h +++ b/src/fs/hfs.h @@ -1,90 +1,85 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_HFS_H) - +#ifndef KPMCORE_HFS_H #define KPMCORE_HFS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** An hfs file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT hfs : public FileSystem { public: hfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: void init() override; bool check(Report& report, const QString& deviceNode) const override; bool create(Report& report, const QString& deviceNode) override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportCreate() const override { return m_Create; } 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; } qint64 maxCapacity() const override; int maxLabelLength() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; public: static CommandSupportType m_GetUsed; static CommandSupportType m_GetLabel; static CommandSupportType m_Create; static CommandSupportType m_Shrink; static CommandSupportType m_Move; static CommandSupportType m_Check; static CommandSupportType m_Copy; static CommandSupportType m_Backup; }; } #endif diff --git a/src/fs/hfsplus.cpp b/src/fs/hfsplus.cpp index 81341ff..f70f1e2 100644 --- a/src/fs/hfsplus.cpp +++ b/src/fs/hfsplus.cpp @@ -1,96 +1,94 @@ /************************************************************************* * Copyright (C) 2008,2011 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/hfsplus.h" #include "util/externalcommand.h" #include "util/capacity.h" -#include - namespace FS { FileSystem::CommandSupportType hfsplus::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfsplus::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfsplus::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfsplus::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfsplus::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfsplus::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfsplus::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hfsplus::m_Backup = FileSystem::cmdSupportNone; hfsplus::hfsplus(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::HfsPlus) { } void hfsplus::init() { m_Check = findExternal(QStringLiteral("fsck.hfsplus")) ? cmdSupportFileSystem : cmdSupportNone; m_Create = findExternal(QStringLiteral("mkfs.hfsplus")) ? cmdSupportFileSystem : cmdSupportNone; m_Copy = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Backup = cmdSupportCore; m_GetLabel = cmdSupportCore; } bool hfsplus::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 hfsplus::supportToolName() const { return SupportTool(QStringLiteral("diskdev_cmds"), QUrl(QStringLiteral("http://opendarwin.org"))); } qint64 hfsplus::maxCapacity() const { return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } int hfsplus::maxLabelLength() const { return 63; } bool hfsplus::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("fsck.hfsplus"), { deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool hfsplus::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.hfsplus"), { deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/hfsplus.h b/src/fs/hfsplus.h index 8f3e2d4..82379c3 100644 --- a/src/fs/hfsplus.h +++ b/src/fs/hfsplus.h @@ -1,90 +1,85 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_HFSPLUS_H) - +#ifndef KPMCORE_HFSPLUS_H #define KPMCORE_HFSPLUS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** An hfsplus file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT hfsplus : public FileSystem { public: hfsplus(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: void init() override; bool check(Report& report, const QString& deviceNode) const override; bool create(Report& report, const QString& deviceNode) override; CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportShrink() const override { return m_Shrink; } CommandSupportType supportMove() const override { return m_Move; } CommandSupportType supportCheck() const override { return m_Check; } CommandSupportType supportCreate() const override { return m_Create; } CommandSupportType supportCopy() const override { return m_Copy; } CommandSupportType supportBackup() const override { return m_Backup; } qint64 maxCapacity() const override; int maxLabelLength() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; public: static CommandSupportType m_GetLabel; static CommandSupportType m_GetUsed; static CommandSupportType m_Shrink; static CommandSupportType m_Move; static CommandSupportType m_Create; static CommandSupportType m_Check; static CommandSupportType m_Copy; static CommandSupportType m_Backup; }; } #endif diff --git a/src/fs/hpfs.cpp b/src/fs/hpfs.cpp index 55c41a1..3a8ec81 100644 --- a/src/fs/hpfs.cpp +++ b/src/fs/hpfs.cpp @@ -1,48 +1,46 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * 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/hpfs.h" #include "util/capacity.h" -#include - namespace FS { FileSystem::CommandSupportType hpfs::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType hpfs::m_GetUUID = FileSystem::cmdSupportNone; hpfs::hpfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Hpfs) { } qint64 hpfs::maxCapacity() const { return 2 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB); } } diff --git a/src/fs/hpfs.h b/src/fs/hpfs.h index 7bbb9ba..3269c71 100644 --- a/src/fs/hpfs.h +++ b/src/fs/hpfs.h @@ -1,101 +1,96 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * 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_HPFS_H) - +#ifndef KPMCORE_HPFS_H #define KPMCORE_HPFS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A hpfs file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT hpfs : public FileSystem { public: hpfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } 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 supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportUpdateUUID() const override { return m_UpdateUUID; } CommandSupportType supportGetUUID() const override { return m_GetUUID; } qint64 maxCapacity() const override; bool supportToolFound() const override { return true; } 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; }; } #endif diff --git a/src/fs/iso9660.h b/src/fs/iso9660.h index f6b2192..3c57c1e 100644 --- a/src/fs/iso9660.h +++ b/src/fs/iso9660.h @@ -1,43 +1,40 @@ /************************************************************************* * 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_ISO9660_H) - +#ifndef KPMCORE_ISO9660_H #define KPMCORE_ISO9660_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" class Report; -class QString; - namespace FS { /** A iso9660 file system. @author Andrius Štikonas */ class LIBKPMCORE_EXPORT iso9660 : public FileSystem { public: iso9660(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); }; } #endif diff --git a/src/fs/jfs.cpp b/src/fs/jfs.cpp index dfb90a0..05eb2e5 100644 --- a/src/fs/jfs.cpp +++ b/src/fs/jfs.cpp @@ -1,199 +1,198 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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/jfs.h" #include "util/externalcommand.h" #include "util/report.h" #include "util/capacity.h" #include -#include #include #include namespace FS { FileSystem::CommandSupportType jfs::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType jfs::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType jfs::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType jfs::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType jfs::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType jfs::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType jfs::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType jfs::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType jfs::m_SetLabel = FileSystem::cmdSupportNone; jfs::jfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Jfs) { } void jfs::init() { m_GetUsed = findExternal(QStringLiteral("jfs_debugfs")) ? cmdSupportFileSystem : cmdSupportNone; m_GetLabel = cmdSupportCore; m_SetLabel = findExternal(QStringLiteral("jfs_tune"), { QStringLiteral("-V") }) ? cmdSupportFileSystem : cmdSupportNone; m_Create = findExternal(QStringLiteral("mkfs.jfs"),{ QStringLiteral("-V") }) ? cmdSupportFileSystem : cmdSupportNone; m_Grow = m_Check = findExternal(QStringLiteral("fsck.jfs"), { QStringLiteral("-V") }) ? cmdSupportFileSystem : cmdSupportNone; m_Copy = m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Backup = cmdSupportCore; } bool jfs::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 jfs::supportToolName() const { return SupportTool(QStringLiteral("jfsutils"), QUrl(QStringLiteral("http://jfs.sourceforge.net/"))); } qint64 jfs::minCapacity() const { return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } qint64 jfs::maxCapacity() const { return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB); } int jfs::maxLabelLength() const { return 11; } qint64 jfs::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("jfs_debugfs"), QStringList() << deviceNode); if (cmd.write(QByteArrayLiteral("dm")) && cmd.start()) { qint64 blockSize = -1; QRegularExpression re(QStringLiteral("Block Size: (\\d+)")); QRegularExpressionMatch reBlockSize = re.match(cmd.output()); if (reBlockSize.hasMatch()) blockSize = reBlockSize.captured(1).toLongLong(); qint64 nBlocks = -1; re.setPattern(QStringLiteral("dn_mapsize:\\s+0x(\\x+)")); QRegularExpressionMatch renBlocks = re.match(cmd.output()); bool ok = false; if (renBlocks.hasMatch()) { nBlocks = renBlocks.captured(1).toLongLong(&ok, 16); if (!ok) nBlocks = -1; } qint64 nFree = -1; re.setPattern(QStringLiteral("dn_nfree:\\s+0x(\\x+)")); QRegularExpressionMatch renFree = re.match(cmd.output()); if (renFree.hasMatch()) { nFree = renFree.captured(1).toLongLong(&ok, 16); if (!ok) nFree = -1; } if (nBlocks > -1 && blockSize > -1 && nFree > -1) return (nBlocks - nFree) * blockSize; } return -1; } bool jfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("jfs_tune"), { QStringLiteral("-L"), newLabel, deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool jfs::writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel) { Q_UNUSED(mountPoint) return writeLabel(report, deviceNode, newLabel); } bool jfs::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("fsck.jfs"), { QStringLiteral("-f"), deviceNode }); return cmd.run(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 1); } bool jfs::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.jfs"), { QStringLiteral("-q"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool jfs::resize(Report& report, const QString& deviceNode, qint64) const { QTemporaryDir tempDir; if (!tempDir.isValid()) { report.line() << xi18nc("@info:progress", "Resizing JFS file system on partition %1 failed: Could not create temp dir.", deviceNode); return false; } bool rval = false; ExternalCommand mountCmd(report, QStringLiteral("mount"), { QStringLiteral("--verbose"), QStringLiteral("--type"), QStringLiteral("jfs"), deviceNode, tempDir.path() }); if (mountCmd.run(-1)) { ExternalCommand resizeMountCmd(report, QStringLiteral("mount"), { QStringLiteral("--verbose"), QStringLiteral("--type"), QStringLiteral("jfs"), QStringLiteral("--options"), QStringLiteral("remount,resize"), deviceNode, tempDir.path() }); if (resizeMountCmd.run(-1) && resizeMountCmd.exitCode() == 0) rval = true; else report.line() << xi18nc("@info:progress", "Resizing JFS file system on partition %1 failed: Remount failed.", deviceNode); ExternalCommand unmountCmd(report, QStringLiteral("umount"), { tempDir.path() }); if (!unmountCmd.run(-1)) report.line() << xi18nc("@info:progress", "Resizing JFS file system on partition %1: Unmount failed.", deviceNode); } else report.line() << xi18nc("@info:progress", "Resizing JFS file system on partition %1 failed: Initial mount failed.", deviceNode); return rval; } bool jfs::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64) const { ExternalCommand resizeMountCmd(report, QStringLiteral("mount"), { QStringLiteral("--verbose"), QStringLiteral("--type"), QStringLiteral("jfs"), QStringLiteral("--options"), QStringLiteral("remount,resize"), deviceNode, mountPoint }); if (resizeMountCmd.run(-1) && resizeMountCmd.exitCode() == 0) return true; report.line() << xi18nc("@info:progress", "Resizing JFS file system on partition %1 failed: Remount failed.", deviceNode); return false; } } diff --git a/src/fs/jfs.h b/src/fs/jfs.h index c67ab27..f49e7aa 100644 --- a/src/fs/jfs.h +++ b/src/fs/jfs.h @@ -1,106 +1,101 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_JFS_H) - +#ifndef KPMCORE_JFS_H #define KPMCORE_JFS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A JFS file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT jfs : public FileSystem { public: jfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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 resize(Report& report, const QString& deviceNode, qint64 length) const override; bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel) override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportCreate() const override { return m_Create; } CommandSupportType supportGrow() const override { return m_Grow; } CommandSupportType supportGrowOnline() const override { return m_Grow; } 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 supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportSetLabelOnline() const override { return m_SetLabel; } qint64 minCapacity() const override; qint64 maxCapacity() const override; int maxLabelLength() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; public: static CommandSupportType m_GetUsed; static CommandSupportType m_GetLabel; static CommandSupportType m_Create; static CommandSupportType m_Grow; static CommandSupportType m_Move; static CommandSupportType m_Check; static CommandSupportType m_Copy; static CommandSupportType m_Backup; static CommandSupportType m_SetLabel; }; } #endif diff --git a/src/fs/linuxraidmember.h b/src/fs/linuxraidmember.h index aa71cdd..5985354 100644 --- a/src/fs/linuxraidmember.h +++ b/src/fs/linuxraidmember.h @@ -1,41 +1,39 @@ /************************************************************************* * Copyright (C) 2018 by Caio Carvalho * * * * 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 LINUXRAIDMEMBER_H #define LINUXRAIDMEMBER_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" class Report; -class QString; - namespace FS { /** A linux_raid_member file system. @author Caio Carvalho */ class LIBKPMCORE_EXPORT linuxraidmember : public FileSystem { public: linuxraidmember(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); }; } #endif // LINUXRAIDMEMBER_H diff --git a/src/fs/linuxswap.h b/src/fs/linuxswap.h index d36392b..adc7da6 100644 --- a/src/fs/linuxswap.h +++ b/src/fs/linuxswap.h @@ -1,112 +1,107 @@ /************************************************************************* * Copyright (C) 2008,2009 by Volker Lanz * * * * 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_LINUXSWAP_H) - +#ifndef KPMCORE_LINUXSWAP_H #define KPMCORE_LINUXSWAP_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A linux swap pseudo file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT linuxswap : public FileSystem { public: linuxswap(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: void init() override; bool create(Report& report, const QString& deviceNode) override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel) override; bool copy(Report& report, const QString& targetDeviceNode, const QString& sourceDeviceNode) const override; bool updateUUID(Report& report, const QString& deviceNode) const override; qint64 readUsedCapacity(const QString& deviceNode) const override; bool canMount(const QString& deviceNode, const QString& mountPoint) const override; bool mount(Report& report, const QString& deviceNode, const QString& mountPoint) override; bool unmount(Report& report, const QString& deviceNode) override; QString mountTitle() const override; QString unmountTitle() const override; 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 supportCopy() const override { return m_Copy; } CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportSetLabelOnline() const override { return m_SetLabel; } CommandSupportType supportUpdateUUID() const override { return m_UpdateUUID; } CommandSupportType supportGetUUID() const override { return m_GetUUID; } int maxLabelLength() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; public: static CommandSupportType m_Create; static CommandSupportType m_Grow; static CommandSupportType m_Shrink; static CommandSupportType m_Move; static CommandSupportType m_Copy; static CommandSupportType m_SetLabel; static CommandSupportType m_GetLabel; static CommandSupportType m_GetUsed; static CommandSupportType m_UpdateUUID; static CommandSupportType m_GetUUID; }; } #endif diff --git a/src/fs/luks.cpp b/src/fs/luks.cpp index 6215554..de67b23 100644 --- a/src/fs/luks.cpp +++ b/src/fs/luks.cpp @@ -1,698 +1,697 @@ /************************************************************************* * Copyright (C) 2012 by Volker Lanz * * Copyright (C) 2013-2017 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/lvm2_pv.h" #include "fs/filesystemfactory.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/helpers.h" #include "util/report.h" #include #include #include #include #include #include #include #include #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::Type t) : FileSystem(firstsector, lastsector, sectorsused, label, t) , m_innerFs(nullptr) , m_isCryptOpen(false) , m_cryptsetupFound(m_Create != cmdSupportNone) , m_isMounted(false) , m_KeySize(-1) , m_PayloadOffset(-1) { } luks::~luks() { delete m_innerFs; } void luks::init() { CommandSupportType cryptsetupFound = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone; m_Create = cryptsetupFound; m_UpdateUUID = cryptsetupFound; m_GetUUID = cryptsetupFound; m_Grow = cryptsetupFound; m_Shrink = cryptsetupFound; m_SetLabel = cmdSupportNone; m_GetLabel = cmdSupportFileSystem; m_Check = cmdSupportCore; m_Copy = cmdSupportCore; m_Move = cmdSupportCore; m_Backup = cmdSupportCore; m_GetUsed = cmdSupportNone; // libparted does not support LUKS, we do this as a special case } void luks::scan(const QString& deviceNode) { getMapperName(deviceNode); getLuksInfo(deviceNode); } bool luks::supportToolFound() const { return m_cryptsetupFound && ((m_isCryptOpen && m_innerFs) ? m_innerFs->supportToolFound() : true); } FileSystem::SupportTool luks::supportToolName() const { if (m_isCryptOpen && m_innerFs && m_cryptsetupFound) return m_innerFs->supportToolName(); return SupportTool(QStringLiteral("cryptsetup"), QUrl(QStringLiteral("https://code.google.com/p/cryptsetup/"))); } bool luks::create(Report& report, const QString& deviceNode) { Q_ASSERT(m_innerFs); Q_ASSERT(!m_passphrase.isEmpty()); ExternalCommand createCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("-s"), QStringLiteral("512"), QStringLiteral("--batch-mode"), QStringLiteral("--force-password"), QStringLiteral("--type"), QStringLiteral("luks1"), QStringLiteral("luksFormat"), deviceNode }); if (!( createCmd.write(m_passphrase.toLocal8Bit() + '\n') && createCmd.start(-1) && createCmd.exitCode() == 0)) { return false; } ExternalCommand openCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("open"), deviceNode, suggestedMapperName(deviceNode) }); if (!( openCmd.write(m_passphrase.toLocal8Bit() + '\n') && openCmd.start(-1))) return false; setPayloadSize(); scan(deviceNode); if (mapperName().isEmpty()) return false; if (!m_innerFs->create(report, mapperName())) return false; return true; } QString luks::mountTitle() const { return xi18nc("@title:menu", "Mount"); } QString luks::unmountTitle() const { return xi18nc("@title:menu", "Unmount"); } QString luks::cryptOpenTitle() const { return xi18nc("@title:menu", "Unlock"); } QString luks::cryptCloseTitle() const { return xi18nc("@title:menu", "Lock"); } void luks::setPassphrase(const QString& passphrase) { m_passphrase = passphrase; } QString luks::passphrase() const { return m_passphrase; } bool luks::canMount(const QString&, const QString& mountPoint) const { return m_isCryptOpen && !m_isMounted && m_innerFs && m_innerFs->canMount(mapperName(), mountPoint); } bool luks::canUnmount(const QString&) const { return m_isCryptOpen && m_isMounted && m_innerFs && m_innerFs->canUnmount(mapperName()); } 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 && supportToolFound(); } bool luks::canCryptClose(const QString&) const { return m_isCryptOpen && !m_isMounted && m_cryptsetupFound; } bool luks::isCryptOpen() const { return m_isCryptOpen; } void luks::setCryptOpen(bool cryptOpen) { m_isCryptOpen = cryptOpen; } bool luks::cryptOpen(QWidget* parent, const QString& deviceNode) { if (m_isCryptOpen) { if (!mapperName().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; } } KPasswordDialog dlg( parent ); dlg.setPrompt(i18n("Enter passphrase for %1:", deviceNode)); if( !dlg.exec() ) return false; QString passphrase = dlg.password(); ExternalCommand openCmd(QStringLiteral("cryptsetup"), { QStringLiteral("open"), QStringLiteral("--tries"), QStringLiteral("1"), deviceNode, suggestedMapperName(deviceNode) }); if (!( openCmd.write(passphrase.toLocal8Bit() + '\n') && openCmd.start(-1) && openCmd.exitCode() == 0) ) return false; if (m_innerFs) { delete m_innerFs; m_innerFs = nullptr; } scan(deviceNode); if (mapperName().isEmpty()) return false; loadInnerFileSystem(mapperName()); m_isCryptOpen = (m_innerFs != nullptr); if (!m_isCryptOpen) return false; for (auto &p : LVM::pvList::list()) if (p.isLuks() && p.partition()->deviceNode() == deviceNode && p.partition()->fileSystem().type() == FileSystem::Type::Lvm2_PV) p.setLuks(false); m_passphrase = passphrase; return true; } 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("close"), mapperName() }); if (!(cmd.run(-1) && cmd.exitCode() == 0)) return false; delete m_innerFs; m_innerFs = nullptr; m_passphrase.clear(); setLabel(FileSystem::readLabel(deviceNode)); setUUID(readUUID(deviceNode)); setSectorsUsed(-1); m_isCryptOpen = (m_innerFs != nullptr); for (auto &p : LVM::pvList::list()) if (!p.isLuks() && p.partition()->deviceNode() == deviceNode) p.setLuks(true); return true; } void luks::loadInnerFileSystem(const QString& mapperNode) { Q_ASSERT(!m_innerFs); FileSystem::Type innerFsType = detectFileSystem(mapperNode); m_innerFs = FileSystemFactory::cloneWithNewType(innerFsType, *this); setLabel(m_innerFs->readLabel(mapperNode)); setUUID(m_innerFs->readUUID(mapperNode)); if (m_innerFs->supportGetUsed() == FileSystem::cmdSupportFileSystem) setSectorsUsed(static_cast(std::ceil((m_innerFs->readUsedCapacity(mapperNode) + payloadOffset()) / static_cast(sectorSize()) ))); m_innerFs->scan(mapperNode); } void luks::createInnerFileSystem(FileSystem::Type type) { Q_ASSERT(!m_innerFs); m_innerFs = FileSystemFactory::cloneWithNewType(type, *this); } bool luks::check(Report& report, const QString&) const { Q_ASSERT(m_innerFs); if (mapperName().isEmpty()) return false; return m_innerFs->check(report, mapperName()); } qint64 luks::readUsedCapacity(const QString& deviceNode) const { if (!m_isCryptOpen) return -1; if (m_innerFs) return m_innerFs->readUsedCapacity(deviceNode); return -1; } bool luks::mount(Report& report, 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); if (mapperName().isEmpty()) return false; if (m_innerFs->canMount(mapperName(), mountPoint)) { if (m_innerFs->mount(report, mapperName(), mountPoint)) { m_isMounted = true; const QStorageInfo storageInfo = QStorageInfo(mountPoint); if (storageInfo.isValid() && !mountPoint.isEmpty()) setSectorsUsed( (storageInfo.bytesTotal() - storageInfo.bytesFree() + payloadOffset()) / sectorSize()); return true; } } else { ExternalCommand mountCmd( report, QStringLiteral("mount"), { QStringLiteral("--verbose"), mapperName(), mountPoint }); if (mountCmd.run() && mountCmd.exitCode() == 0) { m_isMounted = true; return true; } } return false; } bool luks::unmount(Report& report, 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); if (mapperName().isEmpty()) return false; if (m_innerFs->canUnmount(mapperName())) { if (m_innerFs->unmount(report, mapperName())) { m_isMounted = false; return true; } } else { ExternalCommand unmountCmd( report, QStringLiteral("umount"), { QStringLiteral("--verbose"), QStringLiteral("--all-targets"), mapperName() }); 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::Type::Luks; } QString luks::suggestedMapperName(const QString& deviceNode) const { return QStringLiteral("luks-") + readOuterUUID(deviceNode); } QString luks::readLabel(const QString& deviceNode) const { if (m_isCryptOpen && m_innerFs) return m_innerFs->readLabel(mapperName()); return FileSystem::readLabel(deviceNode); } bool luks::writeLabel(Report& report, const QString&, const QString& newLabel) { Q_ASSERT(m_innerFs); return m_innerFs->writeLabel(report, mapperName(), newLabel); } bool luks::resize(Report& report, const QString& deviceNode, qint64 newLength) const { Q_ASSERT(m_innerFs); if (mapperName().isEmpty()) return false; if ( newLength - length() * sectorSize() > 0 ) { ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("resize"), mapperName() }); report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition %1.", deviceNode); if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0) return m_innerFs->resize(report, mapperName(), m_PayloadSize); } else if (m_innerFs->resize(report, mapperName(), m_PayloadSize)) { ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("--size"), QString::number(m_PayloadSize / 512), // LUKS1 payload length is specified in multiples of 512 bytes QStringLiteral("resize"), mapperName() }); report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition %1.", deviceNode); if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0) return true; } report.line() << xi18nc("@info:progress", "Resizing encrypted file system on partition %1 failed.", deviceNode); return false; } bool luks::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const { Q_UNUSED(mountPoint) return resize(report, deviceNode, length); } QString luks::readUUID(const QString& deviceNode) const { QString outerUuid = readOuterUUID(deviceNode); if (m_isCryptOpen && m_innerFs) return m_innerFs->readUUID(mapperName()); return outerUuid; } QString luks::readOuterUUID(const QString &deviceNode) const { if ( deviceNode.isEmpty() ) return QString(); ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksUUID"), deviceNode }); if (cmd.run()) { if ( cmd.exitCode() ) { qWarning() << "Cannot get luksUUID for device" << deviceNode << "\tcryptsetup exit code" << cmd.exitCode() << "\toutput:" << cmd.output().trimmed(); return QString(); } QString outerUuid = cmd.output().trimmed(); const_cast< QString& >( m_outerUuid ) = outerUuid; return outerUuid; } return QStringLiteral("---"); } bool luks::updateUUID(Report& report, const QString& deviceNode) const { const QString uuid = QUuid::createUuid().toString().remove(QRegularExpression(QStringLiteral("\\{|\\}"))); ExternalCommand cmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("luksUUID"), deviceNode, QStringLiteral("--uuid"), uuid }); return cmd.run(-1) && cmd.exitCode() == 0; } void luks::getMapperName(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("lsblk"), { QStringLiteral("--list"), QStringLiteral("--noheadings"), QStringLiteral("--paths"), QStringLiteral("--json"), QStringLiteral("--output"), QStringLiteral("type,name"), deviceNode }); m_MapperName = QString(); if (cmd.run(-1) && cmd.exitCode() == 0) { const QJsonDocument jsonDocument = QJsonDocument::fromJson(cmd.rawOutput()); QJsonObject jsonObject = jsonDocument.object(); const QJsonArray jsonArray = jsonObject[QLatin1String("blockdevices")].toArray(); for (const auto &deviceLine : jsonArray) { QJsonObject deviceObject = deviceLine.toObject(); if (deviceObject[QLatin1String("type")].toString() == QLatin1String("crypt")) { m_MapperName = deviceObject[QLatin1String("name")].toString(); break; } } } } void luks::getLuksInfo(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksDump"), deviceNode }); if (cmd.run(-1) && cmd.exitCode() == 0) { QRegularExpression re(QStringLiteral("Cipher name:\\s+(\\w+)")); QRegularExpressionMatch rem = re.match(cmd.output()); if (rem.hasMatch()) m_CipherName = rem.captured(1); else m_CipherName = QLatin1String("---"); re.setPattern(QStringLiteral("Cipher mode:\\s+(\\w+)")); rem = re.match(cmd.output()); if (rem.hasMatch()) m_CipherMode = rem.captured(1); else m_CipherMode = QLatin1String("---"); re.setPattern(QStringLiteral("Hash spec:\\s+(\\w+)")); rem = re.match(cmd.output()); if (rem.hasMatch()) m_HashName = rem.captured(1); else m_HashName = QLatin1String("---"); re.setPattern(QStringLiteral("MK bits:\\s+(\\d+)")); rem = re.match(cmd.output()); if (rem.hasMatch()) m_KeySize = rem.captured(1).toLongLong(); else m_KeySize = -1; re.setPattern(QStringLiteral("Payload offset:\\s+(\\d+)")); rem = re.match(cmd.output()); if (rem.hasMatch()) m_PayloadOffset = rem.captured(1).toLongLong() * 512; // assuming LUKS sector size is 512; else m_PayloadOffset = -1; } else { m_CipherName = QLatin1String("---"); m_CipherMode = QLatin1String("---"); m_HashName = QLatin1String("---"); m_KeySize = -1; m_PayloadOffset = -1; } } QString luks::outerUuid() const { return m_outerUuid; } bool luks::canEncryptType(FileSystem::Type type) { switch (type) { case Type::Btrfs: case Type::F2fs: case Type::Ext2: case Type::Ext3: case Type::Ext4: case Type::Jfs: case Type::LinuxSwap: case Type::Lvm2_PV: case Type::Nilfs2: case Type::ReiserFS: case Type::Reiser4: case Type::Xfs: case Type::Zfs: return true; default: return false; } } void luks::initLUKS() { setPayloadSize(); QString mapperNode = mapperName(); bool isCryptOpen = !mapperNode.isEmpty(); setCryptOpen(isCryptOpen); if (isCryptOpen) { loadInnerFileSystem(mapperNode); setMounted(detectMountStatus(innerFS(), mapperNode)); } } void luks::setPayloadSize() { ExternalCommand dmsetupCmd(QStringLiteral("dmsetup"), { QStringLiteral("table"), mapperName() }); dmsetupCmd.run(); QRegularExpression re(QStringLiteral("\\d+ (\\d+)")); QRegularExpressionMatch rem = re.match(dmsetupCmd.output()); if (rem.hasMatch()) m_PayloadSize = rem.captured(1).toLongLong() * sectorSize(); } bool luks::testPassphrase(const QString& deviceNode, const QString& passphrase) const { ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("open"), QStringLiteral("--tries"), QStringLiteral("1"), QStringLiteral("--test-passphrase"), deviceNode }); if (cmd.write(passphrase.toLocal8Bit() + '\n') && cmd.start(-1) && cmd.exitCode() == 0) return true; return false; } } diff --git a/src/fs/luks.h b/src/fs/luks.h index 7dddba1..2ead990 100644 --- a/src/fs/luks.h +++ b/src/fs/luks.h @@ -1,231 +1,228 @@ /************************************************************************* * 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 .* *************************************************************************/ #ifndef KPMCORE_LUKS_H #define KPMCORE_LUKS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; class QWidget; 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, FileSystem::Type t = FileSystem::Type::Luks); ~luks() override; enum class KeyLocation { unknown, dmcrypt, keyring }; public: void init() override; void scan(const QString& deviceNode) override; qint64 readUsedCapacity(const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportCreate() const override { return m_Create; } CommandSupportType supportGrow() const override { if (!m_isCryptOpen) return cmdSupportNone; if (m_Grow && m_innerFs) return m_innerFs->supportGrow(); return cmdSupportNone; } CommandSupportType supportGrowOnline() const override { if (!m_isCryptOpen) return cmdSupportNone; if (m_Grow && m_innerFs) return m_innerFs->supportGrowOnline(); return cmdSupportNone; } CommandSupportType supportShrink() const override { if (!m_isCryptOpen) return cmdSupportNone; if (m_Shrink && m_innerFs) return m_innerFs->supportShrink(); return cmdSupportNone; } CommandSupportType supportShrinkOnline() const override { if (!m_isCryptOpen) return cmdSupportNone; if (m_Shrink && m_innerFs) return m_innerFs->supportShrinkOnline(); return cmdSupportNone; } CommandSupportType supportMove() const override { if (m_isCryptOpen) return cmdSupportNone; return m_Move; } CommandSupportType supportCheck() const override { if (!m_isCryptOpen) return cmdSupportNone; if (m_Check && m_innerFs) return m_innerFs->supportCheck(); return cmdSupportNone; } CommandSupportType supportCheckOnline() const override { if (!m_isCryptOpen) return cmdSupportNone; if (m_Check && m_innerFs) return m_innerFs->supportCheckOnline(); return cmdSupportNone; } CommandSupportType supportCopy() const override { if (m_isCryptOpen) return cmdSupportNone; return m_Copy; } CommandSupportType supportBackup() const override { return m_Backup; } CommandSupportType supportSetLabel() const override { if (m_Check && m_innerFs) return m_innerFs->supportSetLabel(); return cmdSupportNone; } CommandSupportType supportUpdateUUID() const override { return m_UpdateUUID; } CommandSupportType supportGetUUID() const override { return m_GetUUID; } bool check(Report& report, const QString& deviceNode) const override; bool create(Report& report, const QString& deviceNode) override; SupportTool supportToolName() const override; bool supportToolFound() const override; QString readUUID(const QString& deviceNode) const override; bool updateUUID(Report& report, const QString& deviceNode) const override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override; QString readLabel(const QString& deviceNode) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; QString mountTitle() const override; QString unmountTitle() const override; QString cryptOpenTitle() const; QString cryptCloseTitle() const; void setPassphrase(const QString&); QString passphrase() const; bool canMount(const QString&, const QString&) const override; bool canUnmount(const QString&) const override; 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(QWidget* parent, const QString& deviceNode); bool cryptClose(const QString& deviceNode); void loadInnerFileSystem(const QString& mapperNode); void createInnerFileSystem(Type type); bool mount(Report& report, const QString& deviceNode, const QString& mountPoint) override; bool unmount(Report& report, const QString& deviceNode) override; FileSystem::Type type() const override; QString suggestedMapperName(const QString& deviceNode) const; void getMapperName(const QString& deviceNode); virtual void getLuksInfo(const QString& deviceNode); FileSystem* innerFS() const { return m_innerFs; } QString outerUuid() const; QString mapperName() const { return m_MapperName; } QString cipherName() const { return m_CipherName; } QString cipherMode() const { return m_CipherMode; } QString hashName() const { return m_HashName; } qint64 keySize() const { return m_KeySize; } qint64 payloadOffset() const { return m_PayloadOffset; } static bool canEncryptType(FileSystem::Type type); void initLUKS(); bool testPassphrase(const QString& deviceNode, const QString& passphrase) const; protected: virtual QString readOuterUUID(const QString& deviceNode) const; void setPayloadSize(); 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; protected: mutable FileSystem* m_innerFs; mutable bool m_isCryptOpen; mutable bool m_cryptsetupFound; QString m_passphrase; bool m_isMounted; QString m_MapperName; QString m_CipherName; QString m_CipherMode; QString m_HashName; qint64 m_KeySize; qint64 m_PayloadOffset; qint64 m_PayloadSize; QString m_outerUuid; luks::KeyLocation m_KeyLocation = KeyLocation::unknown; }; } #endif diff --git a/src/fs/luks2.h b/src/fs/luks2.h index cb014f8..71df99d 100644 --- a/src/fs/luks2.h +++ b/src/fs/luks2.h @@ -1,50 +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) - +#ifndef 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; bool create(Report& report, const QString& deviceNode) override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; FileSystem::Type type() const override; luks::KeyLocation keyLocation(); }; } #endif diff --git a/src/fs/lvm2_pv.cpp b/src/fs/lvm2_pv.cpp index 6a3a4c7..e5e7477 100644 --- a/src/fs/lvm2_pv.cpp +++ b/src/fs/lvm2_pv.cpp @@ -1,310 +1,308 @@ /************************************************************************* * 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/lvm2_pv.h" #include "core/device.h" #include "util/externalcommand.h" #include "util/capacity.h" -#include - #include namespace FS { FileSystem::CommandSupportType lvm2_pv::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType lvm2_pv::m_GetUUID = FileSystem::cmdSupportNone; lvm2_pv::lvm2_pv(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Lvm2_PV) , m_PESize(0) , m_TotalPE(0) , m_AllocatedPE(0) { } void lvm2_pv::init() { CommandSupportType lvmFound = findExternal(QStringLiteral("lvm")) ? cmdSupportFileSystem : cmdSupportNone; m_Create = lvmFound; m_Check = lvmFound; m_Grow = lvmFound; m_Shrink = lvmFound; m_UpdateUUID = lvmFound; m_GetUsed = lvmFound; m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_GetLabel = cmdSupportCore; m_Backup = cmdSupportCore; m_GetUUID = cmdSupportCore; m_GetLabel = cmdSupportNone; m_Copy = cmdSupportNone; // Copying PV can confuse LVM } void lvm2_pv::scan(const QString& deviceNode) { getPESize(deviceNode); m_AllocatedPE = getAllocatedPE(deviceNode); m_TotalPE = getTotalPE(deviceNode); } bool lvm2_pv::supportToolFound() const { return m_GetUsed != cmdSupportNone && m_Create != cmdSupportNone && m_Check != cmdSupportNone && m_UpdateUUID != cmdSupportNone && m_Grow != cmdSupportNone && m_Shrink != cmdSupportNone && m_Move != cmdSupportNone && m_Backup != cmdSupportNone && m_GetUUID != cmdSupportNone; } FileSystem::SupportTool lvm2_pv::supportToolName() const { return SupportTool(QStringLiteral("lvm2"), QUrl(QStringLiteral("http://sourceware.org/lvm2/"))); } qint64 lvm2_pv::maxCapacity() const { return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } qint64 lvm2_pv::readUsedCapacity(const QString& deviceNode) const { QString pvUsed = getpvField(QStringLiteral("pv_used"), deviceNode); QString metadataOffset = getpvField(QStringLiteral("pe_start"), deviceNode); return pvUsed.isEmpty() ? -1 : pvUsed.toLongLong() + metadataOffset.toLongLong(); } bool lvm2_pv::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("pvck"), QStringLiteral("--verbose"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool lvm2_pv::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("pvcreate"), QStringLiteral("--force"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool lvm2_pv::remove(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("pvremove"), QStringLiteral("--force"), QStringLiteral("--force"), QStringLiteral("--yes"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool lvm2_pv::resize(Report& report, const QString& deviceNode, qint64 length) const { bool rval = true; qint64 metadataOffset = getpvField(QStringLiteral("pe_start"), deviceNode).toLongLong(); qint64 lastPE = getTotalPE(deviceNode) - 1; // starts from 0 if (lastPE > 0) { // make sure that the PV is already in a VG qint64 targetPE = (length - metadataOffset) / peSize() - 1; // starts from 0 if (targetPE < lastPE) { //shrinking FS qint64 firstMovedPE = qMax(targetPE + 1, getAllocatedPE(deviceNode)); // starts from 1 ExternalCommand moveCmd(report, QStringLiteral("lvm"), { QStringLiteral("pvmove"), QStringLiteral("--alloc"), QStringLiteral("anywhere"), deviceNode + QStringLiteral(":") + QString::number(firstMovedPE) + QStringLiteral("-") + QString::number(lastPE), deviceNode + QStringLiteral(":") + QStringLiteral("0-") + QString::number(firstMovedPE - 1) }); rval = moveCmd.run(-1) && (moveCmd.exitCode() == 0 || moveCmd.exitCode() == 5); // FIXME: exit code 5: NO data to move } } ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("pvresize"), QStringLiteral("--yes"), QStringLiteral("--setphysicalvolumesize"), QString::number(length) + QStringLiteral("B"), deviceNode }); return rval && cmd.run(-1) && cmd.exitCode() == 0; } bool lvm2_pv::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const { Q_UNUSED(mountPoint) return resize(report, deviceNode, length); } bool lvm2_pv::updateUUID(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("pvchange"), QStringLiteral("--uuid"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } QString lvm2_pv::readUUID(const QString& deviceNode) const { return getpvField(QStringLiteral("pv_uuid"), deviceNode); } bool lvm2_pv::mount(Report& report, const QString& deviceNode, const QString& mountPoint) { Q_UNUSED(report) Q_UNUSED(deviceNode) Q_UNUSED(mountPoint) return false; } bool lvm2_pv::unmount(Report& report, const QString& deviceNode) { Q_UNUSED(deviceNode) Q_UNUSED(report) return false; } bool lvm2_pv::canMount(const QString& deviceNode, const QString& mountPoint) const { Q_UNUSED(deviceNode) Q_UNUSED(mountPoint) return false; } bool lvm2_pv::canUnmount(const QString& deviceNode) const { Q_UNUSED(deviceNode) return false; } qint64 lvm2_pv::getTotalPE(const QString& deviceNode) { QString pvPeCount = getpvField(QStringLiteral("pv_pe_count"), deviceNode); return pvPeCount.isEmpty() ? -1 : pvPeCount.toLongLong(); } qint64 lvm2_pv::getAllocatedPE(const QString& deviceNode) { QString pvPeAllocCount = getpvField(QStringLiteral("pv_pe_alloc_count"), deviceNode); return pvPeAllocCount.isEmpty() ? -1 : pvPeAllocCount.toLongLong(); } void lvm2_pv::getPESize(const QString& deviceNode) { QString vgExtentSize = getpvField(QStringLiteral("vg_extent_size"), deviceNode); m_PESize = vgExtentSize.isEmpty() ? -1 : vgExtentSize.toLongLong(); } /** Get pvs command output with field name * * @param fieldName LVM field name * @param deviceNode path to PV * @return raw output of pvs command, usually with many spaces */ QString lvm2_pv::getpvField(const QString& fieldName, const QString& deviceNode) { QStringList args = { QStringLiteral("pvs"), QStringLiteral("--foreign"), QStringLiteral("--readonly"), QStringLiteral("--noheadings"), QStringLiteral("--units"), QStringLiteral("B"), QStringLiteral("--nosuffix"), QStringLiteral("--options"), fieldName }; if (!deviceNode.isEmpty()) { args << deviceNode; } ExternalCommand cmd(QStringLiteral("lvm"), args, QProcess::ProcessChannelMode::SeparateChannels); if (cmd.run(-1) && cmd.exitCode() == 0) { return cmd.output().trimmed(); } return QString(); } QString lvm2_pv::getVGName(const QString& deviceNode) { return getpvField(QStringLiteral("vg_name"), deviceNode); } QList lvm2_pv::getPVinNode(const PartitionNode* parent) { QList partitions; if (parent == nullptr) return partitions; for (const auto &node : parent->children()) { const Partition* p = dynamic_cast(node); if (p == nullptr) continue; if (node->children().size() > 0) partitions.append(getPVinNode(node)); // FIXME: reenable newly created PVs (before applying) once everything works if(p->fileSystem().type() == FileSystem::Type::Lvm2_PV && p->deviceNode() == p->partitionPath()) partitions.append(LvmPV(p->mountPoint(), p)); if(p->fileSystem().type() == FileSystem::Type::Luks && p->deviceNode() == p->partitionPath()) partitions.append(LvmPV(p->mountPoint(), p, true)); } return partitions; } /** construct a list of Partition objects for LVM PVs that are either unused or belong to some VG. * * @param devices list of Devices which we scan for LVM PVs * @return list of LVM PVs */ QList lvm2_pv::getPVs(const QList& devices) { QList partitions; for (auto const &d : devices) partitions.append(getPVinNode(d->partitionTable())); return partitions; } } namespace LVM { QList pvList::m_list; } LvmPV::LvmPV(const QString vgName, const Partition* p, bool isLuks) : m_vgName(vgName) , m_p(p) , m_isLuks(isLuks) { } diff --git a/src/fs/lvm2_pv.h b/src/fs/lvm2_pv.h index 15bbd92..50066e5 100644 --- a/src/fs/lvm2_pv.h +++ b/src/fs/lvm2_pv.h @@ -1,202 +1,198 @@ /************************************************************************* * 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 .* *************************************************************************/ -#if !defined(KPMCORE_LVM2_PV_H) - +#ifndef KPMCORE_LVM2_PV_H #define KPMCORE_LVM2_PV_H #include "util/libpartitionmanagerexport.h" #include "core/partition.h" #include "fs/filesystem.h" -#include - class Report; -class QString; /** Stores information about LVM PV or potentially encrypted LVM PV * @author Andrius Štikonas */ class LvmPV { public: LvmPV(const QString vgName, const Partition* p, bool isLuks = false); const QString vgName() const { return m_vgName; } QPointer partition() const { return m_p; } bool isLuks() const { return m_isLuks; } void setLuks(bool luks) { m_isLuks = luks; } private: QString m_vgName; QPointer m_p; bool m_isLuks; }; namespace LVM { /** Class to access a global LVM PV list. @author Caio Carvalho */ class LIBKPMCORE_EXPORT pvList { public: static QList &list() { return m_list; } private: pvList() { } private: static QList m_list; }; } namespace FS { /** LVM2 physical volume. @author Andrius Štikonas */ class LIBKPMCORE_EXPORT lvm2_pv : public FileSystem { public: lvm2_pv(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: void init() override; void scan(const QString& deviceNode) 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 remove(Report& report, const QString& deviceNode) const override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override; // bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool updateUUID(Report& report, const QString& deviceNode) const override; QString readUUID(const QString& deviceNode) const override; bool canMount(const QString& deviceNode, const QString& mountPoint) const override; bool canUnmount(const QString& deviceNode) const override; bool mount(Report& report, const QString& deviceNode, const QString& mountPoint) override; // mountPoint == VG name bool unmount(Report& report, const QString& deviceNode) override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportCreate() const override { return m_Create; } CommandSupportType supportGrow() const override { return m_Grow; } CommandSupportType supportGrowOnline() const override { return m_Grow; } CommandSupportType supportShrink() const override { return m_Shrink; } CommandSupportType supportShrinkOnline() const override { return m_Shrink; } CommandSupportType supportMove() const override { return m_Move; } CommandSupportType supportCheck() const override { return m_Check; } CommandSupportType supportCheckOnline() const override { return m_Check; } CommandSupportType supportCopy() const override { return m_Copy; } CommandSupportType supportBackup() const override { return m_Backup; } CommandSupportType supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportUpdateUUID() const override { return m_UpdateUUID; } CommandSupportType supportGetUUID() const override { return m_GetUUID; } qint64 maxCapacity() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; static QString getpvField(const QString& fieldName, const QString& deviceNode = QString()); static qint64 getTotalPE(const QString& deviceNode); static qint64 getAllocatedPE(const QString& deviceNode); static QString getVGName(const QString& deviceNode); static QList getPVinNode(const PartitionNode* parent); static QList getPVs(const QList& devices); qint64 allocatedPE() const { return m_AllocatedPE; } qint64 freePE() const { return m_TotalPE - m_AllocatedPE; } qint64 totalPE() const { return m_TotalPE; } qint64 peSize() const { return m_PESize; } private: void getPESize(const QString& deviceNode); // return PE size in bytes 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: qint64 m_PESize; qint64 m_TotalPE; qint64 m_AllocatedPE; }; } #endif diff --git a/src/fs/nilfs2.cpp b/src/fs/nilfs2.cpp index 5fd15a1..3c53b3f 100644 --- a/src/fs/nilfs2.cpp +++ b/src/fs/nilfs2.cpp @@ -1,195 +1,194 @@ /************************************************************************* * 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/nilfs2.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/report.h" #include #include -#include #include #include #include namespace FS { FileSystem::CommandSupportType nilfs2::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType nilfs2::m_GetUUID = FileSystem::cmdSupportNone; nilfs2::nilfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Nilfs2) { } void nilfs2::init() { m_Create = findExternal(QStringLiteral("mkfs.nilfs2")) ? cmdSupportFileSystem : cmdSupportNone; m_Check = /*findExternal(QStringLiteral("fsck.nilfs2")) ? cmdSupportFileSystem : */cmdSupportNone; m_GetLabel = cmdSupportCore; m_SetLabel = findExternal(QStringLiteral("nilfs-tune")) ? cmdSupportFileSystem : cmdSupportNone; m_UpdateUUID = findExternal(QStringLiteral("nilfs-tune")) ? cmdSupportFileSystem : cmdSupportNone; m_Grow = findExternal(QStringLiteral("nilfs-resize")) ? cmdSupportFileSystem : cmdSupportNone; m_GetUsed = findExternal(QStringLiteral("nilfs-tune")) ? 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_GetLabel = cmdSupportCore; m_Backup = cmdSupportCore; m_GetUUID = cmdSupportCore; } bool nilfs2::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 nilfs2::supportToolName() const { return SupportTool(QStringLiteral("nilfs2-utils"), QUrl(QStringLiteral("http://code.google.com/p/nilfs2/"))); } qint64 nilfs2::minCapacity() const { return 128 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } qint64 nilfs2::maxCapacity() const { return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } int nilfs2::maxLabelLength() const { return 80; } bool nilfs2::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("fsck.nilfs2"), { deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool nilfs2::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.nilfs2"), { QStringLiteral("-f"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } qint64 nilfs2::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("nilfs-tune"), { QStringLiteral("-l"), deviceNode }); if (cmd.run(-1) && cmd.exitCode() == 0) { QRegularExpression re(QStringLiteral("Block size:\\s+(\\d+)")); QRegularExpressionMatch reBlockSize = re.match(cmd.output()); re.setPattern(QStringLiteral("Device size:\\s+(\\d+)")); QRegularExpressionMatch reDeviceSize = re.match(cmd.output()); re.setPattern(QStringLiteral("Free blocks count:\\s+(\\d+)")); QRegularExpressionMatch reFreeBlocks = re.match(cmd.output()); if (reBlockSize.hasMatch() && reDeviceSize.hasMatch() && reFreeBlocks.hasMatch()) return reDeviceSize.captured(1).toLongLong() - reBlockSize.captured(1).toLongLong() * reFreeBlocks.captured(1).toLongLong(); } return -1; } bool nilfs2::resize(Report& report, const QString& deviceNode, qint64 length) const { QTemporaryDir tempDir; if (!tempDir.isValid()) { report.line() << xi18nc("@info:progress", "Resizing NILFS2 file system on partition %1 failed: Could not create temp dir.", deviceNode); return false; } bool rval = false; ExternalCommand mountCmd(report, QStringLiteral("mount"), { QStringLiteral("--verbose"), QStringLiteral("--types"), QStringLiteral("nilfs2"), deviceNode, tempDir.path() }); if (mountCmd.run(-1) && mountCmd.exitCode() == 0) { ExternalCommand resizeCmd(report, QStringLiteral("nilfs-resize"), { QStringLiteral("--verbose"), QStringLiteral("--assume-yes"), deviceNode, QString::number(length) }); if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0) rval = true; else report.line() << xi18nc("@info:progress", "Resizing NILFS2 file system on partition %1 failed: NILFS2 file system resize failed.", deviceNode); ExternalCommand unmountCmd(report, QStringLiteral("umount"), { tempDir.path() }); if (!unmountCmd.run(-1) && unmountCmd.exitCode() == 0) report.line() << xi18nc("@info:progress", "Resizing NILFS2 file system on partition %1: Unmount failed.", deviceNode); } else report.line() << xi18nc("@info:progress", "Resizing NILFS2 file system on partition %1 failed: Initial mount failed.", deviceNode); return rval; } bool nilfs2::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const { ExternalCommand resizeCmd(report, QStringLiteral("nilfs-resize"), { QStringLiteral("--verbose"), QStringLiteral("--assume-yes"), deviceNode, QString::number(length) }); if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0) return true; report.line() << xi18nc("@info:progress", "Resizing NILFS2 file system on partition %1 failed: NILFS2 file system resize failed.", deviceNode); return false; } bool nilfs2::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("nilfs-tune"), { QStringLiteral("-l"), newLabel, deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool nilfs2::updateUUID(Report& report, const QString& deviceNode) const { QUuid uuid = QUuid::createUuid(); ExternalCommand cmd(report, QStringLiteral("nilfs-tune"), { QStringLiteral("-U"), uuid.toString(), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/nilfs2.h b/src/fs/nilfs2.h index 9432208..dfe0108 100644 --- a/src/fs/nilfs2.h +++ b/src/fs/nilfs2.h @@ -1,120 +1,115 @@ /************************************************************************* * 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 .* *************************************************************************/ -#if !defined(KPMCORE_NILFS2_H) - +#ifndef KPMCORE_NILFS2_H #define KPMCORE_NILFS2_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A nilfs2 file system. @author Andrius Štikonas */ class LIBKPMCORE_EXPORT nilfs2 : public FileSystem { public: nilfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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; qint64 readUsedCapacity(const QString& deviceNode) const override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool updateUUID(Report& report, const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportCreate() const override { return m_Create; } CommandSupportType supportGrow() const override { return m_Grow; } CommandSupportType supportGrowOnline() const override { return m_Grow; } CommandSupportType supportShrink() const override { return m_Shrink; } CommandSupportType supportShrinkOnline() 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 supportSetLabel() const override { return m_SetLabel; } 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; SupportTool supportToolName() const override; bool supportToolFound() const override; 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; }; } #endif diff --git a/src/fs/ntfs.cpp b/src/fs/ntfs.cpp index 8639383..47dc39b 100644 --- a/src/fs/ntfs.cpp +++ b/src/fs/ntfs.cpp @@ -1,208 +1,206 @@ /************************************************************************* * 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/ntfs.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/report.h" #include "util/globallog.h" #include #include -#include -#include #include #include #include namespace FS { FileSystem::CommandSupportType ntfs::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ntfs::m_GetUUID = FileSystem::cmdSupportNone; ntfs::ntfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ntfs) { } void ntfs::init() { m_Shrink = m_Grow = m_Check = m_GetUsed = findExternal(QStringLiteral("ntfsresize")) ? cmdSupportFileSystem : cmdSupportNone; m_GetLabel = cmdSupportCore; m_SetLabel = findExternal(QStringLiteral("ntfslabel")) ? cmdSupportFileSystem : cmdSupportNone; m_Create = findExternal(QStringLiteral("mkfs.ntfs")) ? cmdSupportFileSystem : cmdSupportNone; m_Copy = findExternal(QStringLiteral("ntfsclone")) ? cmdSupportFileSystem : cmdSupportNone; m_Backup = cmdSupportCore; m_UpdateUUID = cmdSupportCore; m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_GetUUID = cmdSupportCore; } bool ntfs::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 ntfs::supportToolName() const { return SupportTool(QStringLiteral("ntfs-3g"), QUrl(QStringLiteral("http://www.tuxera.com/community/ntfs-3g-download/"))); } qint64 ntfs::minCapacity() const { return 2 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } qint64 ntfs::maxCapacity() const { return 256 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB); } int ntfs::maxLabelLength() const { return 128; } qint64 ntfs::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("ntfsresize"), { QStringLiteral("--info"), QStringLiteral("--force"), QStringLiteral("--no-progress-bar"), deviceNode }); if (cmd.run(-1) && cmd.exitCode() == 0) { qint64 usedBytes = -1; QRegularExpression re(QStringLiteral("resize at (\\d+) bytes")); QRegularExpressionMatch reUsedBytes = re.match(cmd.output()); if (reUsedBytes.hasMatch()) usedBytes = reUsedBytes.captured(1).toLongLong(); if (usedBytes > -1) return usedBytes; } return -1; } bool ntfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand writeCmd(report, QStringLiteral("ntfslabel"), { QStringLiteral("--force"), deviceNode, newLabel }, QProcess::SeparateChannels); if (!writeCmd.run(-1)) return false; return true; } bool ntfs::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("ntfsresize"), { QStringLiteral("--no-progress-bar"), QStringLiteral("--info"), QStringLiteral("--force"), QStringLiteral("--verbose"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool ntfs::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.ntfs"), { QStringLiteral("--quick"), QStringLiteral("--verbose"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool ntfs::copy(Report& report, const QString& targetDeviceNode, const QString& sourceDeviceNode) const { ExternalCommand cmd(report, QStringLiteral("ntfsclone"), { QStringLiteral("--force"), QStringLiteral("--overwrite"), targetDeviceNode, sourceDeviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool ntfs::resize(Report& report, const QString& deviceNode, qint64 length) const { QStringList args = { QStringLiteral("--no-progress-bar"), QStringLiteral("--force"), deviceNode, QStringLiteral("--size"), QString::number(length) }; QStringList dryRunArgs = args; dryRunArgs << QStringLiteral("--no-action"); ExternalCommand cmdDryRun(QStringLiteral("ntfsresize"), dryRunArgs); if (cmdDryRun.run(-1) && cmdDryRun.exitCode() == 0) { ExternalCommand cmd(report, QStringLiteral("ntfsresize"), args); return cmd.run(-1) && cmd.exitCode() == 0; } return false; } bool ntfs::updateUUID(Report& report, const QString& deviceNode) const { Q_UNUSED(report) ExternalCommand cmd(QStringLiteral("ntfslabel"), { QStringLiteral("--new-serial"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool ntfs::updateBootSector(Report& report, const QString& deviceNode) const { report.line() << xi18nc("@info:progress", "Updating boot sector for NTFS file system on partition %1.", deviceNode); qint64 n = firstSector(); char* s = reinterpret_cast(&n); #if Q_BYTE_ORDER == Q_BIG_ENDIAN std::swap(s[0], s[3]); std::swap(s[1], s[2]); #endif ExternalCommand cmd; if (!cmd.writeData(report, QByteArray(s, sizeof(s)), deviceNode, 28)) { Log() << xi18nc("@info:progress", "Could not write new start sector to partition %1 when trying to update the NTFS boot sector.", deviceNode); return false; } // Also update backup NTFS boot sector located at the end of the partition // NOTE: this should fail if filesystem does not span the whole partition qint64 pos = (lastSector() - firstSector()) * sectorSize() + 28; if (!cmd.writeData(report, QByteArray(s, sizeof(s)), deviceNode, pos)) { Log() << xi18nc("@info:progress", "Could not write new start sector to partition %1 when trying to update the NTFS boot sector.", deviceNode); return false; } Log() << xi18nc("@info:progress", "Updated NTFS boot sector for partition %1 successfully.", deviceNode); return true; } } diff --git a/src/fs/ntfs.h b/src/fs/ntfs.h index c1d409e..09feb94 100644 --- a/src/fs/ntfs.h +++ b/src/fs/ntfs.h @@ -1,113 +1,108 @@ /************************************************************************* * Copyright (C) 2008,2009 by Volker Lanz * * * * 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_NTFS_H) - +#ifndef KPMCORE_NTFS_H #define KPMCORE_NTFS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** An NTFS file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT ntfs : public FileSystem { public: ntfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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 copy(Report& report, const QString& targetDeviceNode, const QString& sourceDeviceNode) const override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool updateUUID(Report& report, const QString& deviceNode) const override; bool updateBootSector(Report& report, const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } 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 supportSetLabel() const override { return m_SetLabel; } 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; SupportTool supportToolName() const override; bool supportToolFound() const override; 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; }; } #endif diff --git a/src/fs/ocfs2.cpp b/src/fs/ocfs2.cpp index af8eaaa..6647d20 100644 --- a/src/fs/ocfs2.cpp +++ b/src/fs/ocfs2.cpp @@ -1,155 +1,154 @@ /************************************************************************* * Copyright (C) 2010 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/ocfs2.h" #include "util/externalcommand.h" #include "util/capacity.h" #include -#include namespace FS { FileSystem::CommandSupportType ocfs2::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType ocfs2::m_GetUUID = FileSystem::cmdSupportNone; ocfs2::ocfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ocfs2) { } void ocfs2::init() { m_Create = findExternal(QStringLiteral("mkfs.ocfs2"), { QStringLiteral("--version") }) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("fsck.ocfs2"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone; m_Grow = (m_Check != cmdSupportNone && findExternal(QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--version") }) && findExternal(QStringLiteral("debugfs.ocfs2"), { QStringLiteral("--version") })) ? cmdSupportFileSystem : cmdSupportNone; m_Shrink = cmdSupportNone; // TODO: it seems there's no way to get the FS usage with ocfs2 m_GetUsed = cmdSupportNone; m_SetLabel = findExternal(QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--version") }) ? cmdSupportFileSystem : cmdSupportNone; m_UpdateUUID = findExternal(QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--version") }) ? cmdSupportFileSystem : 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 ocfs2::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 ocfs2::supportToolName() const { return SupportTool(QStringLiteral("ocfs2-tools"), QUrl(QStringLiteral("http://oss.oracle.com/projects/ocfs2-tools/"))); } qint64 ocfs2::minCapacity() const { return 14000 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::KiB); } qint64 ocfs2::maxCapacity() const { return 4 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::PiB); } qint64 ocfs2::readUsedCapacity(const QString& deviceNode) const { Q_UNUSED(deviceNode) return -1; } bool ocfs2::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("fsck.ocfs2"), { QStringLiteral("-f"), QStringLiteral("-y"), deviceNode }); return cmd.run(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 1 || cmd.exitCode() == 2); } bool ocfs2::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.ocfs2"), { deviceNode }); cmd.write("y\n"); if (!cmd.start()) return false; return cmd.exitCode() == 0; } bool ocfs2::resize(Report& report, const QString& deviceNode, qint64 length) const { ExternalCommand cmdBlockSize(QStringLiteral("debugfs.ocfs2"), { QStringLiteral("--request"), QStringLiteral("stats"), deviceNode }); qint32 blockSize = -1; if (cmdBlockSize.run(-1) && cmdBlockSize.exitCode() == 0) { QRegularExpression re(QStringLiteral("Block Size Bits: (\\d+)")); QRegularExpressionMatch reBlockSizeBits = re.match(cmdBlockSize.output()); if (reBlockSizeBits.hasMatch()) blockSize = 1 << reBlockSizeBits.captured(1).toInt(); } if (blockSize == -1) return false; ExternalCommand cmd(report, QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--yes"), QStringLiteral("--volume-size"), deviceNode, QString::number(length / blockSize) }); return cmd.run(-1) && cmd.exitCode() == 0; } bool ocfs2::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--label"), newLabel, deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool ocfs2::updateUUID(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--uuid-reset"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/ocfs2.h b/src/fs/ocfs2.h index 1a86172..44b0ebd 100644 --- a/src/fs/ocfs2.h +++ b/src/fs/ocfs2.h @@ -1,110 +1,105 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * 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_OCFS2_H) - +#ifndef KPMCORE_OCFS2_H #define KPMCORE_OCFS2_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A ocfs2 file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT ocfs2 : public FileSystem { public: ocfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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 resize(Report& report, const QString& deviceNode, qint64 length) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool updateUUID(Report& report, const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } 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 supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportUpdateUUID() const override { return m_UpdateUUID; } CommandSupportType supportGetUUID() const override { return m_GetUUID; } qint64 minCapacity() const override; qint64 maxCapacity() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; 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; }; } #endif diff --git a/src/fs/reiser4.cpp b/src/fs/reiser4.cpp index 38e1d1e..c367411 100644 --- a/src/fs/reiser4.cpp +++ b/src/fs/reiser4.cpp @@ -1,130 +1,129 @@ /************************************************************************* * Copyright (C) 2008 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/reiser4.h" #include "util/capacity.h" #include "util/externalcommand.h" #include -#include namespace FS { FileSystem::CommandSupportType reiser4::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiser4::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiser4::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiser4::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiser4::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiser4::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiser4::m_Backup = FileSystem::cmdSupportNone; reiser4::reiser4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Reiser4) { } void reiser4::init() { m_GetLabel = cmdSupportCore; m_GetUsed = findExternal(QStringLiteral("debugfs.reiser4"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone; m_Create = findExternal(QStringLiteral("mkfs.reiser4"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("fsck.reiser4"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone; m_Move = m_Copy = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Backup = cmdSupportCore; } bool reiser4::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 reiser4::supportToolName() const { return SupportTool(QStringLiteral("reiser4progs"), QUrl(QStringLiteral("http://www.kernel.org/pub/linux/utils/fs/reiser4/reiser4progs/"))); } qint64 reiser4::maxCapacity() const { // looks like it's actually unknown. see // http://en.wikipedia.org/wiki/Comparison_of_file_systems return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } int reiser4::maxLabelLength() const { return 16; } qint64 reiser4::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("debugfs.reiser4"), { deviceNode }); if (cmd.run(-1) && cmd.exitCode() == 16) { qint64 blocks = -1; QRegularExpression re(QStringLiteral("blocks:\\s+(\\d+)")); QRegularExpressionMatch reBlocks = re.match(cmd.output()); if (reBlocks.hasMatch()) blocks = reBlocks.captured(1).toLongLong(); qint64 blockSize = -1; re.setPattern(QStringLiteral("blksize:\\s+(\\d+)")); QRegularExpressionMatch reBlockSize = re.match(cmd.output()); if (reBlockSize.hasMatch()) blockSize = reBlockSize.captured(1).toLongLong(); qint64 freeBlocks = -1; re.setPattern(QStringLiteral("free blocks:\\s+(\\d+)")); QRegularExpressionMatch reFreeBlocks = re.match(cmd.output()); if (reFreeBlocks.hasMatch()) freeBlocks = reFreeBlocks.captured(1).toLongLong(); if (blocks > - 1 && blockSize > -1 && freeBlocks > -1) return (blocks - freeBlocks) * blockSize; } return -1; } bool reiser4::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("fsck.reiser4"), { QStringLiteral("--yes"), QStringLiteral("--fix"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool reiser4::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.reiser4"), { QStringLiteral("--yes"), QStringLiteral("--force"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/reiser4.h b/src/fs/reiser4.h index 34f4a13..c35ffce 100644 --- a/src/fs/reiser4.h +++ b/src/fs/reiser4.h @@ -1,87 +1,82 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_REISER4_H) - +#ifndef KPMCORE_REISER4_H #define KPMCORE_REISER4_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A Reiser4 file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT reiser4 : public FileSystem { public: reiser4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportCreate() const override { return m_Create; } 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; } qint64 maxCapacity() const override; int maxLabelLength() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; public: static CommandSupportType m_GetUsed; static CommandSupportType m_GetLabel; static CommandSupportType m_Create; static CommandSupportType m_Move; static CommandSupportType m_Check; static CommandSupportType m_Copy; static CommandSupportType m_Backup; }; } #endif diff --git a/src/fs/reiserfs.cpp b/src/fs/reiserfs.cpp index 5bfeb06..553196d 100644 --- a/src/fs/reiserfs.cpp +++ b/src/fs/reiserfs.cpp @@ -1,179 +1,177 @@ /************************************************************************* * 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/reiserfs.h" #include "util/externalcommand.h" #include "util/capacity.h" #include -#include -#include #include namespace FS { FileSystem::CommandSupportType reiserfs::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType reiserfs::m_GetUUID = FileSystem::cmdSupportNone; reiserfs::reiserfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::ReiserFS) { } void reiserfs::init() { m_GetLabel = cmdSupportCore; m_GetUsed = findExternal(QStringLiteral("debugreiserfs"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone; m_SetLabel = findExternal(QStringLiteral("reiserfstune")) ? cmdSupportFileSystem : cmdSupportNone; m_Create = findExternal(QStringLiteral("mkfs.reiserfs")) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("fsck.reiserfs")) ? cmdSupportFileSystem : cmdSupportNone; m_Move = m_Copy = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Grow = findExternal(QStringLiteral("resize_reiserfs"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone; m_Shrink = (m_GetUsed != cmdSupportNone && m_Grow != cmdSupportNone) ? cmdSupportFileSystem : cmdSupportNone; m_Backup = cmdSupportCore; m_UpdateUUID = findExternal(QStringLiteral("reiserfstune")) ? cmdSupportFileSystem : cmdSupportNone; m_GetUUID = cmdSupportCore; } bool reiserfs::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 reiserfs::supportToolName() const { return SupportTool(QStringLiteral("reiserfsprogs"), QUrl(QStringLiteral("http://www.kernel.org/pub/linux/utils/fs/reiserfs/"))); } qint64 reiserfs::minCapacity() const { return 32 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } qint64 reiserfs::maxCapacity() const { return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } int reiserfs::maxLabelLength() const { return 16; } qint64 reiserfs::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("debugreiserfs"), { deviceNode }); if (cmd.run(-1) && cmd.exitCode() == 16) { qint64 blockCount = -1; QRegularExpression re(QStringLiteral("Count of blocks[^:]+: (\\d+)")); QRegularExpressionMatch reBlockCount = re.match(cmd.output()); if (reBlockCount.hasMatch()) blockCount = reBlockCount.captured(1).toLongLong(); qint64 blockSize = -1; re.setPattern(QStringLiteral("Blocksize: (\\d+)")); QRegularExpressionMatch reBlockSize = re.match(cmd.output()); if (reBlockSize.hasMatch()) blockSize = reBlockSize.captured(1).toLongLong(); qint64 freeBlocks = -1; re.setPattern(QStringLiteral("Free blocks[^:]+: (\\d+)")); QRegularExpressionMatch reFreeBlocks = re.match(cmd.output()); if (reFreeBlocks.hasMatch()) freeBlocks = reFreeBlocks.captured(1).toLongLong(); if (blockCount > -1 && blockSize > -1 && freeBlocks > -1) return (blockCount - freeBlocks) * blockSize; } return -1; } bool reiserfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("reiserfstune"), { QStringLiteral("--label"), newLabel, deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool reiserfs::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("fsck.reiserfs"), { QStringLiteral("--fix-fixable"), QStringLiteral("--quiet"), QStringLiteral("--yes"), deviceNode }); return cmd.run(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 1 || cmd.exitCode() == 256); } bool reiserfs::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.reiserfs"), { QStringLiteral("-f"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool reiserfs::resize(Report& report, const QString& deviceNode, qint64 length) const { ExternalCommand cmd(report, QStringLiteral("resize_reiserfs"), { deviceNode, QStringLiteral("-q"), QStringLiteral("-s"), QString::number(length) }); bool rval = cmd.write(QByteArrayLiteral("y\n")); if (!rval) return false; if (!cmd.start(-1)) return false; return cmd.exitCode() == 0 || cmd.exitCode() == 256; } bool reiserfs::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const { return resize(report, deviceNode, length); } bool reiserfs::updateUUID(Report& report, const QString& deviceNode) const { const QString uuid = QUuid::createUuid().toString().remove(QRegularExpression(QStringLiteral("\\{|\\}"))); ExternalCommand cmd(report, QStringLiteral("reiserfstune"), { QStringLiteral("--uuid"), uuid, deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/reiserfs.h b/src/fs/reiserfs.h index 598c4d2..219f430 100644 --- a/src/fs/reiserfs.h +++ b/src/fs/reiserfs.h @@ -1,117 +1,112 @@ /************************************************************************* * Copyright (C) 2008,2009 by Volker Lanz * * * * 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_REISERFS_H) - +#ifndef KPMCORE_REISERFS_H #define KPMCORE_REISERFS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" #include "util/capacity.h" -#include - class Report; -class QString; - namespace FS { /** A ReiserFS file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT reiserfs : public FileSystem { public: reiserfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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 resize(Report& report, const QString& deviceNode, qint64 length) const override; bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool updateUUID(Report& report, const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return m_GetLabel; } CommandSupportType supportCreate() const override { return m_Create; } CommandSupportType supportGrow() const override { return m_Grow; } CommandSupportType supportGrowOnline() 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 supportSetLabel() const override { return m_SetLabel; } 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; SupportTool supportToolName() const override; bool supportToolFound() const override; 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; }; } #endif diff --git a/src/fs/udf.cpp b/src/fs/udf.cpp index b0d28a9..90d90bb 100644 --- a/src/fs/udf.cpp +++ b/src/fs/udf.cpp @@ -1,184 +1,182 @@ /************************************************************************* * Copyright (C) 2017 by Pali Rohár * * * * 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/udf.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/report.h" #include #include #include -#include -#include namespace FS { constexpr qint64 MIN_UDF_BLOCKS = 300; constexpr qint64 MAX_UDF_BLOCKS = ((1ULL << 32) - 1); FileSystem::CommandSupportType udf::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType udf::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType udf::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType udf::m_Create = FileSystem::cmdSupportNone; bool udf::oldMkudffsVersion = false; udf::udf(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Udf) { } void udf::init() { m_GetUsed = findExternal(QStringLiteral("udfinfo"), {}, 1) ? cmdSupportFileSystem : cmdSupportNone; m_SetLabel = m_UpdateUUID = findExternal(QStringLiteral("udflabel"), {}, 1) ? cmdSupportFileSystem : cmdSupportNone; m_Create = findExternal(QStringLiteral("mkudffs"), {}, 1) ? cmdSupportFileSystem : cmdSupportNone; if (m_Create == cmdSupportFileSystem) { // Detect old mkudffs prior to version 1.1 by lack of --label option ExternalCommand cmd(QStringLiteral("mkudffs"), { QStringLiteral("--help") }); oldMkudffsVersion = cmd.run(-1) && !cmd.output().contains(QStringLiteral("--label")); } } bool udf::supportToolFound() const { return m_GetUsed != cmdSupportNone && m_SetLabel != cmdSupportNone && m_UpdateUUID != cmdSupportNone && m_Create != cmdSupportNone; } FileSystem::SupportTool udf::supportToolName() const { return SupportTool(QStringLiteral("udftools"), QUrl(QStringLiteral("https://github.com/pali/udftools"))); } qint64 udf::minCapacity() const { return MIN_UDF_BLOCKS * sectorSize(); } qint64 udf::maxCapacity() const { return MAX_UDF_BLOCKS * sectorSize(); } int udf::maxLabelLength() const { return 126; } QValidator* udf::labelValidator(QObject *parent) const { QRegularExpressionValidator *m_LabelValidator = new QRegularExpressionValidator(parent); if (oldMkudffsVersion) { // Mkudffs from udftools prior to version 1.1 damages the label if it // contains non-ASCII characters. Therefore do not allow a label with // such characters with old versions of mkudffs. m_LabelValidator->setRegularExpression(QRegularExpression(QStringLiteral("[\\x{0001}-\\x{007F}]{0,126}"))); } else { // UDF label can only contain 126 bytes, either 126 ISO-8859-1 // (Latin 1) characters or 63 UCS-2BE characters. m_LabelValidator->setRegularExpression(QRegularExpression(QStringLiteral("[\\x{0001}-\\x{00FF}]{0,126}|[\\x{0001}-\\x{FFFF}]{0,63}"))); } return m_LabelValidator; } qint64 udf::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("udfinfo"), { QStringLiteral("--utf8"), deviceNode }); if (!cmd.run(-1) || cmd.exitCode() != 0) return -1; QRegularExpressionMatch reBlockSize = QRegularExpression(QStringLiteral("^blocksize=([0-9]+)$"), QRegularExpression::MultilineOption).match(cmd.output()); QRegularExpressionMatch reUsedBlocks = QRegularExpression(QStringLiteral("^usedblocks=([0-9]+)$"), QRegularExpression::MultilineOption).match(cmd.output()); if (!reBlockSize.hasMatch() || !reUsedBlocks.hasMatch()) return -1; qint64 blockSize = reBlockSize.captured(1).toLongLong(); qint64 usedBlocks = reUsedBlocks.captured(1).toLongLong(); return usedBlocks * blockSize; } bool udf::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("udflabel"), { QStringLiteral("--utf8"), deviceNode, newLabel }); return cmd.run(-1) && cmd.exitCode() == 0; } bool udf::updateUUID(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("udflabel"), { QStringLiteral("--utf8"), QStringLiteral("--uuid=random"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool udf::create(Report& report, const QString& deviceNode) { return createWithLabel(report, deviceNode, QString()); } bool udf::createWithLabel(Report& report, const QString& deviceNode, const QString& label) { // It is not possible to create UDF filesystem without a label or with empty label // When --lvid or --vid option is not specified, mkudffs use sane default QStringList labelArgs; if (!label.isEmpty()) { // The Volume Identifier (--vid) can only contain 30 bytes, either 30 // ISO-8859-1 (Latin 1) characters or 15 UCS-2BE characters. Store the // most characters possible in the Volume Identifier. Either up to 15 // UCS-2BE characters when a character needing 16-bit encoding is found in // the first 15 characters, or up to 30 characters when a character // needing 16-bit encoding is found in the second 15 characters. const QRegularExpression nonLatin1RegExp = QRegularExpression(QStringLiteral("[^\\x{0000}-\\x{00FF}]")); QString shortLabel = label.left(30); int firstNonLatin1Pos = shortLabel.indexOf(nonLatin1RegExp); if (firstNonLatin1Pos != -1 && firstNonLatin1Pos < 15) shortLabel = shortLabel.left(15); else if (firstNonLatin1Pos != -1 && firstNonLatin1Pos < 30) shortLabel = shortLabel.left(firstNonLatin1Pos); // UDF Logical Volume Identifier (--lvid) represents the label, but blkid // (from util-linux) prior to version v2.26 reads the Volume Identifier // (--vid). Therefore for compatibility reasons store the label in both // locations. labelArgs << QStringLiteral("--lvid=") + label; labelArgs << QStringLiteral("--vid=") + shortLabel; } QStringList cmdArgs; cmdArgs << QStringLiteral("--utf8"); // TODO: Add GUI option for choosing different optical disks and UDF revision // For now format as UDF revision 2.01 for hard disk media type cmdArgs << QStringLiteral("--media-type=hd"); cmdArgs << QStringLiteral("--udfrev=0x201"); // mkudffs from udftools prior to 1.1 is not able to detect logical (sector) size // and UDF block size must match logical sector size of underlying media cmdArgs << QStringLiteral("--blocksize=") + QString::number(sectorSize()); cmdArgs << labelArgs; cmdArgs << deviceNode; ExternalCommand cmd(report, QStringLiteral("mkudffs"), cmdArgs); return cmd.run(-1) && cmd.exitCode() == 0; } } diff --git a/src/fs/udf.h b/src/fs/udf.h index f49df36..511982f 100644 --- a/src/fs/udf.h +++ b/src/fs/udf.h @@ -1,100 +1,95 @@ /************************************************************************* * Copyright (C) 2017 by Pali Rohár * * * * 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_UDF_H) - +#ifndef KPMCORE_UDF_H #define KPMCORE_UDF_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A udf file system. @author Pali Rohár */ class LIBKPMCORE_EXPORT udf : public FileSystem { public: udf(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: void init() override; qint64 readUsedCapacity(const QString& deviceNode) const override; bool create(Report& report, const QString& deviceNode) override; bool createWithLabel(Report& report, const QString& deviceNode, const QString& label) override; bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; bool updateUUID(Report& report, const QString& deviceNode) const override; CommandSupportType supportGetUsed() const override { return m_GetUsed; } CommandSupportType supportGetLabel() const override { return cmdSupportCore; } CommandSupportType supportCreate() const override { return m_Create; } CommandSupportType supportCreateWithLabel() const override { return m_Create; } CommandSupportType supportMove() const override { return cmdSupportCore; } CommandSupportType supportCopy() const override { return cmdSupportCore; } CommandSupportType supportBackup() const override { return cmdSupportCore; } CommandSupportType supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportUpdateUUID() const override { return m_UpdateUUID; } CommandSupportType supportGetUUID() const override { return cmdSupportCore; } qint64 minCapacity() const override; qint64 maxCapacity() const override; int maxLabelLength() const override; QValidator* labelValidator(QObject *parent = nullptr) const override; SupportTool supportToolName() const override; bool supportToolFound() const override; public: static CommandSupportType m_GetUsed; static CommandSupportType m_SetLabel; static CommandSupportType m_UpdateUUID; static CommandSupportType m_Create; private: static bool oldMkudffsVersion; }; } #endif diff --git a/src/fs/ufs.h b/src/fs/ufs.h index 2c67f92..4d057d2 100644 --- a/src/fs/ufs.h +++ b/src/fs/ufs.h @@ -1,62 +1,57 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_UFS_H) - +#ifndef KPMCORE_UFS_H #define KPMCORE_UFS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - -class QString; - namespace FS { /** A UFS file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT ufs : public FileSystem { public: ufs(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/unformatted.h b/src/fs/unformatted.h index 8c66407..2d1234c 100644 --- a/src/fs/unformatted.h +++ b/src/fs/unformatted.h @@ -1,58 +1,53 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_UNFORMATTED_H) - +#ifndef KPMCORE_UNFORMATTED_H #define KPMCORE_UNFORMATTED_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A pseudo file system for unformatted partitions. @author Volker Lanz */ class LIBKPMCORE_EXPORT unformatted : public FileSystem { public: unformatted(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: bool create(Report&, const QString&) override; CommandSupportType supportCreate() const override { return m_Create; } bool supportToolFound() const override { return true; } public: static CommandSupportType m_Create; }; } #endif diff --git a/src/fs/unknown.h b/src/fs/unknown.h index cf87ca4..bb5cff6 100644 --- a/src/fs/unknown.h +++ b/src/fs/unknown.h @@ -1,51 +1,49 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_UNKNOWN_H #define KPMCORE_UNKNOWN_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - namespace FS { /** A pseudo file system for partitions whose file system we cannot determine. @author Volker Lanz */ class LIBKPMCORE_EXPORT unknown : public FileSystem { public: unknown(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: bool supportToolFound() const override { return true; } bool canMount(const QString & deviceNode, const QString & mountPoint) const override; CommandSupportType supportMove() const override { return m_Move; } static CommandSupportType m_Move; }; } #endif diff --git a/src/fs/xfs.cpp b/src/fs/xfs.cpp index 25d2ef3..0e20295 100644 --- a/src/fs/xfs.cpp +++ b/src/fs/xfs.cpp @@ -1,203 +1,201 @@ /************************************************************************* * Copyright (C) 2008 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/xfs.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/report.h" #include -#include -#include #include #include namespace FS { FileSystem::CommandSupportType xfs::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType xfs::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType xfs::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType xfs::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType xfs::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType xfs::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType xfs::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType xfs::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType xfs::m_SetLabel = FileSystem::cmdSupportNone; xfs::xfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Xfs) { } void xfs::init() { m_GetLabel = cmdSupportCore; m_SetLabel = m_GetUsed = findExternal(QStringLiteral("xfs_db")) ? cmdSupportFileSystem : cmdSupportNone; m_Create = findExternal(QStringLiteral("mkfs.xfs")) ? cmdSupportFileSystem : cmdSupportNone; m_Check = findExternal(QStringLiteral("xfs_repair")) ? cmdSupportFileSystem : cmdSupportNone; m_Grow = (findExternal(QStringLiteral("xfs_growfs"), { QStringLiteral("-V") }) && m_Check != cmdSupportNone) ? cmdSupportFileSystem : cmdSupportNone; m_Copy = findExternal(QStringLiteral("xfs_copy")) ? cmdSupportFileSystem : cmdSupportNone; m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone; m_Backup = cmdSupportCore; } bool xfs::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 xfs::supportToolName() const { return SupportTool(QStringLiteral("xfsprogs"), QUrl(QStringLiteral("http://oss.sgi.com/projects/xfs/"))); } qint64 xfs::minCapacity() const { return 32 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } qint64 xfs::maxCapacity() const { return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } int xfs::maxLabelLength() const { return 12; } qint64 xfs::readUsedCapacity(const QString& deviceNode) const { ExternalCommand cmd(QStringLiteral("xfs_db"), { QStringLiteral("-c"), QStringLiteral("sb 0"), QStringLiteral("-c"), QStringLiteral("print"), deviceNode }); if (cmd.run(-1) && cmd.exitCode() == 0) { qint64 dBlocks = -1; QRegularExpression re(QStringLiteral("dblocks = (\\d+)")); QRegularExpressionMatch reDBlocks = re.match(cmd.output()); if (reDBlocks.hasMatch()) dBlocks = reDBlocks.captured(1).toLongLong(); qint64 blockSize = -1; re.setPattern(QStringLiteral("blocksize = (\\d+)")); QRegularExpressionMatch reBlockSize = re.match(cmd.output()); if (reBlockSize.hasMatch()) blockSize = reBlockSize.captured(1).toLongLong(); qint64 fdBlocks = -1; re.setPattern(QStringLiteral("fdblocks = (\\d+)")); QRegularExpressionMatch reFdBlocks = re.match(cmd.output()); if (reFdBlocks.hasMatch()) fdBlocks = reFdBlocks.captured(1).toLongLong(); if (dBlocks > -1 && blockSize > -1 && fdBlocks > -1) return (dBlocks - fdBlocks) * blockSize; } return -1; } bool xfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { ExternalCommand cmd(report, QStringLiteral("xfs_db"), { QStringLiteral("-x"), QStringLiteral("-c"), QStringLiteral("sb 0"), QStringLiteral("-c"), QStringLiteral("label ") + newLabel, deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool xfs::check(Report& report, const QString& deviceNode) const { ExternalCommand cmd(report, QStringLiteral("xfs_repair"), { QStringLiteral("-v"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool xfs::create(Report& report, const QString& deviceNode) { ExternalCommand cmd(report, QStringLiteral("mkfs.xfs"), { QStringLiteral("-f"), deviceNode }); return cmd.run(-1) && cmd.exitCode() == 0; } bool xfs::copy(Report& report, const QString& targetDeviceNode, const QString& sourceDeviceNode) const { ExternalCommand cmd(report, QStringLiteral("xfs_copy"), { sourceDeviceNode, targetDeviceNode }); // xfs_copy behaves a little strangely. It apparently kills itself at the end of main, causing QProcess // to report that it crashed. // See http://oss.sgi.com/archives/xfs/2004-11/msg00169.html // So we cannot rely on QProcess::exitStatus() and thus not on ExternalCommand::run() returning true. cmd.run(-1); return cmd.exitCode() == 0; } bool xfs::resize(Report& report, const QString& deviceNode, qint64) const { QTemporaryDir tempDir; if (!tempDir.isValid()) { report.line() << xi18nc("@info:progress", "Resizing XFS file system on partition %1 failed: Could not create temp dir.", deviceNode); return false; } bool rval = false; ExternalCommand mountCmd(report, QStringLiteral("mount"), { QStringLiteral("--verbose"), QStringLiteral("--types"), QStringLiteral("xfs"), deviceNode, tempDir.path() }); if (mountCmd.run(-1)) { ExternalCommand resizeCmd(report, QStringLiteral("xfs_growfs"), { tempDir.path() }); if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0) rval = true; else report.line() << xi18nc("@info:progress", "Resizing XFS file system on partition %1 failed: xfs_growfs failed.", deviceNode); ExternalCommand unmountCmd(report, QStringLiteral("umount"), { tempDir.path() }); if (!unmountCmd.run(-1)) report.line() << xi18nc("@info:progress", "Resizing XFS file system on partition %1 failed: Unmount failed.", deviceNode); } else report.line() << xi18nc("@info:progress", "Resizing XFS file system on partition %1 failed: Initial mount failed.", deviceNode); return rval; } bool xfs::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64) const { ExternalCommand resizeCmd(report, QStringLiteral("xfs_growfs"), { mountPoint }); if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0) return true; report.line() << xi18nc("@info:progress", "Resizing XFS file system on partition %1 failed: xfs_growfs failed.", deviceNode); return false; } } diff --git a/src/fs/xfs.h b/src/fs/xfs.h index 3199c93..b9e489f 100644 --- a/src/fs/xfs.h +++ b/src/fs/xfs.h @@ -1,103 +1,98 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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_XFS_H) - +#ifndef KPMCORE_XFS_H #define KPMCORE_XFS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** An XFS file system. @author Volker Lanz */ class LIBKPMCORE_EXPORT xfs : public FileSystem { public: xfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); 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 copy(Report& report, const QString&, const QString&) const override; bool resize(Report& report, const QString& deviceNode, qint64 length) const override; bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) 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 supportCreate() const override { return m_Create; } CommandSupportType supportGrow() const override { return m_Grow; } CommandSupportType supportGrowOnline() const override { return m_Grow; } 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 supportSetLabel() const override { return m_SetLabel; } qint64 minCapacity() const override; qint64 maxCapacity() const override; int maxLabelLength() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; public: static CommandSupportType m_GetUsed; static CommandSupportType m_GetLabel; static CommandSupportType m_Create; static CommandSupportType m_Grow; static CommandSupportType m_Move; static CommandSupportType m_Check; static CommandSupportType m_Copy; static CommandSupportType m_Backup; static CommandSupportType m_SetLabel; }; } #endif diff --git a/src/fs/zfs.cpp b/src/fs/zfs.cpp index a3cb201..0455bb7 100644 --- a/src/fs/zfs.cpp +++ b/src/fs/zfs.cpp @@ -1,102 +1,100 @@ /************************************************************************* * Copyright (C) 2010 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/zfs.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/report.h" -#include - namespace FS { FileSystem::CommandSupportType zfs::m_GetUsed = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_GetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_Create = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_Grow = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_Shrink = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_Move = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_Check = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_Copy = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_Backup = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_SetLabel = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType zfs::m_GetUUID = FileSystem::cmdSupportNone; zfs::zfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Zfs) { } void zfs::init() { m_SetLabel = findExternal(QStringLiteral("zpool"), {}, 2) ? cmdSupportFileSystem : cmdSupportNone; m_GetLabel = cmdSupportCore; m_Backup = cmdSupportCore; m_GetUUID = cmdSupportCore; } bool zfs::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 zfs::supportToolName() const { return SupportTool(QStringLiteral("zfs"), QUrl(QStringLiteral("http://zfsonlinux.org/"))); } qint64 zfs::minCapacity() const { return 64 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } qint64 zfs::maxCapacity() const { return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } bool zfs::remove(Report& report, const QString& deviceNode) const { Q_UNUSED(deviceNode) ExternalCommand cmd(report, QStringLiteral("zpool"), { QStringLiteral("destroy"), QStringLiteral("-f"), label() }); return cmd.run(-1) && cmd.exitCode() == 0; } bool zfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { Q_UNUSED(deviceNode) ExternalCommand cmd1(report, QStringLiteral("zpool"), { QStringLiteral("export"), label() }); ExternalCommand cmd2(report, QStringLiteral("zpool"), { QStringLiteral("import"), label(), newLabel }); return cmd1.run(-1) && cmd1.exitCode() == 0 && cmd2.run(-1) && cmd2.exitCode() == 0; } } diff --git a/src/fs/zfs.h b/src/fs/zfs.h index c87f971..9996614 100644 --- a/src/fs/zfs.h +++ b/src/fs/zfs.h @@ -1,107 +1,102 @@ /************************************************************************* * Copyright (C) 2010 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 .* *************************************************************************/ -#if !defined(KPMCORE_ZFS_H) - +#ifndef KPMCORE_ZFS_H #define KPMCORE_ZFS_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" -#include - class Report; -class QString; - namespace FS { /** A zfs file system. @author Andrius Štikonas */ class LIBKPMCORE_EXPORT zfs : public FileSystem { public: zfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label); public: void init() override; bool remove(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 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 supportSetLabel() const override { return m_SetLabel; } CommandSupportType supportUpdateUUID() const override { return m_UpdateUUID; } CommandSupportType supportGetUUID() const override { return m_GetUUID; } qint64 minCapacity() const override; qint64 maxCapacity() const override; SupportTool supportToolName() const override; bool supportToolFound() const override; 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; }; } #endif diff --git a/src/util/externalcommand.cpp b/src/util/externalcommand.cpp index 5ed64c1..e73a10d 100644 --- a/src/util/externalcommand.cpp +++ b/src/util/externalcommand.cpp @@ -1,403 +1,401 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016-2018 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 "backend/corebackendmanager.h" #include "core/device.h" #include "core/copysource.h" #include "core/copytarget.h" #include "core/copytargetbytearray.h" #include "core/copysourcedevice.h" #include "core/copytargetdevice.h" #include "util/globallog.h" #include "util/externalcommand.h" #include "util/report.h" #include "externalcommandhelper_interface.h" #include #include #include #include #include #include #include -#include -#include #include #include #include #include #include #include struct ExternalCommandPrivate { Report *m_Report; QString m_Command; QStringList m_Args; int m_ExitCode; QByteArray m_Output; QByteArray m_Input; DBusThread *m_thread; QProcess::ProcessChannelMode processChannelMode; }; KAuth::ExecuteJob* ExternalCommand::m_job; bool ExternalCommand::helperStarted = false; QWidget* ExternalCommand::parent; /** Creates a new ExternalCommand instance without Report. @param cmd the command to run @param args the arguments to pass to the command */ ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : d(std::make_unique()) { d->m_Report = nullptr; d->m_Command = cmd; d->m_Args = args; d->m_ExitCode = -1; d->m_Output = QByteArray(); if (!helperStarted) if(!startHelper()) Log(Log::Level::error) << xi18nc("@info:status", "Could not obtain administrator privileges."); d->processChannelMode = processChannelMode; } /** Creates a new ExternalCommand instance with Report. @param report the Report to write output to. @param cmd the command to run @param args the arguments to pass to the command */ ExternalCommand::ExternalCommand(Report& report, const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : d(std::make_unique()) { d->m_Report = report.newChild(); d->m_Command = cmd; d->m_Args = args; d->m_ExitCode = -1; d->m_Output = QByteArray(); d->processChannelMode = processChannelMode; } ExternalCommand::~ExternalCommand() { } /* void ExternalCommand::setup() { connect(this, qOverload(&QProcess::finished), this, &ExternalCommand::onFinished); connect(this, &ExternalCommand::readyReadStandardOutput, this, &ExternalCommand::onReadOutput); } */ /** Executes the external command. @param timeout timeout to wait for the process to start @return true on success */ bool ExternalCommand::start(int timeout) { if (command().isEmpty()) return false; if (!QDBusConnection::systemBus().isConnected()) { qWarning() << QDBusConnection::systemBus().lastError().message(); QTimer::singleShot(timeout, this, &ExternalCommand::quit); return false; } if (report()) report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" ")))); if ( qEnvironmentVariableIsSet( "KPMCORE_DEBUG" )) qDebug() << xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" "))); QString cmd = QStandardPaths::findExecutable(command()); if (cmd.isEmpty()) cmd = QStandardPaths::findExecutable(command(), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") }); auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days bool rval = false; QDBusPendingCall pcall = interface->start(cmd, args(), d->m_Input, d->processChannelMode); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); QEventLoop loop; auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) { loop.exit(); if (watcher->isError()) qWarning() << watcher->error(); else { QDBusPendingReply reply = *watcher; d->m_Output = reply.value()[QStringLiteral("output")].toByteArray(); setExitCode(reply.value()[QStringLiteral("exitCode")].toInt()); rval = reply.value()[QStringLiteral("success")].toBool(); } }; connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop); loop.exec(); QTimer::singleShot(timeout, this, &ExternalCommand::quit); return rval; } bool ExternalCommand::copyBlocks(const CopySource& source, CopyTarget& target) { bool rval = true; const qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy if (!QDBusConnection::systemBus().isConnected()) { qWarning() << QDBusConnection::systemBus().lastError().message(); return false; } // TODO KF6:Use new signal-slot syntax connect(m_job, SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long))); connect(m_job, &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport); auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days QDBusPendingCall pcall = interface->copyblocks(source.path(), source.firstByte(), source.length(), target.path(), target.firstByte(), blockSize); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); QEventLoop loop; auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) { loop.exit(); if (watcher->isError()) qWarning() << watcher->error(); else { QDBusPendingReply reply = *watcher; rval = reply.value()[QStringLiteral("success")].toBool(); CopyTargetByteArray *byteArrayTarget = dynamic_cast(&target); if (byteArrayTarget) byteArrayTarget->m_Array = reply.value()[QStringLiteral("targetByteArray")].toByteArray(); } setExitCode(!rval); }; connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop); loop.exec(); return rval; } bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte) { d->m_Report = commandReport.newChild(); if (report()) report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" ")))); bool rval = true; if (!QDBusConnection::systemBus().isConnected()) { qWarning() << QDBusConnection::systemBus().lastError().message(); return false; } auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days QDBusPendingCall pcall = interface->writeData(buffer, deviceNode, firstByte); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); QEventLoop loop; auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) { loop.exit(); if (watcher->isError()) qWarning() << watcher->error(); else { QDBusPendingReply reply = *watcher; rval = reply.argumentAt<0>(); } setExitCode(!rval); }; connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop); loop.exec(); return rval; } bool ExternalCommand::write(const QByteArray& input) { if ( qEnvironmentVariableIsSet( "KPMCORE_DEBUG" )) qDebug() << "Command input:" << QString::fromLocal8Bit(input); d->m_Input = input; return true; } /** Runs the command. @param timeout timeout to use for waiting when starting and when waiting for the process to finish @return true on success */ bool ExternalCommand::run(int timeout) { return start(timeout) /* && exitStatus() == 0*/; } void ExternalCommand::onReadOutput() { // const QByteArray s = readAllStandardOutput(); // // if(m_Output.length() > 10*1024*1024) { // prevent memory overflow for badly corrupted file systems // if (report()) // report()->line() << xi18nc("@info:status", "(Command is printing too much output)"); // return; // } // // m_Output += s; // // if (report()) // *report() << QString::fromLocal8Bit(s); } void ExternalCommand::setCommand(const QString& cmd) { d->m_Command = cmd; } const QString& ExternalCommand::command() const { return d->m_Command; } const QStringList& ExternalCommand::args() const { return d->m_Args; } void ExternalCommand::addArg(const QString& s) { d->m_Args << s; } void ExternalCommand::setArgs(const QStringList& args) { d->m_Args = args; } int ExternalCommand::exitCode() const { return d->m_ExitCode; } const QString ExternalCommand::output() const { return QString::fromLocal8Bit(d->m_Output); } const QByteArray& ExternalCommand::rawOutput() const { return d->m_Output; } Report* ExternalCommand::report() { return d->m_Report; } void ExternalCommand::setExitCode(int i) { d->m_ExitCode = i; } /**< Dummy function for QTimer when needed. */ void ExternalCommand::quit() { } bool ExternalCommand::startHelper() { if (!QDBusConnection::systemBus().isConnected()) { qWarning() << QDBusConnection::systemBus().lastError().message(); return false; } QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); if (iface.isValid()) { exit(0); } d->m_thread = new DBusThread; d->m_thread->start(); KAuth::Action action = KAuth::Action(QStringLiteral("org.kde.kpmcore.externalcommand.init")); action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand")); action.setTimeout(10 * 24 * 3600 * 1000); // 10 days action.setParentWidget(parent); QVariantMap arguments; action.setArguments(arguments); m_job = action.execute(); m_job->start(); // Wait until ExternalCommand Helper is ready (helper sends newData signal just before it enters event loop) QEventLoop loop; auto exitLoop = [&] () { loop.exit(); }; auto conn = QObject::connect(m_job, &KAuth::ExecuteJob::newData, exitLoop); QObject::connect(m_job, &KJob::finished, [=] () { if(m_job->error()) exitLoop(); } ); loop.exec(); QObject::disconnect(conn); helperStarted = true; return true; } void ExternalCommand::stopHelper() { auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), QStringLiteral("/Helper"), QDBusConnection::systemBus()); interface->exit(); } void DBusThread::run() { if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.applicationinterface")) || !QDBusConnection::systemBus().registerObject(QStringLiteral("/Application"), this, QDBusConnection::ExportAllSlots)) { qWarning() << QDBusConnection::systemBus().lastError().message(); return; } QEventLoop loop; loop.exec(); } diff --git a/src/util/externalcommand.h b/src/util/externalcommand.h index c36c42e..4a5d980 100644 --- a/src/util/externalcommand.h +++ b/src/util/externalcommand.h @@ -1,144 +1,142 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016-2018 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_EXTERNALCOMMAND_H #define KPMCORE_EXTERNALCOMMAND_H #include "util/libpartitionmanagerexport.h" #include #include -#include -#include #include #include #include #include namespace KAuth { class ExecuteJob; } class KJob; class Report; class CopySource; class CopyTarget; class QDBusInterface; struct ExternalCommandPrivate; class DBusThread : public QThread { Q_OBJECT // We register on DBus so the helper can monitor us and terminate if we // terminate. Q_CLASSINFO("D-Bus Interface", "org.kde.kpmcore.applicationinterface") void run() override; }; /** An external command. Runs an external command as a child process. @author Volker Lanz @author Andrius Štikonas */ class LIBKPMCORE_EXPORT ExternalCommand : public QObject { Q_OBJECT Q_DISABLE_COPY(ExternalCommand) public: explicit ExternalCommand(const QString& cmd = QString(), const QStringList& args = QStringList(), const QProcess::ProcessChannelMode processChannelMode = QProcess::MergedChannels); explicit ExternalCommand(Report& report, const QString& cmd = QString(), const QStringList& args = QStringList(), const QProcess::ProcessChannelMode processChannelMode = QProcess::MergedChannels); ~ExternalCommand(); public: bool copyBlocks(const CopySource& source, CopyTarget& target); bool writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte); // same as copyBlocks but from QByteArray /**< @param cmd the command to run */ void setCommand(const QString& cmd); /**< @return the command to run */ const QString& command() const; /**< @return the arguments */ const QStringList& args() const; /**< @param s the argument to add */ void addArg(const QString& s); /**< @param args the new arguments */ void setArgs(const QStringList& args); bool write(const QByteArray& input); /**< @param input the input for the program */ bool startCopyBlocks(); bool start(int timeout = 30000); bool run(int timeout = 30000); /**< @return the exit code */ int exitCode() const; /**< @return the command output */ const QString output() const; /**< @return the command output */ const QByteArray& rawOutput() const; /**< @return pointer to the Report or nullptr */ Report* report(); void emitReport(const QVariantMap& report) { emit reportSignal(report); } /**< Dummy function for QTimer when needed. */ void quit(); // KAuth /**< start ExternalCommand Helper */ bool startHelper(); /**< stop ExternalCommand Helper */ static void stopHelper(); /**< Sets a parent widget for the authentication dialog. * @param p parent widget */ static void setParentWidget(QWidget *p) { parent = p; } Q_SIGNALS: void progress(int); void reportSignal(const QVariantMap&); public Q_SLOTS: void emitProgress(KJob*, unsigned long percent) { emit progress(percent); } private: void setExitCode(int i); void onReadOutput(); private: std::unique_ptr d; // KAuth static KAuth::ExecuteJob *m_job; static bool helperStarted; static QWidget *parent; }; #endif diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp index 9e96966..845738c 100644 --- a/src/util/externalcommandhelper.cpp +++ b/src/util/externalcommandhelper.cpp @@ -1,308 +1,307 @@ /************************************************************************* * Copyright (C) 2017-2018 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 "externalcommandhelper.h" #include "externalcommand_whitelist.h" #include #include #include #include -#include #include #include #include /** Initialize ExternalCommandHelper Daemon and prepare DBus interface * * KAuth helper runs in the background until application exits. * To avoid forever running helper in case of application crash * ExternalCommand class opens a DBus service that we monitor for changes. * If helper is not busy then it exits when the client services gets * unregistered. Otherwise, * we wait for the current job to finish before exiting, so even in case * of main application crash, we do not leave partially moved data. * * This helper also starts another DBus interface where it listens to * command execution requests from the application that started the helper. * */ ActionReply ExternalCommandHelper::init(const QVariantMap& args) { Q_UNUSED(args) ActionReply reply; if (!QDBusConnection::systemBus().isConnected() || !QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.helperinterface")) || !QDBusConnection::systemBus().registerObject(QStringLiteral("/Helper"), this, QDBusConnection::ExportAllSlots)) { qWarning() << QDBusConnection::systemBus().lastError().message(); reply.addData(QStringLiteral("success"), false); // Also end the application loop started by KAuth's main() code. Our loop // exits when our client disappears. Without client we have no reason to // live. qApp->quit(); return reply; } m_loop = std::make_unique(); HelperSupport::progressStep(QVariantMap()); // End the loop and return only once the client is done using us. auto serviceWatcher = new QDBusServiceWatcher(QStringLiteral("org.kde.kpmcore.applicationinterface"), QDBusConnection::systemBus(), QDBusServiceWatcher::WatchForUnregistration, this); connect(serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, [this]() { m_loop->exit(); }); m_loop->exec(); reply.addData(QStringLiteral("success"), true); // Also end the application loop started by KAuth's main() code. Our loop // exits when our client disappears. Without client we have no reason to // live. qApp->quit(); return reply; } /** Reads the given number of bytes from the sourceDevice into the given buffer. @param sourceDevice device or file to read from @param buffer buffer to store the bytes read in @param offset offset where to begin reading @param size the number of bytes to read @return true on success */ bool ExternalCommandHelper::readData(const QString& sourceDevice, QByteArray& buffer, const qint64 offset, const qint64 size) { QFile device(sourceDevice); if (!device.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) { qCritical() << xi18n("Could not open device %1 for reading.", sourceDevice); return false; } if (!device.seek(offset)) { qCritical() << xi18n("Could not seek position %1 on device %2.", offset, sourceDevice); return false; } buffer = device.read(size); if (size != buffer.size()) { qCritical() << xi18n("Could not read from device %1.", sourceDevice); return false; } return true; } /** Writes the data from buffer to a given device or file. @param targetDevice device or file to write to @param buffer the data that we write @param offset offset where to begin writing @return true on success */ bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteArray& buffer, const qint64 offset) { QFile device(targetDevice); if (!device.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered)) { qCritical() << xi18n("Could not open device %1 for writing.", targetDevice); return false; } if (!device.seek(offset)) { qCritical() << xi18n("Could not seek position %1 on device %2.", offset, targetDevice); return false; } if (device.write(buffer) != buffer.size()) { qCritical() << xi18n("Could not write to device %1.", targetDevice); return false; } return true; } // If targetDevice is empty then return QByteArray with data that was read from disk. QVariantMap ExternalCommandHelper::copyblocks(const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize) { QVariantMap reply; reply[QStringLiteral("success")] = true; const qint64 blocksToCopy = sourceLength / blockSize; qint64 readOffset = sourceFirstByte; qint64 writeOffset = targetFirstByte; qint32 copyDirection = 1; if (targetFirstByte > sourceFirstByte) { readOffset = sourceFirstByte + sourceLength - blockSize; writeOffset = targetFirstByte + sourceLength - blockSize; copyDirection = -1; } const qint64 lastBlock = sourceLength % blockSize; qint64 bytesWritten = 0; qint64 blocksCopied = 0; QByteArray buffer; int percent = 0; QTime t; t.start(); QVariantMap report; report[QStringLiteral("report")] = xi18nc("@info:progress", "Copying %1 blocks (%2 bytes) from %3 to %4, direction: %5.", blocksToCopy, sourceLength, readOffset, writeOffset, copyDirection == 1 ? i18nc("direction: left", "left") : i18nc("direction: right", "right")); HelperSupport::progressStep(report); bool rval = true; while (blocksCopied < blocksToCopy && !targetDevice.isEmpty()) { if (!(rval = readData(sourceDevice, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize))) break; if (!(rval = writeData(targetDevice, buffer, writeOffset + blockSize * blocksCopied * copyDirection))) break; bytesWritten += buffer.size(); if (++blocksCopied * 100 / blocksToCopy != percent) { percent = blocksCopied * 100 / blocksToCopy; if (percent % 5 == 0 && t.elapsed() > 1000) { const qint64 mibsPerSec = (blocksCopied * blockSize / 1024 / 1024) / (t.elapsed() / 1000); const qint64 estSecsLeft = (100 - percent) * t.elapsed() / percent / 1000; report[QStringLiteral("report")]= xi18nc("@info:progress", "Copying %1 MiB/second, estimated time left: %2", mibsPerSec, QTime(0, 0).addSecs(estSecsLeft).toString()); HelperSupport::progressStep(report); } HelperSupport::progressStep(percent); } } // copy the remainder if (rval && lastBlock > 0) { Q_ASSERT(lastBlock < blockSize); const qint64 lastBlockReadOffset = copyDirection > 0 ? readOffset + blockSize * blocksCopied : sourceFirstByte; const qint64 lastBlockWriteOffset = copyDirection > 0 ? writeOffset + blockSize * blocksCopied : targetFirstByte; report[QStringLiteral("report")]= xi18nc("@info:progress", "Copying remainder of block size %1 from %2 to %3.", lastBlock, lastBlockReadOffset, lastBlockWriteOffset); HelperSupport::progressStep(report); rval = readData(sourceDevice, buffer, lastBlockReadOffset, lastBlock); if (rval) { if (targetDevice.isEmpty()) reply[QStringLiteral("targetByteArray")] = buffer; else rval = writeData(targetDevice, buffer, lastBlockWriteOffset); } if (rval) { HelperSupport::progressStep(100); bytesWritten += buffer.size(); } } report[QStringLiteral("report")] = xi18ncp("@info:progress argument 2 is a string such as 7 bytes (localized accordingly)", "Copying 1 block (%2) finished.", "Copying %1 blocks (%2) finished.", blocksCopied, i18np("1 byte", "%1 bytes", bytesWritten)); HelperSupport::progressStep(report); reply[QStringLiteral("success")] = rval; return reply; } bool ExternalCommandHelper::writeData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetFirstByte) { // Do not allow using this helper for writing to arbitrary location if ( targetDevice.left(5) != QStringLiteral("/dev/") && !targetDevice.contains(QStringLiteral("/etc/fstab"))) return false; return writeData(targetDevice, buffer, targetFirstByte); } QVariantMap ExternalCommandHelper::start(const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode) { QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); QVariantMap reply; reply[QStringLiteral("success")] = true; if (command.isEmpty()) { reply[QStringLiteral("success")] = false; return reply; } // Compare with command whitelist QString basename = command.mid(command.lastIndexOf(QLatin1Char('/')) + 1); if (std::find(std::begin(allowedCommands), std::end(allowedCommands), basename) == std::end(allowedCommands)) { qInfo() << command <<" command is not one of the whitelisted command"; m_loop->exit(); reply[QStringLiteral("success")] = false; return reply; } // connect(&cmd, &QProcess::readyReadStandardOutput, this, &ExternalCommandHelper::onReadOutput); m_cmd.setEnvironment( { QStringLiteral("LVM_SUPPRESS_FD_WARNINGS=1") } ); m_cmd.setProcessChannelMode(static_cast(processChannelMode)); m_cmd.start(command, arguments); m_cmd.write(input); m_cmd.closeWriteChannel(); m_cmd.waitForFinished(-1); QByteArray output = m_cmd.readAllStandardOutput(); reply[QStringLiteral("output")] = output; reply[QStringLiteral("exitCode")] = m_cmd.exitCode(); return reply; } void ExternalCommandHelper::exit() { m_loop->exit(); QDBusConnection::systemBus().unregisterObject(QStringLiteral("/Helper")); QDBusConnection::systemBus().unregisterService(QStringLiteral("org.kde.kpmcore.helperinterface")); } void ExternalCommandHelper::onReadOutput() { /* const QByteArray s = cmd.readAllStandardOutput(); if(output.length() > 10*1024*1024) { // prevent memory overflow for badly corrupted file systems if (report()) report()->line() << xi18nc("@info:status", "(Command is printing too much output)"); return; } output += s; if (report()) *report() << QString::fromLocal8Bit(s);*/ } KAUTH_HELPER_MAIN("org.kde.kpmcore.externalcommand", ExternalCommandHelper) diff --git a/src/util/externalcommandhelper.h b/src/util/externalcommandhelper.h index 6d7029b..ef7539b 100644 --- a/src/util/externalcommandhelper.h +++ b/src/util/externalcommandhelper.h @@ -1,60 +1,59 @@ /************************************************************************* * Copyright (C) 2017-2018 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_EXTERNALCOMMANDHELPER_H #define KPMCORE_EXTERNALCOMMANDHELPER_H #include #include #include #include -#include #include using namespace KAuth; class ExternalCommandHelper : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kpmcore.externalcommand") Q_SIGNALS: void progress(int); void quit(); public: 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); Q_SCRIPTABLE QVariantMap start(const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode); Q_SCRIPTABLE QVariantMap copyblocks(const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize); Q_SCRIPTABLE bool writeData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetFirstByte); Q_SCRIPTABLE void exit(); private: void onReadOutput(); std::unique_ptr m_loop; QProcess m_cmd; // QByteArray output; }; #endif