diff --git a/src/backend/corebackenddevice.h b/src/backend/corebackenddevice.h index 600adc6..b3c3126 100644 --- a/src/backend/corebackenddevice.h +++ b/src/backend/corebackenddevice.h @@ -1,121 +1,104 @@ /************************************************************************* * 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_COREBACKENDDEVICE_H) #define KPMCORE_COREBACKENDDEVICE_H #include class CoreBackendPartition; class CoreBackendPartitionTable; class Partition; class PartitionTable; class Report; /** * Interface class for devices in the backend plugin. * For a device description, see Device. This * CoreBackendDevice can be used for (read- and) write * operations on the raw device. * * @author Volker Lanz */ class CoreBackendDevice { public: CoreBackendDevice(const QString& deviceNode); virtual ~CoreBackendDevice() {} public: /** * Get the device path for this device (e.g. "/dev/sda") * @return the device path */ virtual const QString& deviceNode() const { return m_DeviceNode; } /** * Determine if this device is opened in exclusive mode. * @return true if it is opened in exclusive mode, otherwise false */ virtual bool isExclusive() const { return m_Exclusive; } /** * Open the backend device * @return true if successful */ virtual bool open() = 0; /** * Open the backend device in exclusive mode * @return true if successful */ virtual bool openExclusive() = 0; /** * Close the backend device * @return true if successful */ virtual bool close() = 0; /** * Open this backend device's partition table * @return a pointer to the CoreBackendPartitionTable for this device or nullptr in case * of errors */ virtual CoreBackendPartitionTable* openPartitionTable() = 0; /** * Create a new partition table on this device. * @param report the Report to write information to * @param ptable the PartitionTable to create on this backend device * @return true if successful */ virtual bool createPartitionTable(Report& report, const PartitionTable& ptable) = 0; - /** - * Read data from an opened device into a buffer. - * @param buffer the buffer to write the read data to - * @param offset offset byte where to start reading on the device - * @param size the number of bytes to read - * @return true on success - */ - virtual bool readData(QByteArray& buffer, qint64 offset, qint64 size) = 0; - - /** - * Write data from a buffer to an exclusively opened device. - * @param buffer the buffer with the data - * @param offset offset byte where to start writing to the device - * @return true on success - */ - virtual bool writeData(QByteArray& buffer, qint64 offset) = 0; - protected: void setExclusive(bool b) { m_Exclusive = b; } private: const QString m_DeviceNode; bool m_Exclusive; }; #endif diff --git a/src/core/copysource.h b/src/core/copysource.h index 3f25e7f..f8f36b2 100644 --- a/src/core/copysource.h +++ b/src/core/copysource.h @@ -1,56 +1,55 @@ /************************************************************************* * 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_COPYSOURCE_H) #define KPMCORE_COPYSOURCE_H #include class CopyTarget; class QString; /** Base class for something to copy from. Abstract base class for all copy sources. Used in combination with CopyTarget to implement moving, copying, backing up and restoring FileSystems. @see CopyTarget @author Volker Lanz */ class CopySource { Q_DISABLE_COPY(CopySource) protected: CopySource() {} virtual ~CopySource() {} public: virtual bool open() = 0; virtual QString path() const = 0; - virtual bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) = 0; virtual qint64 length() const = 0; virtual bool overlaps(const CopyTarget& target) const = 0; virtual qint64 firstByte() const = 0; virtual qint64 lastByte() const = 0; private: }; #endif diff --git a/src/core/copysourcedevice.cpp b/src/core/copysourcedevice.cpp index 3b91744..9754a0d 100644 --- a/src/core/copysourcedevice.cpp +++ b/src/core/copysourcedevice.cpp @@ -1,110 +1,94 @@ /************************************************************************* * 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 "core/copysourcedevice.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "core/copytarget.h" #include "core/copytargetdevice.h" #include "core/device.h" /** Constructs a CopySource on the given Device @param d Device from which to copy @param firstbyte the first byte that will be copied @param lastbyte the last byte that will be copied */ CopySourceDevice::CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte) : CopySource(), m_Device(d), m_FirstByte(firstbyte), m_LastByte(lastbyte), m_BackendDevice(nullptr) { } /** Destructs a CopySourceDevice */ CopySourceDevice::~CopySourceDevice() { delete m_BackendDevice; } /** Opens the Device @return true if the Device could be successfully opened */ bool CopySourceDevice::open() { m_BackendDevice = CoreBackendManager::self()->backend()->openDeviceExclusive(device()); return m_BackendDevice != nullptr; } /** Returns the length of this CopySource @return length of the copy source */ qint64 CopySourceDevice::length() const { return lastByte() - firstByte() + 1; } -/** Reads a given number of bytes from the Device into the given buffer. - - Note that @p readOffset must be greater or equal than zero. - - @param buffer the buffer to store the read bytes in - @param readOffset the offset to begin reading - @param size the number of bytes to read - - @return true if successful -*/ -bool CopySourceDevice::readData(QByteArray& buffer, qint64 readOffset, qint64 size) -{ - Q_ASSERT(readOffset >= 0); - return m_BackendDevice->readData(buffer, readOffset, size); -} - /** Checks if this CopySourceDevice overlaps with the given CopyTarget @param target the CopyTarget to check overlapping with @return true if overlaps */ bool CopySourceDevice::overlaps(const CopyTarget& target) const { try { const CopyTargetDevice& t = dynamic_cast(target); if (device().deviceNode() != t.device().deviceNode()) return false; // overlapping at the front? if (firstByte() <= t.firstByte() && lastByte() >= t.firstByte()) return true; // overlapping at the back? if (firstByte() <= t.lastByte() && lastByte() >= t.lastByte()) return true; } catch (...) { } return false; } QString CopySourceDevice::path() const { return m_Device.deviceNode(); } diff --git a/src/core/copysourcedevice.h b/src/core/copysourcedevice.h index 04f1734..bfdbd45 100644 --- a/src/core/copysourcedevice.h +++ b/src/core/copysourcedevice.h @@ -1,75 +1,74 @@ /************************************************************************* * 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_COPYSOURCEDEVICE_H) #define KPMCORE_COPYSOURCEDEVICE_H #include "core/copysource.h" #include "util/libpartitionmanagerexport.h" #include class Device; class CopyTarget; class CoreBackendDevice; class QString; /** A Device to copy from. Represents a Device to copy from. Used to copy a Partition to somewhere on the same or another Device or to backup its FileSystem to a file. @author Volker Lanz */ class CopySourceDevice : public CopySource { Q_DISABLE_COPY(CopySourceDevice) public: CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte); ~CopySourceDevice(); public: bool open() override; - bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override; qint64 length() const override; bool overlaps(const CopyTarget& target) const override; qint64 firstByte() const override { return m_FirstByte; /**< @return first byte to copy */ } qint64 lastByte() const override { return m_LastByte; /**< @return last byte to copy */ } Device& device() { return m_Device; /**< @return Device to copy from */ } const Device& device() const { return m_Device; /**< @return Device to copy from */ } QString path() const override; protected: Device& m_Device; const qint64 m_FirstByte; const qint64 m_LastByte; CoreBackendDevice* m_BackendDevice; }; #endif diff --git a/src/core/copysourcefile.cpp b/src/core/copysourcefile.cpp index 936aec0..40c3a15 100644 --- a/src/core/copysourcefile.cpp +++ b/src/core/copysourcefile.cpp @@ -1,62 +1,47 @@ /************************************************************************* * 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 "core/copysourcefile.h" #include #include /** Constructs a CopySourceFile from the given @p filename. @param filename filename of the file to copy from */ CopySourceFile::CopySourceFile(const QString& filename) : CopySource(), m_File(filename) { } /** Opens the file. @return true on success */ bool CopySourceFile::open() { return file().open(QIODevice::ReadOnly); } /** Returns the length of the file in bytes. @return length of the file in bytes. */ qint64 CopySourceFile::length() const { return QFileInfo(file()).size(); } - -/** Reads the given number of bytes from the file into the given buffer. - @param buffer buffer to store the bytes read in - @param readOffset offset where to begin reading - @param size the number of bytes to read - @return true on success -*/ -bool CopySourceFile::readData(QByteArray& buffer, qint64 readOffset, qint64 size) -{ - if (!file().seek(readOffset)) - return false; - - buffer = file().read(size); - return !buffer.isEmpty(); -} diff --git a/src/core/copysourcefile.h b/src/core/copysourcefile.h index 0ff8ff7..3a5cebd 100644 --- a/src/core/copysourcefile.h +++ b/src/core/copysourcefile.h @@ -1,71 +1,70 @@ /************************************************************************* * 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_COPYSOURCEFILE_H) #define KPMCORE_COPYSOURCEFILE_H #include "core/copysource.h" #include #include class QString; class CopyTarget; /** A file to copy from. Represents a file to copy from. Used to restore a FileSystem from a backup file. @author Volker Lanz */ class CopySourceFile : public CopySource { public: CopySourceFile(const QString& filename); public: bool open() override; - bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override; qint64 length() const override; bool overlaps(const CopyTarget&) const override { return false; /**< @return false for file */ } qint64 firstByte() const override { return 0; /**< @return 0 for file */ } qint64 lastByte() const override { return length(); /**< @return equal to length for file. @see length() */ } QString path() const override { return m_File.fileName(); } protected: QFile& file() { return m_File; } const QFile& file() const { return m_File; } protected: QFile m_File; }; #endif diff --git a/src/core/copysourceshred.cpp b/src/core/copysourceshred.cpp index b8d708e..91ab354 100644 --- a/src/core/copysourceshred.cpp +++ b/src/core/copysourceshred.cpp @@ -1,59 +1,45 @@ /************************************************************************* * 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 "core/copysourceshred.h" /** Constructs a CopySourceShred with the given @p size @param s the size the copy source will (pretend to) have */ CopySourceShred::CopySourceShred(qint64 s, bool randomShred) : CopySource(), m_Size(s), m_SourceFile(randomShred ? QStringLiteral("/dev/urandom") : QStringLiteral("/dev/zero")) { } /** Opens the shred source. @return true on success */ bool CopySourceShred::open() { return sourceFile().open(QIODevice::ReadOnly); } /** Returns the length of the source in bytes. @return length of the source in bytes. */ qint64 CopySourceShred::length() const { return size(); } - -/** Reads the given number of bytes from the source into the given buffer. - @param buffer buffer to store the data read in - @param readOffset offset where to begin reading (unused) - @param size the number of bytes to read - @return true on success -*/ -bool CopySourceShred::readData(QByteArray& buffer, qint64 readOffset, qint64 size) -{ - Q_UNUSED(readOffset); - - buffer = sourceFile().read(size); - return !buffer.isEmpty(); -} diff --git a/src/core/copysourceshred.h b/src/core/copysourceshred.h index e293531..a181100 100644 --- a/src/core/copysourceshred.h +++ b/src/core/copysourceshred.h @@ -1,74 +1,73 @@ /************************************************************************* * 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_COPYSOURCESHRED_H) #define KPMCORE_COPYSOURCESHRED_H #include "core/copysource.h" #include class CopyTarget; class QString; /** A source for securely overwriting a partition (shredding). Represents a source of data (random or zeros) to copy from. Used to securely overwrite data on disk. @author Volker Lanz */ class CopySourceShred : public CopySource { public: CopySourceShred(qint64 size, bool randomShred); public: bool open() override; - bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override; qint64 length() const override; bool overlaps(const CopyTarget&) const override { return false; /**< @return false for shred source */ } qint64 firstByte() const override { return 0; /**< @return 0 for shred source */ } qint64 lastByte() const override { return length(); /**< @return equal to length for shred source. @see length() */ } QString path() const override { return m_SourceFile.fileName(); } protected: QFile& sourceFile() { return m_SourceFile; } const QFile& sourceFile() const { return m_SourceFile; } qint64 size() const { return m_Size; } private: qint64 m_Size; QFile m_SourceFile; }; #endif diff --git a/src/core/copytarget.h b/src/core/copytarget.h index 97385a1..92324f6 100644 --- a/src/core/copytarget.h +++ b/src/core/copytarget.h @@ -1,61 +1,60 @@ /************************************************************************* * 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_COPYTARGET_H) #define KPMCORE_COPYTARGET_H #include class QString; /** Base class for something to copy to. Abstract base class for all copy targets. Used together with CopySource to implement moving, copying, restoring and backing up FileSystems. @see CopySource @author Volker Lanz */ class CopyTarget { Q_DISABLE_COPY(CopyTarget) protected: CopyTarget() : m_BytesWritten(0) {} virtual ~CopyTarget() {} public: virtual bool open() = 0; - virtual bool writeData(QByteArray& buffer, qint64 writeOffset) = 0; virtual qint64 firstByte() const = 0; virtual qint64 lastByte() const = 0; virtual QString path() const = 0; qint64 bytesWritten() const { return m_BytesWritten; } protected: void setBytesWritten(qint64 s) { m_BytesWritten = s; } private: qint64 m_BytesWritten; }; #endif diff --git a/src/core/copytargetdevice.cpp b/src/core/copytargetdevice.cpp index 92e67f2..2ad9a02 100644 --- a/src/core/copytargetdevice.cpp +++ b/src/core/copytargetdevice.cpp @@ -1,77 +1,58 @@ /************************************************************************* * 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 "core/copytargetdevice.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "core/device.h" /** Constructs a device to copy to. @param d the Device to copy to @param firstbyte the first byte on the Device to write to @param lastbyte the last byte on the Device to write to */ CopyTargetDevice::CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte) : CopyTarget(), m_Device(d), m_BackendDevice(nullptr), m_FirstByte(firstbyte), m_LastByte(lastbyte) { } /** Destructs a CopyTargetDevice */ CopyTargetDevice::~CopyTargetDevice() { delete m_BackendDevice; } /** Opens a CopyTargetDevice for writing to. @return true on success */ bool CopyTargetDevice::open() { m_BackendDevice = CoreBackendManager::self()->backend()->openDeviceExclusive(device()); return m_BackendDevice != nullptr; } -/** Writes the given number of bytes to the Device. - - Note that @p writeOffset must be greater or equal than zero. - - @param buffer the data to write - @param writeOffset where to start writing on the Device - @return true on success -*/ -bool CopyTargetDevice::writeData(QByteArray& buffer, qint64 writeOffset) -{ - Q_ASSERT(writeOffset >= 0); - bool rval = m_BackendDevice->writeData(buffer, writeOffset); - - if (rval) - setBytesWritten(bytesWritten() + buffer.size()); - - return rval; -} - QString CopyTargetDevice::path() const { return m_Device.deviceNode(); } diff --git a/src/core/copytargetdevice.h b/src/core/copytargetdevice.h index 556b75e..f7021d2 100644 --- a/src/core/copytargetdevice.h +++ b/src/core/copytargetdevice.h @@ -1,72 +1,71 @@ /************************************************************************* * 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_COPYTARGETDEVICE_H) #define KPMCORE_COPYTARGETDEVICE_H #include "core/copytarget.h" #include "util/libpartitionmanagerexport.h" #include class Device; class CoreBackendDevice; /** A Device to copy to. Represents a target Device to copy to. Used to copy a Partition to somewhere on the same or another Device or to restore a FileSystem from a file to a Partition. @see CopyTargetFile, CopySourceDevice @author Volker Lanz */ class CopyTargetDevice : public CopyTarget { Q_DISABLE_COPY(CopyTargetDevice) public: CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte); ~CopyTargetDevice(); public: bool open() override; - bool writeData(QByteArray& buffer, qint64 writeOffset) override; qint64 firstByte() const override { return m_FirstByte; /**< @return the first byte to write to */ } qint64 lastByte() const override { return m_LastByte; /**< @return the last byte to write to */ } Device& device() { return m_Device; /**< @return the Device to write to */ } const Device& device() const { return m_Device; /**< @return the Device to write to */ } QString path() const override; protected: Device& m_Device; CoreBackendDevice* m_BackendDevice; const qint64 m_FirstByte; const qint64 m_LastByte; }; #endif diff --git a/src/core/copytargetfile.cpp b/src/core/copytargetfile.cpp index 508f9b2..bd87637 100644 --- a/src/core/copytargetfile.cpp +++ b/src/core/copytargetfile.cpp @@ -1,53 +1,35 @@ /************************************************************************* * 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 "core/copytargetfile.h" /** Constructs a file to write to. @param filename name of the file to write to */ CopyTargetFile::CopyTargetFile(const QString& filename) : CopyTarget(), m_File(filename) { } /** Opens the file for writing. @return true on success */ bool CopyTargetFile::open() { return file().open(QIODevice::WriteOnly | QIODevice::Truncate); } - -/** Writes the given number of bytes from the given buffer to the file. - @param buffer the data to write - @param writeOffset where in the file to start writing - @return true on success -*/ -bool CopyTargetFile::writeData(QByteArray& buffer, qint64 writeOffset) -{ - if (!file().seek(writeOffset)) - return false; - - bool rval = file().write(buffer) == buffer.size(); - - if (rval) - setBytesWritten(bytesWritten() + buffer.size()); - - return rval; -} diff --git a/src/core/copytargetfile.h b/src/core/copytargetfile.h index 17ecff2..258a403 100644 --- a/src/core/copytargetfile.h +++ b/src/core/copytargetfile.h @@ -1,68 +1,67 @@ /************************************************************************* * 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_COPYTARGETFILE_H) #define KPMCORE_COPYTARGETFILE_H #include "core/copytarget.h" #include #include class QString; /** A file to copy to. Repesents a target file to copy to. Used to back up a FileSystem to a file. @see CopySourceFile, CopyTargetDevice @author Volker Lanz */ class CopyTargetFile : public CopyTarget { public: CopyTargetFile(const QString& filename); public: bool open() override; - bool writeData(QByteArray& buffer, qint64 writeOffset) override; qint64 firstByte() const override { return 0; /**< @return always 0 for a file */ } qint64 lastByte() const override { return bytesWritten(); /**< @return the number of bytes written so far */ } QString path() const override { return m_File.fileName(); } protected: QFile& file() { return m_File; } const QFile& file() const { return m_File; } protected: QFile m_File; }; #endif diff --git a/src/plugins/dummy/dummydevice.cpp b/src/plugins/dummy/dummydevice.cpp index 92c2de7..d2b43e9 100644 --- a/src/plugins/dummy/dummydevice.cpp +++ b/src/plugins/dummy/dummydevice.cpp @@ -1,91 +1,68 @@ /************************************************************************* * 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 "plugins/dummy/dummydevice.h" #include "plugins/dummy/dummypartitiontable.h" #include "core/partitiontable.h" #include "util/globallog.h" #include "util/report.h" DummyDevice::DummyDevice(const QString& deviceNode) : CoreBackendDevice(deviceNode) { } DummyDevice::~DummyDevice() { } bool DummyDevice::open() { return true; } bool DummyDevice::openExclusive() { return true; } bool DummyDevice::close() { return true; } CoreBackendPartitionTable* DummyDevice::openPartitionTable() { CoreBackendPartitionTable* ptable = new DummyPartitionTable(); if (ptable == nullptr || !ptable->open()) { delete ptable; ptable = nullptr; } return ptable; } bool DummyDevice::createPartitionTable(Report& report, const PartitionTable& ptable) { Q_UNUSED(report); Q_UNUSED(ptable); return true; } - -bool DummyDevice::readData(QByteArray& buffer, qint64 offset, qint64 size) -{ - Q_UNUSED(buffer); - Q_UNUSED(offset); - Q_UNUSED(size); - - if (!isExclusive()) - return false; - - return true; -} - -bool DummyDevice::writeData(QByteArray& buffer, qint64 offset) -{ - Q_UNUSED(buffer); - Q_UNUSED(offset); - - if (!isExclusive()) - return false; - - return true; -} diff --git a/src/plugins/dummy/dummydevice.h b/src/plugins/dummy/dummydevice.h index 9493365..6895e65 100644 --- a/src/plugins/dummy/dummydevice.h +++ b/src/plugins/dummy/dummydevice.h @@ -1,52 +1,49 @@ /************************************************************************* * 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_DUMMYDEVICE_H) #define KPMCORE_DUMMYDEVICE_H #include "backend/corebackenddevice.h" #include class Partition; class PartitionTable; class Report; class CoreBackendPartitionTable; class DummyDevice : public CoreBackendDevice { Q_DISABLE_COPY(DummyDevice) public: DummyDevice(const QString& deviceNode); ~DummyDevice(); public: bool open() override; bool openExclusive() override; bool close() override; CoreBackendPartitionTable* openPartitionTable() override; bool createPartitionTable(Report& report, const PartitionTable& ptable) override; - - bool readData(QByteArray& buffer, qint64 offset, qint64 size) override; - bool writeData(QByteArray& buffer, qint64 offset) override; }; #endif diff --git a/src/plugins/libparted/libparteddevice.cpp b/src/plugins/libparted/libparteddevice.cpp index 6354b58..d97e41c 100644 --- a/src/plugins/libparted/libparteddevice.cpp +++ b/src/plugins/libparted/libparteddevice.cpp @@ -1,132 +1,112 @@ /************************************************************************* * 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 "plugins/libparted/libparteddevice.h" #include "plugins/libparted/libpartedpartitiontable.h" #include "core/partitiontable.h" #include "util/globallog.h" #include "util/report.h" #include LibPartedDevice::LibPartedDevice(const QString& deviceNode) : CoreBackendDevice(deviceNode), m_PedDevice(nullptr) { } LibPartedDevice::~LibPartedDevice() { if (pedDevice()) close(); } bool LibPartedDevice::open() { Q_ASSERT(pedDevice() == nullptr); if (pedDevice()) return false; m_PedDevice = ped_device_get(deviceNode().toLocal8Bit().constData()); return m_PedDevice != nullptr; } bool LibPartedDevice::openExclusive() { bool rval = open() && ped_device_open(pedDevice()); if (rval) setExclusive(true); return rval; } bool LibPartedDevice::close() { Q_ASSERT(pedDevice()); if (pedDevice() && isExclusive()) { ped_device_close(pedDevice()); setExclusive(false); } m_PedDevice = nullptr; return true; } CoreBackendPartitionTable* LibPartedDevice::openPartitionTable() { CoreBackendPartitionTable* ptable = new LibPartedPartitionTable(pedDevice()); if (ptable == nullptr || !ptable->open()) { delete ptable; ptable = nullptr; } return ptable; } bool LibPartedDevice::createPartitionTable(Report& report, const PartitionTable& ptable) { PedDiskType* pedDiskType = ped_disk_type_get(ptable.typeName().toLocal8Bit().constData()); if (pedDiskType == nullptr) { report.line() << xi18nc("@info:progress", "Creating partition table failed: Could not retrieve partition table type \"%1\" for %2.", ptable.typeName(), deviceNode()); return false; } PedDevice* dev = ped_device_get(deviceNode().toLocal8Bit().constData()); if (dev == nullptr) { report.line() << xi18nc("@info:progress", "Creating partition table failed: Could not open backend device %1.", deviceNode()); return false; } PedDisk* disk = ped_disk_new_fresh(dev, pedDiskType); if (disk == nullptr) { report.line() << xi18nc("@info:progress", "Creating partition table failed: Could not create a new partition table in the backend for device %1.", deviceNode()); return false; } return LibPartedPartitionTable::commit(disk); } - -bool LibPartedDevice::readData(QByteArray& buffer, qint64 offset, qint64 size) -{ - if (!isExclusive()) - return false; - - void *data = malloc(size); - bool rval = ped_device_read(pedDevice(), data, offset / pedDevice()->sector_size, size / pedDevice()->sector_size); - buffer = QByteArray(static_cast(data), size); - free(data); - return rval; -} - -bool LibPartedDevice::writeData(QByteArray& buffer, qint64 offset) -{ - if (!isExclusive()) - return false; - - return ped_device_write(pedDevice(), static_cast(buffer.constData()), offset / pedDevice()->sector_size, buffer.size() / pedDevice()->sector_size); -} diff --git a/src/plugins/libparted/libparteddevice.h b/src/plugins/libparted/libparteddevice.h index c8d98c0..dc8f16a 100644 --- a/src/plugins/libparted/libparteddevice.h +++ b/src/plugins/libparted/libparteddevice.h @@ -1,62 +1,59 @@ /************************************************************************* * 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_LIBPARTEDDEVICE_H) #define KPMCORE_LIBPARTEDDEVICE_H #include "backend/corebackenddevice.h" #include #include class Partition; class PartitionTable; class Report; class CoreBackendPartitionTable; class LibPartedDevice : public CoreBackendDevice { Q_DISABLE_COPY(LibPartedDevice) public: LibPartedDevice(const QString& deviceNode); ~LibPartedDevice(); public: bool open() override; bool openExclusive() override; bool close() override; CoreBackendPartitionTable* openPartitionTable() override; bool createPartitionTable(Report& report, const PartitionTable& ptable) override; - bool readData(QByteArray& buffer, qint64 offset, qint64 size) override; - bool writeData(QByteArray& buffer, qint64 offset) override; - protected: PedDevice* pedDevice() { return m_PedDevice; } private: PedDevice* m_PedDevice; }; #endif diff --git a/src/plugins/sfdisk/sfdiskdevice.cpp b/src/plugins/sfdisk/sfdiskdevice.cpp index c8ce382..7dfc248 100644 --- a/src/plugins/sfdisk/sfdiskdevice.cpp +++ b/src/plugins/sfdisk/sfdiskdevice.cpp @@ -1,118 +1,81 @@ /************************************************************************* * 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 "plugins/sfdisk/sfdiskdevice.h" #include "plugins/sfdisk/sfdiskpartitiontable.h" #include "core/partitiontable.h" #include "util/externalcommand.h" #include "util/report.h" SfdiskDevice::SfdiskDevice(const Device& d) : CoreBackendDevice(d.deviceNode()), m_device(&d) { } SfdiskDevice::~SfdiskDevice() { close(); } bool SfdiskDevice::open() { return true; } bool SfdiskDevice::openExclusive() { setExclusive(true); return true; } bool SfdiskDevice::close() { if (isExclusive()) setExclusive(false); CoreBackendPartitionTable* ptable = new SfdiskPartitionTable(m_device); ptable->commit(); delete ptable; return true; } CoreBackendPartitionTable* SfdiskDevice::openPartitionTable() { return new SfdiskPartitionTable(m_device); } bool SfdiskDevice::createPartitionTable(Report& report, const PartitionTable& ptable) { QByteArray tableType; if (ptable.type() == PartitionTable::msdos || ptable.type() == PartitionTable::msdos_sectorbased) tableType = QByteArrayLiteral("dos"); else tableType = ptable.typeName().toLocal8Bit(); ExternalCommand createCommand(report, QStringLiteral("sfdisk"), { m_device->deviceNode() } ); if ( createCommand.write(QByteArrayLiteral("label: ") + tableType + QByteArrayLiteral("\nwrite\n")) && createCommand.start(-1) && createCommand.waitFor() ) { return createCommand.output().contains(QStringLiteral("Script header accepted.")); } return false; } - -bool SfdiskDevice::readData(QByteArray& buffer, qint64 offset, qint64 size) -{ - if (!isExclusive()) - return false; - - ExternalCommand ddCommand(QStringLiteral("dd"), { - QStringLiteral("skip=") + QString::number(offset), - QStringLiteral("bs=") + QString::number(size), - QStringLiteral("count=1"), - QStringLiteral("iflag=skip_bytes"), - QStringLiteral("if=") + m_device->deviceNode() }, QProcess::SeparateChannels); - if (ddCommand.run(-1) && ddCommand.exitCode() == 0) { - buffer = ddCommand.rawOutput(); - return true; - } - - return false; -} - -bool SfdiskDevice::writeData(QByteArray& buffer, qint64 offset) -{ - if (!isExclusive()) - return false; - - ExternalCommand ddCommand(QStringLiteral("dd"), { - QStringLiteral("of=") + m_device->deviceNode(), - QStringLiteral("seek=") + QString::number(offset), - QStringLiteral("bs=1M"), - QStringLiteral("oflag=seek_bytes"), - QStringLiteral("conv=fsync") }, QProcess::SeparateChannels); - if ( ddCommand.write(buffer) && ddCommand.start(-1) && ddCommand.waitFor() && ddCommand.exitCode() == 0 ) { - return true; - } - - return false; -} diff --git a/src/plugins/sfdisk/sfdiskdevice.h b/src/plugins/sfdisk/sfdiskdevice.h index aeab327..096dd74 100644 --- a/src/plugins/sfdisk/sfdiskdevice.h +++ b/src/plugins/sfdisk/sfdiskdevice.h @@ -1,56 +1,53 @@ /************************************************************************* * 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(SFDISKDEVICE__H) #define SFDISKDEVICE__H #include "backend/corebackenddevice.h" #include "core/device.h" #include class Partition; class PartitionTable; class Report; class CoreBackendPartitionTable; class SfdiskDevice : public CoreBackendDevice { Q_DISABLE_COPY(SfdiskDevice); public: SfdiskDevice(const Device& d); ~SfdiskDevice(); public: bool open() override; bool openExclusive() override; bool close() override; CoreBackendPartitionTable* openPartitionTable() override; bool createPartitionTable(Report& report, const PartitionTable& ptable) override; - bool readData(QByteArray& buffer, qint64 offset, qint64 size) override; - bool writeData(QByteArray& buffer, qint64 offset) override; - private: const Device *m_device; }; #endif diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp index 3d77b81..3694e5b 100644 --- a/src/util/externalcommandhelper.cpp +++ b/src/util/externalcommandhelper.cpp @@ -1,198 +1,210 @@ /************************************************************************* * 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 "externalcommandhelper.h" #include #include #include #include #include #include - +/** 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(QString& sourceDevice, QByteArray& buffer, qint64 offset, 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 %1.", 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(QString &targetDevice, QByteArray& buffer, 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 %1.", targetDevice); return false; } if (device.write(buffer) != buffer.size()) { qCritical() << xi18n("Could not write to device %1.", targetDevice); return false; } return true; } ActionReply ExternalCommandHelper::copyblockshelper(const QVariantMap& args) { command = args[QStringLiteral("command")].toString(); qint64 blockSize = args[QStringLiteral("blockSize")].toLongLong(); qint64 blocksToCopy = args[QStringLiteral("blocksToCopy")].toLongLong(); qint64 readOffset = args[QStringLiteral("readOffset")].toLongLong(); qint64 writeOffset = args[QStringLiteral("writeOffset")].toLongLong(); qint32 copyDirection = args[QStringLiteral("copyDirection")].toLongLong(); QString sourceDevice = args[QStringLiteral("sourceDevice")].toString(); QString targetDevice = args[QStringLiteral("targetDevice")].toString(); qint64 lastBlock = args[QStringLiteral("lastBlock")].toLongLong(); qint64 sourceFirstByte = args[QStringLiteral("sourceFirstByte")].toLongLong(); qint64 targetFirstByte = args[QStringLiteral("targetFirstByte")].toLongLong(); qint64 sourceLength = args[QStringLiteral("sourceLength")].toLongLong(); QStringList environment = args[QStringLiteral("environment")].toStringList(); ActionReply reply; cmd.setEnvironment(environment); 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) { 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) 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); return reply; } ActionReply ExternalCommandHelper::start(const QVariantMap& args) { ActionReply reply; QString command = args[QStringLiteral("command")].toString(); QStringList arguments = args[QStringLiteral("arguments")].toStringList(); QStringList environment = args[QStringLiteral("environment")].toStringList(); QByteArray input = args[QStringLiteral("input")].toByteArray(); // connect(&cmd, &QProcess::readyReadStandardOutput, this, &ExternalCommandHelper::onReadOutput); cmd.setEnvironment(environment); cmd.start(command, arguments); cmd.write(input); cmd.closeWriteChannel(); cmd.waitForFinished(-1); QByteArray output = cmd.readAllStandardOutput(); reply.addData(QStringLiteral("output"), output); reply.addData(QStringLiteral("exitCode"), cmd.exitCode()); return reply; } 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)