Compare commits

..

No commits in common. "master" and "v4.2.0" have entirely different histories.

94 changed files with 480 additions and 1027 deletions

View File

@ -1,8 +0,0 @@
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0
include:
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/reuse-lint.yml

View File

@ -1,11 +0,0 @@
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0
Dependencies:
- 'on': ['@all']
'require':
'frameworks/extra-cmake-modules': '@latest'
'frameworks/kcoreaddons': '@latest'
'frameworks/ki18n': '@latest'
'frameworks/kwidgetsaddons': '@latest'
'libraries/polkit-qt-1': '@latest'

View File

@ -18,7 +18,7 @@ Files: src/util/org.kde.kpmcore.helperinterface.conf
License: MIT
Copyright: 2018 Andrius Štikonas <andrius@stikonas.eu>
# Just list of directories
Files: src/util/trustedprefixes
### KAuth actions
Files: src/util/org.kde.kpmcore.externalcommand.actions
License: CC0-1.0
Copyright: None
Copyright: 2018 Andrius Štikonas <andrius@stikonas.eu>

View File

@ -1,39 +1,35 @@
# SPDX-FileCopyrightText: 2008 Volker Lanz <vl@fidra.de>
# SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
# SPDX-FileCopyrightText: 2014-2022 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2014-2020 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2020 David Edmundson <kde@davidedmundson.co.uk>
# SPDX-License-Identifier: GPL-3.0-or-later
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
project(kpmcore)
# KDE Application Version, managed by release script
set (RELEASE_SERVICE_VERSION_MAJOR "22")
set (RELEASE_SERVICE_VERSION_MINOR "07")
set (RELEASE_SERVICE_VERSION_MICRO "70")
set (RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
project(kpmcore VERSION ${RELEASE_SERVICE_VERSION})
set(SOVERSION "12")
add_definitions(-D'VERSION="${RELEASE_SERVICE_VERSION}"') #"
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
set(CMAKE_USE_RELATIVE_PATHS OFF)
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
# Note that KPMcore is restricted to only run binaries installed into trusted prefixes
# See src/util/trustedprefixes
# By default this is set to / and /usr which is good for majority of distros
# Dependencies
set(QT_MIN_VERSION "5.15.0")
set(KF5_MIN_VERSION "5.90")
set(QT_MIN_VERSION "5.14.0")
set(KF5_MIN_VERSION "5.56")
set(BLKID_MIN_VERSION "2.33.2")
# PolkitQt5-1
# Runtime
# smartmontools 7.0
set(KDE_COMPILERSETTINGS_LEVEL "5.85")
set(VERSION_MAJOR "4")
set(VERSION_MINOR "2")
set(VERSION_RELEASE "0")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE})
set(SOVERSION "10")
add_definitions(-D'VERSION="${VERSION}"') #"
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
@ -46,16 +42,12 @@ include(GenerateExportHeader)
include(ECMSetupVersion)
include(ECMConfiguredInstall)
ecm_setup_version(${RELEASE_SERVICE_VERSION} VARIABLE_PREFIX KPMCORE
ecm_setup_version(${VERSION} VARIABLE_PREFIX KPMCORE
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kpmcore_version.h"
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KPMcoreConfigVersion.cmake"
SOVERSION ${SOVERSION})
if (NOT QT_MAJOR_VERSION)
set(QT_MAJOR_VERSION "5")
endif()
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} COMPONENTS REQUIRED
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
Core
DBus
Gui
@ -64,14 +56,26 @@ find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} COMPONENTS REQUIRED
# Load the frameworks we need
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED
Auth
CoreAddons
I18n
WidgetsAddons
)
find_package(PolkitQt${QT_MAJOR_VERSION}-1 REQUIRED)
find_package(PolkitQt5-1 REQUIRED)
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050f00)
# use sane compile flags
add_definitions(
-DQT_USE_QSTRINGBUILDER
-DQT_NO_CAST_TO_ASCII
-DQT_NO_CAST_FROM_ASCII
-DQT_STRICT_ITERATORS
-DQT_NO_URL_CAST_FROM_STRING
-DQT_NO_CAST_FROM_BYTEARRAY
-DQT_NO_CAST_TO_BYTEARRAY
-DQT_USE_FAST_OPERATOR_PLUS
-DQT_NO_KEYWORDS
)
kde_enable_exceptions()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@ -79,14 +83,18 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
pkg_check_modules(BLKID REQUIRED blkid>=${BLKID_MIN_VERSION})
endif()
include_directories(${Qt5Core_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS} ${BLKID_INCLUDE_DIRS} lib/ src/)
add_subdirectory(src)
# create a Config.cmake and a ConfigVersion.cmake file and install them
set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KPMcore")
set(INCLUDE_INSTALL_DIR "include/kpmcore/")
set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KPMcore")
configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/KPMcoreConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/KPMcoreConfig.cmake"
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
PATH_VARS INCLUDE_INSTALL_DIR
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KPMcoreConfig.cmake"
@ -99,10 +107,10 @@ install(EXPORT KPMcoreTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KPMc
ki18n_install(po)
set_target_properties( kpmcore
PROPERTIES VERSION ${RELEASE_SERVICE_VERSION} SOVERSION ${SOVERSION}
PROPERTIES VERSION ${VERSION} SOVERSION ${SOVERSION}
)
message(STATUS "kpmcore ${RELEASE_SERVICE_VERSION} will be built for install into ${CMAKE_INSTALL_PREFIX}")
message(STATUS "kpmcore ${VERSION} will be built for install into ${CMAKE_INSTALL_PREFIX}")
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)

View File

@ -1,11 +1,9 @@
# SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
# SPDX-FileCopyrightText: 2016-2022 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2016 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-License-Identifier: GPL-3.0-or-later
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Qt@QT_MAJOR_VERSION@ @QT_MIN_VERSION@ COMPONENTS Core)
set_and_check(KPMCORE_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
include("${CMAKE_CURRENT_LIST_DIR}/KPMcoreTargets.cmake")

View File

@ -1,4 +1,4 @@
<!-- SPDX-FileCopyrightText: 2017 Adriaan de Groot <groot@kde.org>
<!-- SPDX-FileCopyrightText: 2017 Adriaan de Groot <groot@kde.org>
SPDX-FileCopyrightText: 2017-2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-License-Identifier: CC-BY-4.0
-->
@ -35,6 +35,7 @@ looks like this:
```cmake
find_package( KPMcore 3.2 REQUIRED )
include_directories( ${KPMCORE_INCLUDE_DIR} )
target_link_libraries( target kpmcore )
```

View File

@ -1,17 +0,0 @@
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
maintainer: stikonas
description: KPMcore, the KDE Partition Manager core, is a library for examining and modifying partitions, disk devices, and filesystems.
platforms:
- name: Linux
release: true
public_lib: true
public_source_dirs:
- src
libraries:
- cmake: kpmcore
cmakename: KPMcore
irc: kde-devel
mailinglist: kde-devel

View File

@ -1,16 +1,11 @@
# SPDX-FileCopyrightText: 2008,2012 Volker Lanz <vl@fidra.de>
# SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
# SPDX-FileCopyrightText: 2014-2020 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2021 Harald Sitter <sitter@kde.org>
# SPDX-License-Identifier: GPL-3.0-or-later
add_definitions(-DTRANSLATION_DOMAIN=\"kpmcore\")
include_directories(
${BLKID_INCLUDE_DIRS}
)
include(backend/CMakeLists.txt)
include(core/CMakeLists.txt)
include(util/CMakeLists.txt)
@ -33,31 +28,24 @@ ki18n_wrap_ui(kpmcore_SRCS ${gui_UIFILES})
add_library(kpmcore SHARED ${kpmcore_SRCS})
target_link_libraries( kpmcore PUBLIC
Qt::Core
Qt5::Core
PRIVATE
${BLKID_LIBRARIES}
Qt::DBus
Qt::Gui
Qt5::DBus
Qt5::Gui
KF5::I18n
KF5::CoreAddons
KF5::WidgetsAddons
)
generate_export_header(kpmcore
BASE_NAME LIBKPMCORE
EXPORT_FILE_NAME util/libpartitionmanagerexport.h
)
list(APPEND UTIL_LIB_HDRS ${CMAKE_CURRENT_BINARY_DIR}/util/libpartitionmanagerexport.h)
target_include_directories(kpmcore INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR}/kpmcore>")
install(TARGETS kpmcore EXPORT KPMcoreTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES ${CORE_LIB_HDRS} DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kpmcore/core/ COMPONENT Devel)
install(FILES ${BACKEND_LIB_HDRS} DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kpmcore/backend/ COMPONENT Devel)
install(FILES ${FS_LIB_HDRS} DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kpmcore/fs/ COMPONENT Devel)
install(FILES ${JOBS_LIB_HDRS} DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kpmcore/jobs/ COMPONENT Devel)
install(FILES ${OPS_LIB_HDRS} DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kpmcore/ops/ COMPONENT Devel)
install(FILES ${UTIL_LIB_HDRS} DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kpmcore/util/ COMPONENT Devel)
install(FILES ${GUI_LIB_HDRS} DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kpmcore/gui/ COMPONENT Devel)
install(TARGETS kpmcore EXPORT KPMcoreTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES ${CORE_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/core/ COMPONENT Devel)
install(FILES ${BACKEND_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/backend/ COMPONENT Devel)
install(FILES ${FS_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/fs/ COMPONENT Devel)
install(FILES ${JOBS_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/jobs/ COMPONENT Devel)
install(FILES ${OPS_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/ops/ COMPONENT Devel)
install(FILES ${UTIL_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/util/ COMPONENT Devel)
install(FILES ${GUI_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/gui/ COMPONENT Devel)
############################################

View File

@ -4,4 +4,7 @@
# SPDX-License-Identifier: MIT
$XGETTEXT $(find -name \*.cc -o -name \*.cpp -o -name \*.h$) -o $podir/kpmcore.pot
$EXTRACTRC `find -name \*.rc` >> rc.cpp || exit 11
$EXTRACTRC `find -name \*.ui` >> rc.cpp || exit 12
$XGETTEXT `find -name \*.cc -o -name \*.cpp -o -name \*.h` rc.cpp -o $podir/kpmcore.pot
rm -f rc.cpp

View File

@ -1,26 +0,0 @@
# SPDX-FileCopyrightText: 2020 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-License-Identifier: MIT
function get_files
{
echo util/org.kde.kpmcore.externalcommand.policy
}
function po_for_file
{
case "$1" in
util/org.kde.kpmcore.externalcommand.policy)
echo kpmcore._policy_.po
;;
esac
}
function tags_for_file
{
case "$1" in
util/org.kde.kpmcore.externalcommand.policy)
echo description
echo message
;;
esac
}

View File

@ -14,8 +14,6 @@
#include "util/globallog.h"
#include <QDebug>
#include <QFileInfo>
#include <KLocalizedString>
struct CoreBackendPrivate
{
@ -31,20 +29,6 @@ CoreBackend::~CoreBackend()
{
}
bool CoreBackend::isPolkitInstalledCorrectly() {
// Assume PACKAGE_DATA_DIR is /usr/share, this is defined on polkit on buildtime so this might be wrong.
// This is a warning, not a hard failure, so it does not matter much.
QFileInfo fInfo(QStringLiteral("/usr/share/polkit-1/actions/org.kde.kpmcore.externalcommand.policy"));
// TODO: Port kpm to qCDebug, currently everything is debug.
if (!fInfo.exists()) {
qDebug() << "Installation might be wrong, we can't locate `org.kde.kpmcore.externalcommand.policy` on the polkit actions folder.";
qDebug() << "Please check if your Installation is on a different prefix and copy it to /usr/share/polkit-1/actions";
qDebug() << "That's specified for your distro. Since this is distro specific, you need to look at your distribution documentation.";
}
return fInfo.exists();
}
void CoreBackend::emitProgress(int i)
{
Q_EMIT progress(i);

View File

@ -47,7 +47,7 @@ class LIBKPMCORE_EXPORT CoreBackend : public QObject
protected:
CoreBackend();
~CoreBackend() override;
virtual ~CoreBackend();
Q_SIGNALS:
/**
@ -170,8 +170,6 @@ public:
*/
virtual void emitScanProgress(const QString& deviceNode, int i);
static bool isPolkitInstalledCorrectly();
protected:
static void setPartitionTableForDevice(Device& d, PartitionTable* p);
static void setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_primaries);

View File

@ -1,6 +1,6 @@
/*
SPDX-FileCopyrightText: 2010 Volker Lanz <vl@fidra.de>
SPDX-FileCopyrightText: 2014-2021 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2014-2018 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
@ -17,6 +17,7 @@
#include <KLocalizedString>
#include <KPluginFactory>
#include <KPluginLoader>
#include <KPluginMetaData>
struct CoreBackendManagerPrivate
@ -50,7 +51,13 @@ CoreBackend* CoreBackendManager::backend()
QVector<KPluginMetaData> CoreBackendManager::list() const
{
return KPluginMetaData::findPlugins(QStringLiteral("kpmcore"));
auto filter = [&](const KPluginMetaData &metaData) {
return metaData.serviceTypes().contains(QStringLiteral("PartitionManager/Plugin")) &&
metaData.category().contains(QStringLiteral("BackendPlugin"));
};
// find backend plugins in standard path (e.g. /usr/lib64/qt5/plugins) using filter from above
return KPluginLoader::findPlugins(QString(), filter);
}
bool CoreBackendManager::load(const QString& name)
@ -58,25 +65,29 @@ bool CoreBackendManager::load(const QString& name)
if (backend())
unload();
QString path = QStringLiteral("kpmcore/") + name;
KPluginLoader loader(name);
KPluginMetaData metadata(path);
d->m_Backend = KPluginFactory::instantiatePlugin<CoreBackend>(metadata).plugin;
KPluginFactory* factory = loader.factory();
if (!backend()) {
qWarning() << "Could not create instance of plugin " << name;
return false;
if (factory != nullptr) {
d->m_Backend = factory->create<CoreBackend>(nullptr);
QString id = loader.metaData().toVariantMap().value(QStringLiteral("MetaData"))
.toMap().value(QStringLiteral("KPlugin")).toMap().value(QStringLiteral("Id")).toString();
QString version = loader.metaData().toVariantMap().value(QStringLiteral("MetaData"))
.toMap().value(QStringLiteral("KPlugin")).toMap().value(QStringLiteral("Version")).toString();
if (id.isEmpty())
return false;
backend()->setId(id);
backend()->setVersion(version);
qDebug() << "Loaded backend plugin: " << backend()->id();
return true;
}
QString id = metadata.pluginId();
QString version = metadata.version();
if (id.isEmpty())
return false;
backend()->setId(id);
backend()->setVersion(version);
qDebug() << "Loaded backend plugin: " << backend()->id();
return true;
qWarning() << "Could not load plugin for core backend " << name << ": " << loader.errorString();
return false;
}
void CoreBackendManager::unload()

View File

@ -14,10 +14,10 @@
#include <memory>
#include <QStringList>
#include <QVector>
class QString;
class QStringList;
class KPluginMetaData;
class CoreBackend;
struct CoreBackendManagerPrivate;

View File

@ -56,7 +56,7 @@ public:
public:
explicit Device(const Device& other);
~Device() override;
virtual ~Device();
virtual bool operator==(const Device& other) const;
virtual bool operator!=(const Device& other) const;

View File

@ -82,17 +82,10 @@ FstabEntryList readFstabEntries( const QString& fstabPath )
// (4) dump frequency (optional, defaults to 0), no comment is allowed if omitted,
// (5) pass number (optional, defaults to 0), no comment is allowed if omitted,
// (#) comment (optional).
// Handle deprecated subtypes, e.g. sshfs#example. They are not relevant for partitioning, ignore them.
if (splitLine.size() < 3) {
continue;
}
auto fsSpec = splitLine.at(0);
auto mountPoint = unescapeSpaces(splitLine.at(1));
auto mountPoint = splitLine.at(1);
auto fsType = splitLine.at(2);
// Options may be omitted in some rare cases like NixOS generated fstab.
auto options = splitLine.length() >= 4 ? splitLine.at(3) : QStringLiteral("defaults");
auto options = splitLine.at(3);
switch (splitLine.length()) {
case 4:
@ -117,22 +110,6 @@ FstabEntryList readFstabEntries( const QString& fstabPath )
return fstabEntries;
}
QString escapeSpaces(const QString& mountPoint)
{
QString tmp = mountPoint;
tmp.replace(QStringLiteral(" "), QStringLiteral("\\040"));
tmp.replace(QStringLiteral("\t"), QStringLiteral("\\011"));
return tmp;
}
QString unescapeSpaces(const QString& mountPoint)
{
QString tmp = mountPoint;
tmp.replace(QStringLiteral("\\040"), QStringLiteral(" "));
tmp.replace(QStringLiteral("\\011"), QStringLiteral("\t"));
return tmp;
}
void FstabEntry::setFsSpec(const QString& s)
{
d->m_fsSpec = s;
@ -231,8 +208,8 @@ static QString findBlkIdDevice(const char *token, const QString& value)
free(c);
}
#else
Q_UNUSED(token)
Q_UNUSED(value)
Q_UNUSED(token);
Q_UNUSED(value);
#endif
return rval;
@ -240,8 +217,7 @@ static QString findBlkIdDevice(const char *token, const QString& value)
static void parseFsSpec(const QString& m_fsSpec, FstabEntry::Type& m_entryType, QString& m_deviceNode)
{
m_entryType = FstabEntry::Type::other;
m_deviceNode = m_fsSpec;
m_entryType = FstabEntry::Type::comment;
if (m_fsSpec.startsWith(QStringLiteral("UUID="))) {
m_entryType = FstabEntry::Type::uuid;
m_deviceNode = findBlkIdDevice("UUID", QString(m_fsSpec).remove(QStringLiteral("UUID=")));
@ -256,8 +232,7 @@ static void parseFsSpec(const QString& m_fsSpec, FstabEntry::Type& m_entryType,
m_deviceNode = findBlkIdDevice("PARTLABEL", QString(m_fsSpec).remove(QStringLiteral("PARTLABEL=")));
} else if (m_fsSpec.startsWith(QStringLiteral("/"))) {
m_entryType = FstabEntry::Type::deviceNode;
} else if (m_fsSpec.isEmpty()) {
m_entryType = FstabEntry::Type::comment;
m_deviceNode = m_fsSpec;
}
}
@ -267,7 +242,7 @@ std::array<unsigned int, 4> fstabColumnWidth(const FstabEntryList& fstabEntries)
{
std::array<unsigned int, 4> columnWidth;
#define FIELD_WIDTH(x) 3 + escapeSpaces(std::max_element(fstabEntries.begin(), fstabEntries.end(), [](const FstabEntry& a, const FstabEntry& b) {return escapeSpaces(a.x()).length() < escapeSpaces(b.x()).length(); })->x()).length();
#define FIELD_WIDTH(x) 3 + std::max_element(fstabEntries.begin(), fstabEntries.end(), [](const FstabEntry& a, const FstabEntry& b) {return a.x().length() < b.x().length(); })->x().length();
columnWidth[0] = FIELD_WIDTH(fsSpec);
columnWidth[1] = FIELD_WIDTH(mountPoint);
@ -287,7 +262,7 @@ static void writeEntry(QTextStream& s, const FstabEntry& entry, std::array<unsig
s.setFieldAlignment(QTextStream::AlignLeft);
s.setFieldWidth(columnWidth[0]);
s << entry.fsSpec()
<< qSetFieldWidth(columnWidth[1]) << (entry.mountPoint().isEmpty() ? QStringLiteral("none") : escapeSpaces(entry.mountPoint()))
<< qSetFieldWidth(columnWidth[1]) << (entry.mountPoint().isEmpty() ? QStringLiteral("none") : entry.mountPoint())
<< qSetFieldWidth(columnWidth[2]) << entry.type()
<< qSetFieldWidth(columnWidth[3]) << entry.optionsString() << qSetFieldWidth(0)
<< entry.dumpFreq() << " "
@ -295,7 +270,7 @@ static void writeEntry(QTextStream& s, const FstabEntry& entry, std::array<unsig
<< entry.comment() << "\n";
}
bool writeMountpoints(const FstabEntryList& fstabEntries)
bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename)
{
QString fstabContents;
QTextStream out(&fstabContents);
@ -306,5 +281,5 @@ bool writeMountpoints(const FstabEntryList& fstabEntries)
writeEntry(out, e, columnWidth);
ExternalCommand cmd;
return cmd.writeFstab(fstabContents.toLocal8Bit());
return cmd.createFile(fstabContents.toLocal8Bit(), filename);
}

View File

@ -26,7 +26,7 @@ struct FstabEntryPrivate;
class LIBKPMCORE_EXPORT FstabEntry
{
public:
enum class Type { deviceNode, uuid, label, partlabel, partuuid, comment, other };
enum class Type { deviceNode, uuid, label, partlabel, partuuid, comment };
FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq = 0, int passNumber = 0, const QString& comment = QString());
@ -111,11 +111,8 @@ private:
typedef QList<FstabEntry> FstabEntryList;
QString escapeSpaces(const QString& mountPoint);
QString unescapeSpaces(const QString& mountPoint);
LIBKPMCORE_EXPORT FstabEntryList readFstabEntries(const QString& fstabPath = QStringLiteral("/etc/fstab"));
LIBKPMCORE_EXPORT QStringList possibleMountPoints(const QString& deviceNode, const QString& fstabPath = QStringLiteral("/etc/fstab"));
LIBKPMCORE_EXPORT bool writeMountpoints(const FstabEntryList& fstabEntries);
LIBKPMCORE_EXPORT bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename = QStringLiteral("/etc/fstab"));
#endif

View File

@ -1,6 +1,6 @@
/*
SPDX-FileCopyrightText: 2016 Chantara Tith <tith.chantara@gmail.com>
SPDX-FileCopyrightText: 2016-2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2016-2019 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
SPDX-FileCopyrightText: 2019 Yuri Chornoivan <yurchor@ukr.net>
@ -21,8 +21,6 @@
#include "util/globallog.h"
#include "util/report.h"
#include <utility>
#include <QRegularExpression>
#include <QStorageInfo>
#include <QtMath>
@ -217,7 +215,7 @@ void LvmDevice::scanSystemLVM(QList<Device*>& devices)
// Inform LvmDevice about which physical volumes form that particular LvmDevice
for (const auto &d : lvmList)
for (const auto &p : std::as_const(LVM::pvList::list()))
for (const auto &p : qAsConst(LVM::pvList::list()))
if (p.vgName() == d->name())
d->physicalVolumes().append(p.partition());

View File

@ -24,6 +24,7 @@
class PartitionTable;
class Report;
class Partition;
class SmartStatus;
/** Representation of LVM Volume Group(VG).
@ -39,7 +40,7 @@ class LIBKPMCORE_EXPORT LvmDevice : public VolumeManagerDevice
public:
explicit LvmDevice(const QString& name, const QString& iconName = QString());
~LvmDevice() override;
~LvmDevice();
public:
const QStringList deviceNodes() const override;

View File

@ -45,7 +45,7 @@ public:
public:
explicit OperationStack(QObject* parent = nullptr);
~OperationStack() override;
~OperationStack();
Q_SIGNALS:
void operationsChanged();

View File

@ -264,25 +264,25 @@ private:
m_Number = n;
}
qint32 m_Number = 0;
qint32 m_Number;
Partitions m_Children;
QPointer< PartitionNode > m_Parent = nullptr;
FileSystem* m_FileSystem = nullptr;
QPointer< PartitionNode > m_Parent;
FileSystem* m_FileSystem;
PartitionRole m_Roles;
qint64 m_FirstSector = 0;
qint64 m_LastSector = 0;
qint64 m_FirstSector;
qint64 m_LastSector;
QString m_DevicePath;
QString m_Label;
QString m_Type;
QString m_UUID;
quint64 m_Attributes = 0;
quint64 m_Attributes;
QString m_PartitionPath;
QString m_MountPoint;
PartitionTable::Flags m_AvailableFlags;
PartitionTable::Flags m_ActiveFlags;
bool m_IsMounted = false;
qint64 m_SectorSize = 0;
State m_State = None;
bool m_IsMounted;
qint64 m_SectorSize;
State m_State;
};
QTextStream& operator<<(QTextStream& stream, const Partition& p);

View File

@ -33,7 +33,7 @@ public:
protected:
PartitionNode() {}
~PartitionNode() override {}
virtual ~PartitionNode() {}
public:
virtual bool insert(Partition* partNew);

View File

@ -23,8 +23,6 @@
#include "util/globallog.h"
#include <utility>
#include <KLocalizedString>
#include <QDebug>
@ -594,7 +592,7 @@ QTextStream& operator<<(QTextStream& stream, const PartitionTable& ptable)
std::sort(partitions.begin(), partitions.end(), [](const Partition* p1, const Partition* p2) { return p1->number() < p2->number(); });
for (const auto &p : std::as_const(partitions))
for (const auto &p : qAsConst(partitions))
stream << *p;
return stream;

View File

@ -14,8 +14,6 @@
#include "fs/filesystemfactory.h"
#include "util/externalcommand.h"
#include <utility>
#include <KLocalizedString>
#include <QFile>
#include <QRegularExpression>
@ -223,7 +221,7 @@ void SoftwareRAID::scanSoftwareRAID(QList<Device*>& devices)
}
}
for (const QString& name : std::as_const(availableInConf)) {
for (const QString& name : qAsConst(availableInConf)) {
SoftwareRAID *raidDevice = new SoftwareRAID(name, SoftwareRAID::Status::Inactive);
devices << raidDevice;
}

View File

@ -35,7 +35,7 @@ SmartAttribute::SmartAttribute(const SmartAttributeParsedData& a) :
m_Assessment(getAssessment(a)),
m_Value(getPrettyValue(a.prettyValue(), a.prettyUnit()))
{
}
QString SmartAttribute::assessmentToString(Assessment a)
@ -65,7 +65,7 @@ static QString getPrettyValue(quint64 value, SmartAttributeUnit unit)
switch (unit) {
case SmartAttributeUnit::Miliseconds:
rval = KFormat().formatSpelloutDuration(value);
rval = KFormat().formatDuration(value);
break;
case SmartAttributeUnit::Sectors:

View File

@ -1,7 +1,7 @@
/*
SPDX-FileCopyrightText: 2008 Lennart Poettering
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
SPDX-FileCopyrightText: 2018-2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2018-2019 Andrius Štikonas <andrius@stikonas.eu>
SPDX-License-Identifier: GPL-3.0-or-later
*/
@ -9,8 +9,6 @@
#include "smartattributeparseddata.h"
#include "core/smartdiskinformation.h"
#include <utility>
#include <QJsonObject>
#include <QMap>
#include <QRegularExpression>
@ -617,7 +615,7 @@ static SmartQuirk getQuirk(QString model, QString firmware)
QRegularExpression modelRegex;
QRegularExpression firmwareRegex;
for (const SmartAttributeParsedData::SmartQuirkDataBase &item : std::as_const(db)) {
for (const SmartAttributeParsedData::SmartQuirkDataBase &item : qAsConst(db)) {
if (!item.model.isEmpty()) {
modelRegex.setPattern(item.model);
QRegularExpressionMatch match = modelRegex.match(model);

View File

@ -1,6 +1,6 @@
/*
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
SPDX-FileCopyrightText: 2018-2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2018-2019 Andrius Štikonas <andrius@stikonas.eu>
SPDX-License-Identifier: GPL-3.0-or-later
*/
@ -9,7 +9,6 @@
#include "core/smartattributeparseddata.h"
#include <memory>
#include <utility>
static quint64 u64log2(quint64 n);
@ -146,7 +145,7 @@ bool SmartDiskInformation::updatePowerCycle()
/** Validate disk attributes status */
void SmartDiskInformation::validateBadAttributes()
{
for (const SmartAttributeParsedData &attribute : std::as_const(m_Attributes)) {
for (const SmartAttributeParsedData &attribute : qAsConst(m_Attributes)) {
if (attribute.prefailure()) {
if (attribute.goodNowValid() && !attribute.goodNow())
m_BadAttributeNow = true;
@ -162,7 +161,7 @@ void SmartDiskInformation::validateBadAttributes()
SmartAttributeParsedData *SmartDiskInformation::findAttribute(quint32 id)
{
SmartAttributeParsedData *attr = nullptr;
for (const SmartAttributeParsedData &attribute : std::as_const(m_Attributes)) {
for (const SmartAttributeParsedData &attribute : qAsConst(m_Attributes)) {
if (id == attribute.id()) {
attr = new SmartAttributeParsedData(attribute);
break;

View File

@ -1,6 +1,5 @@
/*
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
SPDX-FileCopyrightText: 2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-License-Identifier: GPL-3.0-or-later
*/
@ -13,7 +12,6 @@
#include "util/externalcommand.h"
#include <errno.h>
#include <utility>
#include <QDebug>
#include <QJsonArray>
@ -117,11 +115,7 @@ void SmartParser::loadSmartOutput()
if (m_SmartOutput.isEmpty()) {
ExternalCommand smartctl(QStringLiteral("smartctl"), { QStringLiteral("--all"), QStringLiteral("--json"), devicePath() });
// Exit status of smartctl is a bitfield, check that bits 0 and 1 are not set:
// - bit 0: command line did not parse;
// - bit 1: device open failed.
// See `man 8 smartctl` for more details.
if (smartctl.run() && (smartctl.exitCode() & 1) == 0 && (smartctl.exitCode() & 2) == 0) {
if (smartctl.run() && smartctl.exitCode() == 0) {
QByteArray output = smartctl.rawOutput();
m_SmartOutput = QJsonDocument::fromJson(output);
@ -153,7 +147,7 @@ void SmartParser::loadAttributes()
return;
}
for (const QJsonValue &value : std::as_const(attributeArray)) {
for (const QJsonValue &value : qAsConst(attributeArray)) {
SmartAttributeParsedData parsedObject(m_DiskInformation, value.toObject());
m_DiskInformation->addAttribute(parsedObject);
}

View File

@ -1,7 +1,7 @@
/*
SPDX-FileCopyrightText: 2010 Volker Lanz <vl@fidra.de>
SPDX-FileCopyrightText: 2010 Yuri Chornoivan <yurchor@ukr.net>
SPDX-FileCopyrightText: 2014-2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2014-2019 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2015-2016 Teo Mrnjavac <teo@kde.org>
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
SPDX-FileCopyrightText: 2019 Shubham Jangra <aryan100jangid@gmail.com>
@ -22,7 +22,6 @@
#include <QStringList>
#include <errno.h>
#include <utility>
SmartStatus::SmartStatus(const QString &device_path) :
m_DevicePath(device_path),
@ -145,7 +144,7 @@ void SmartStatus::addAttributes(QList<SmartAttributeParsedData> attr)
{
m_Attributes.clear();
for (const SmartAttributeParsedData &at : std::as_const(attr)) {
for (const SmartAttributeParsedData &at : qAsConst(attr)) {
SmartAttribute sm(at);
m_Attributes.append(sm);
}

View File

@ -42,8 +42,6 @@ public:
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;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -28,7 +28,6 @@ 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;
bool exfat::exfatUtils = false;
exfat::exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Exfat)
@ -37,20 +36,11 @@ exfat::exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QS
void exfat::init()
{
// Check if we are using exfat-utils or exfatprogs
exfatUtils = findExternal(QStringLiteral("mkexfatfs"));
if (exfatUtils) {
m_Create = cmdSupportFileSystem;
m_Check = findExternal(QStringLiteral("fsck.exfat"), {}, 1) ? cmdSupportFileSystem : cmdSupportNone;
m_SetLabel = findExternal(QStringLiteral("exfatlabel")) ? cmdSupportFileSystem : cmdSupportNone;
}
else {
m_Create = findExternal(QStringLiteral("mkfs.exfat"), {}, 1) ? cmdSupportFileSystem : cmdSupportNone;
m_Check = findExternal(QStringLiteral("fsck.exfat"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone;
m_SetLabel = findExternal(QStringLiteral("tune.exfat")) ? cmdSupportFileSystem : cmdSupportNone;
}
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;
@ -80,7 +70,7 @@ bool exfat::supportToolFound() const
FileSystem::SupportTool exfat::supportToolName() const
{
return SupportTool(QStringLiteral("exfatprogs"), QUrl(QStringLiteral("https://github.com/exfatprogs/exfatprogs")));
return SupportTool(QStringLiteral("exfat-utils"), QUrl(QStringLiteral("https://github.com/relan/exfat")));
}
qint64 exfat::maxCapacity() const
@ -95,7 +85,7 @@ int exfat::maxLabelLength() const
bool exfat::check(Report& report, const QString& deviceNode) const
{
ExternalCommand cmd(report, QStringLiteral("fsck.exfat"), { deviceNode });
ExternalCommand cmd(report, QStringLiteral("exfatfsck"), { deviceNode });
return cmd.run(-1) && cmd.exitCode() == 0;
}
@ -107,16 +97,7 @@ bool exfat::create(Report& report, const QString& deviceNode)
bool exfat::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel)
{
ExternalCommand cmd(report);
if (exfatUtils) {
cmd.setCommand(QStringLiteral("exfatlabel"));
cmd.setArgs({ deviceNode, newLabel });
}
else {
cmd.setCommand(QStringLiteral("tune.exfat"));
cmd.setArgs({ deviceNode, QStringLiteral("-L"), newLabel });
}
ExternalCommand cmd(report, QStringLiteral("exfatlabel"), { deviceNode, newLabel });
return cmd.run(-1) && cmd.exitCode() == 0;
}

View File

@ -96,9 +96,6 @@ public:
static CommandSupportType m_SetLabel;
static CommandSupportType m_UpdateUUID;
static CommandSupportType m_GetUUID;
private:
static bool exfatUtils;
};
}

View File

@ -91,9 +91,6 @@ public:
SupportTool supportToolName() const override;
bool supportToolFound() const override;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
public:
static CommandSupportType m_GetUsed;
static CommandSupportType m_GetLabel;

View File

@ -42,9 +42,6 @@ public:
CommandSupportType supportGrowOnline() const override {
return m_Grow;
}
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
};
}

View File

@ -42,9 +42,6 @@ public:
CommandSupportType supportGrowOnline() const override {
return m_Grow;
}
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
};
}

View File

@ -40,8 +40,6 @@ public:
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;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -140,8 +140,7 @@ bool fat12::writeLabel(Report& report, const QString& deviceNode, const QString&
{
report.line() << xi18nc("@info:progress", "Setting label for partition <filename>%1</filename> to %2", deviceNode, newLabel.toUpper());
const QString label = newLabel.isEmpty() ? QStringLiteral("-r") : newLabel.toUpper();
ExternalCommand cmd(report, QStringLiteral("fatlabel"), { deviceNode, label });
ExternalCommand cmd(report, QStringLiteral("fatlabel"), { deviceNode, newLabel.toUpper() });
return cmd.run(-1) && cmd.exitCode() == 0;
}

View File

@ -31,7 +31,6 @@
#include <QFileInfo>
#include <QStandardPaths>
#include <QStorageInfo>
#include <QTemporaryDir>
const std::vector<QColor> FileSystem::defaultColorCode =
{
@ -81,7 +80,6 @@ struct FileSystemPrivate {
qint64 m_SectorsUsed;
QString m_Label;
QString m_UUID;
QString m_posixPermissions;
QStringList m_AvailableFeatures;
QVariantMap m_Features;
};
@ -128,67 +126,6 @@ FileSystem::~FileSystem()
{
}
QString FileSystem::implPosixPermissions() const
{
return d->m_posixPermissions;
}
void FileSystem::implSetPosixPermissions(const QString& permissions)
{
d->m_posixPermissions = permissions;
}
bool FileSystem::execChangePosixPermission(Report& report, const QString& deviceNode)
{
// do nothing if the posix permissions is not used here.
if (d->m_posixPermissions.isEmpty()) {
return true;
}
QTemporaryDir tmpDir;
ExternalCommand mountCmd(report, QStringLiteral("mount"),
{ deviceNode, tmpDir.path() });
bool step = mountCmd.run() && mountCmd.exitCode() == 0;
if (!step) {
return false;
}
ExternalCommand chmodCmd(report, QStringLiteral("chmod"),
// forcing recursive, should be empty but
// programming is weird.
{
d->m_posixPermissions,
tmpDir.path(),
QStringLiteral("--recursive")
});
const bool chmodStep = chmodCmd.run() && chmodCmd.exitCode() == 0;
ExternalCommand umountCmd(report, QStringLiteral("umount"),
// forcing recursive, should be empty but
// programming is weird.
{
deviceNode,
});
const bool umountStep = umountCmd.run() && umountCmd.exitCode() == 0;
// we can't return false if chmodStep fails because we still need to umount
// the drive.
if (!chmodStep) {
return false;
}
if (!umountStep) {
return false;
}
return true;
}
/** Reads the capacity in use on this FileSystem
@param deviceNode the device node for the Partition the FileSystem is on
@return the used capacity in bytes or -1 in case of an error

View File

@ -113,9 +113,6 @@ protected:
FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type);
FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features, FileSystem::Type type);
QString implPosixPermissions() const;
void implSetPosixPermissions(const QString& permissions);
public:
virtual ~FileSystem();
@ -202,14 +199,6 @@ public:
virtual SupportTool supportToolName() const;
virtual bool supportToolFound() const;
virtual QString posixPermissions() const { return QString{}; };
virtual void setPosixPermissions(const QString& permissions) { Q_UNUSED(permissions); };
// Tries to change the posix permission on the filesystem, if the
// filesystem supports it. by supports I mean reimplements `posixPermissions()`
// and setPosixPermissions.
bool execChangePosixPermission(Report& report, const QString& deviceNode);
/**
* Returns the (possibly translated) name of the type of this filesystem.
* @see nameForType()

View File

@ -1,6 +1,6 @@
/*
SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
SPDX-FileCopyrightText: 2012-2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2012-2019 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2015-2016 Teo Mrnjavac <teo@kde.org>
SPDX-FileCopyrightText: 2017 Pali Rohár <pali.rohar@gmail.com>
SPDX-FileCopyrightText: 2019 Shubham Jangra <aryan100jangid@gmail.com>
@ -10,8 +10,6 @@
SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <utility>
#include "fs/filesystemfactory.h"
#include "fs/filesystem.h"
@ -94,7 +92,7 @@ void FileSystemFactory::init()
fileSystems.insert(FileSystem::Type::Xfs, new FS::xfs(-1, -1, -1, QString()));
fileSystems.insert(FileSystem::Type::Zfs, new FS::zfs(-1, -1, -1, QString()));
for (const auto &fs : std::as_const(fileSystems))
for (const auto &fs : qAsConst(fileSystems))
fs->init();
qDeleteAll(m_FileSystems);

View File

@ -37,8 +37,6 @@ public:
bool check(Report& report, const QString& deviceNode) const override;
bool create(Report& report, const QString& deviceNode) override;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetLabel() const override {
return m_GetLabel;

View File

@ -41,8 +41,6 @@ public:
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;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -122,6 +122,12 @@ bool linuxswap::writeLabel(Report& report, const QString& deviceNode, const QStr
return cmd.run(-1) && cmd.exitCode() == 0;
}
bool linuxswap::writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel)
{
Q_UNUSED(mountPoint)
return writeLabel(report, deviceNode, newLabel);
}
QString linuxswap::mountTitle() const
{
return xi18nc("@title:menu", "Activate swap");

View File

@ -40,6 +40,7 @@ public:
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;
@ -75,6 +76,9 @@ public:
CommandSupportType supportSetLabel() const override {
return m_SetLabel;
}
CommandSupportType supportSetLabelOnline() const override {
return m_SetLabel;
}
CommandSupportType supportUpdateUUID() const override {
return m_UpdateUUID;
}

View File

@ -46,7 +46,7 @@ lvm2_pv::lvm2_pv(qint64 firstsector, qint64 lastsector,
void lvm2_pv::init()
{
CommandSupportType lvmFound = findExternal(QStringLiteral("lvm"), {}, 3) ? cmdSupportFileSystem : cmdSupportNone;
CommandSupportType lvmFound = findExternal(QStringLiteral("lvm")) ? cmdSupportFileSystem : cmdSupportNone;
m_Create = lvmFound;
m_Check = lvmFound;

View File

@ -31,10 +31,7 @@ public:
bool check(Report& report, const QString&deviceNode) const override;
bool create(Report& report, const QString&deviceNode) override;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetLabel() const override {
return m_GetLabel;
}

View File

@ -41,8 +41,6 @@ public:
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 posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -47,8 +47,7 @@ ntfs::ntfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QStr
void ntfs::init()
{
m_Shrink = m_Grow = m_Check = findExternal(QStringLiteral("ntfsresize")) ? cmdSupportFileSystem : cmdSupportNone;
m_GetUsed = findExternal(QStringLiteral("ntfsinfo")) ? cmdSupportFileSystem : cmdSupportNone;
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;
@ -98,27 +97,18 @@ int ntfs::maxLabelLength() const
qint64 ntfs::readUsedCapacity(const QString& deviceNode) const
{
ExternalCommand cmd(QStringLiteral("ntfsinfo"), { QStringLiteral("--mft"), QStringLiteral("--force"), deviceNode });
ExternalCommand cmd(QStringLiteral("ntfsresize"), { QStringLiteral("--info"), QStringLiteral("--force"), QStringLiteral("--no-progress-bar"), deviceNode });
if (cmd.run(-1) && cmd.exitCode() == 0) {
QRegularExpression re(QStringLiteral("Cluster Size: (\\d+)"));
QRegularExpressionMatch reClusterSize = re.match(cmd.output());
qint64 clusterSize = reClusterSize.hasMatch() ? reClusterSize.captured(1).toLongLong() : -1;
QRegularExpression re2(QStringLiteral("Free Clusters: (\\d+)"));
QRegularExpressionMatch reFreeClusters = re2.match(cmd.output());
qint64 freeClusters = reFreeClusters.hasMatch() ? reFreeClusters.captured(1).toLongLong() : -1;
QRegularExpression re3(QStringLiteral("Volume Size in Clusters: (\\d+)"));
QRegularExpressionMatch reVolumeSize = re3.match(cmd.output());
qint64 volumeSize = reVolumeSize.hasMatch() ? reVolumeSize.captured(1).toLongLong() : -1;
qint64 usedBytes = -1;
qDebug () << volumeSize << freeClusters << clusterSize;
if (clusterSize > -1 && freeClusters > -1 && volumeSize > -1) {
usedBytes = (volumeSize - freeClusters) * clusterSize;
}
return usedBytes;
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;

View File

@ -40,8 +40,6 @@ public:
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;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -38,8 +38,6 @@ public:
qint64 readUsedCapacity(const QString& deviceNode) const override;
bool check(Report& report, const QString& deviceNode) const override;
bool create(Report& report, const QString& deviceNode) override;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -44,8 +44,6 @@ public:
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 posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -38,8 +38,6 @@ public:
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;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -13,7 +13,6 @@ namespace FS
{
FileSystem::CommandSupportType unknown::m_Move = FileSystem::cmdSupportCore;
FileSystem::CommandSupportType unknown::m_Copy = FileSystem::cmdSupportCore;
unknown::unknown(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Unknown)

View File

@ -37,12 +37,7 @@ public:
return m_Move;
}
CommandSupportType supportCopy() const override {
return m_Copy;
}
static CommandSupportType m_Move;
static CommandSupportType m_Copy;
};
}

View File

@ -41,8 +41,6 @@ public:
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;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -77,6 +77,13 @@ 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)

View File

@ -35,9 +35,8 @@ public:
public:
void init() override;
bool remove(Report& report, const QString& deviceNode) const override;
bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override;
QString posixPermissions() const override { return implPosixPermissions(); };
void setPosixPermissions(const QString& permissions) override { implSetPosixPermissions(permissions); };
CommandSupportType supportGetUsed() const override {
return m_GetUsed;

View File

@ -33,7 +33,7 @@ class LIBKPMCORE_EXPORT PartWidgetBase : public QWidget
protected:
PartWidgetBase(QWidget* parent) : QWidget(parent) {}
~PartWidgetBase() override {}
virtual ~PartWidgetBase() {}
public:
virtual qint32 borderWidth() const {

View File

@ -31,7 +31,6 @@ set(JOBS_SRC
jobs/setpartflagsjob.cpp
jobs/copyfilesystemjob.cpp
jobs/movefilesystemjob.cpp
jobs/changepermissionsjob.cpp
)
set(JOBS_LIB_HDRS

View File

@ -1,44 +0,0 @@
/*
SPDX-FileCopyrightText: Tomaz Canabrava <tcanabrava@kde.org>
SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "jobs/changepermissionsjob.h"
#include "core/lvmdevice.h"
#include "core/partition.h"
#include "util/report.h"
#include <KLocalizedString>
/** Creates a new CreateVolumeGroupJob
* @param permission the new permission for the partition, in chmod style.
* @param partition the partition to change the permission.
*/
ChangePermissionJob::ChangePermissionJob(Partition& partition) :
Job(),
m_Partition(partition)
{
}
bool ChangePermissionJob::run(Report& parent)
{
bool rval = false;
auto &fs = m_Partition.fileSystem();
Report* report = jobStarted(parent);
rval = fs.execChangePosixPermission(*report, m_Partition.deviceNode());
jobFinished(*report, rval);
return rval;
}
QString ChangePermissionJob::description() const
{
return xi18nc("@info/plain", "Change the permissions of: <filename>%1</filename> to %2", m_Partition.deviceNode(), m_permissions);
}

View File

@ -1,43 +0,0 @@
/*
SPDX-FileCopyrightText: 2021 Tomaz Canabrava <tcanabrava@kde.org>
SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef KPMCORE_CHANGEPERMISSIONJOB_H
#define KPMCORE_CHANGEPERMISSIONJOB_H
#include "jobs/job.h"
class Partition;
class Report;
class QString;
/** Check a FileSystem.
@author Volker Lanz <vl@fidra.de>
*/
class ChangePermissionJob : public Job
{
public:
/* Permission should be set in the partition. */
explicit ChangePermissionJob(Partition& p);
public:
bool run(Report& parent) override;
QString description() const override;
protected:
Partition& partition() {
return m_Partition;
}
const Partition& partition() const {
return m_Partition;
}
private:
Partition& m_Partition;
QString m_permissions;
};
#endif

View File

@ -49,7 +49,7 @@ protected:
Job();
public:
~Job() override {}
virtual ~Job() {}
Q_SIGNALS:
void started();

View File

@ -13,7 +13,6 @@
#include "jobs/deletefilesystemjob.h"
#include "jobs/createfilesystemjob.h"
#include "jobs/checkfilesystemjob.h"
#include "jobs/changepermissionsjob.h"
#include "fs/filesystem.h"
#include "fs/filesystemfactory.h"
@ -43,10 +42,6 @@ CreateFileSystemOperation::CreateFileSystemOperation(Device& d, Partition& p, Fi
addJob(deleteJob());
addJob(createJob());
addJob(checkJob());
// if the user never configured a new permission, nothing will run, if he did,
// then we change the permissions on the newly created partition.
addJob(new ChangePermissionJob(p));
}
CreateFileSystemOperation::~CreateFileSystemOperation()

View File

@ -21,7 +21,6 @@
#include "jobs/setfilesystemlabeljob.h"
#include "jobs/setpartflagsjob.h"
#include "jobs/checkfilesystemjob.h"
#include "jobs/changepermissionsjob.h"
#include "fs/filesystem.h"
#include "fs/filesystemfactory.h"
@ -32,56 +31,37 @@
#include <KLocalizedString>
struct NewOperationPrivate
{
NewOperationPrivate(Device& d, Partition* p) :
m_TargetDevice(d),
m_NewPartition(p),
m_CreatePartitionJob(new CreatePartitionJob(d, *p)),
m_SetPartitionLabelJob(nullptr),
m_SetPartitionUUIDJob(nullptr),
m_SetPartitionAttributesJob(nullptr),
m_CreateFileSystemJob(nullptr),
m_SetPartFlagsJob(nullptr),
m_SetFileSystemLabelJob(nullptr),
m_CheckFileSystemJob(nullptr)
{
}
Device& m_TargetDevice;
Partition* m_NewPartition;
CreatePartitionJob* m_CreatePartitionJob;
SetPartitionLabelJob* m_SetPartitionLabelJob;
SetPartitionUUIDJob* m_SetPartitionUUIDJob;
SetPartitionAttributesJob* m_SetPartitionAttributesJob;
CreateFileSystemJob* m_CreateFileSystemJob;
SetPartFlagsJob* m_SetPartFlagsJob;
SetFileSystemLabelJob* m_SetFileSystemLabelJob;
CheckFileSystemJob* m_CheckFileSystemJob;
};
/** Creates a new NewOperation.
@param d the Device to create a new Partition on
@param p pointer to the new Partition to create. May not be nullptr.
*/
NewOperation::NewOperation(Device& d, Partition* p) :
Operation(),
d_ptr(std::make_unique<NewOperationPrivate>(d, p))
m_TargetDevice(d),
m_NewPartition(p),
m_CreatePartitionJob(new CreatePartitionJob(targetDevice(), newPartition())),
m_SetPartitionLabelJob(nullptr),
m_SetPartitionUUIDJob(nullptr),
m_SetPartitionAttributesJob(nullptr),
m_CreateFileSystemJob(nullptr),
m_SetPartFlagsJob(nullptr),
m_SetFileSystemLabelJob(nullptr),
m_CheckFileSystemJob(nullptr)
{
addJob(createPartitionJob());
if (!p->label().isEmpty()) {
d_ptr->m_SetPartitionLabelJob = new SetPartitionLabelJob(targetDevice(), newPartition(), p->label());
m_SetPartitionLabelJob = new SetPartitionLabelJob(targetDevice(), newPartition(), p->label());
addJob(setPartitionLabelJob());
}
if (!p->uuid().isEmpty()) {
d_ptr->m_SetPartitionUUIDJob = new SetPartitionUUIDJob(targetDevice(), newPartition(), p->uuid());
m_SetPartitionUUIDJob = new SetPartitionUUIDJob(targetDevice(), newPartition(), p->uuid());
addJob(setPartitionUUIDJob());
}
if (p->attributes()) {
d_ptr->m_SetPartitionAttributesJob = new SetPartitionAttributesJob(targetDevice(), newPartition(), p->attributes());
m_SetPartitionAttributesJob = new SetPartitionAttributesJob(targetDevice(), newPartition(), p->attributes());
addJob(setPartitionAttributesJob());
}
@ -94,90 +74,26 @@ NewOperation::NewOperation(Device& d, Partition* p) :
// label. The operation stack will merge these operations with this one here
// and if the jobs don't exist things will break.
d_ptr->m_CreateFileSystemJob = new CreateFileSystemJob(targetDevice(), newPartition(), fs.label());
m_CreateFileSystemJob = new CreateFileSystemJob(targetDevice(), newPartition(), fs.label());
addJob(createFileSystemJob());
if (fs.type() == FileSystem::Type::Lvm2_PV) {
d_ptr->m_SetPartFlagsJob = new SetPartFlagsJob(targetDevice(), newPartition(), PartitionTable::Flag::Lvm);
m_SetPartFlagsJob = new SetPartFlagsJob(targetDevice(), newPartition(), PartitionTable::Flag::Lvm);
addJob(setPartFlagsJob());
}
d_ptr->m_SetFileSystemLabelJob = new SetFileSystemLabelJob(newPartition(), fs.label());
m_SetFileSystemLabelJob = new SetFileSystemLabelJob(newPartition(), fs.label());
addJob(setLabelJob());
d_ptr->m_CheckFileSystemJob = new CheckFileSystemJob(newPartition());
m_CheckFileSystemJob = new CheckFileSystemJob(newPartition());
addJob(checkJob());
// if the user never configured a new permission, nothing will run, if he did,
// then we change the permissions on the newly created partition.
addJob(new ChangePermissionJob(newPartition()));
}
}
NewOperation::~NewOperation()
{
if (status() == StatusPending)
delete d_ptr->m_NewPartition;
}
Partition& NewOperation::newPartition()
{
return *d_ptr->m_NewPartition;
}
const Partition& NewOperation::newPartition() const
{
return *d_ptr->m_NewPartition;
}
Device& NewOperation::targetDevice()
{
return d_ptr->m_TargetDevice;
}
const Device& NewOperation::targetDevice() const
{
return d_ptr->m_TargetDevice;
}
CreatePartitionJob* NewOperation::createPartitionJob()
{
return d_ptr->m_CreatePartitionJob;
}
SetPartitionLabelJob* NewOperation::setPartitionLabelJob()
{
return d_ptr->m_SetPartitionLabelJob;
}
SetPartitionUUIDJob* NewOperation::setPartitionUUIDJob()
{
return d_ptr->m_SetPartitionUUIDJob;
}
SetPartitionAttributesJob* NewOperation::setPartitionAttributesJob()
{
return d_ptr->m_SetPartitionAttributesJob;
}
CreateFileSystemJob* NewOperation::createFileSystemJob()
{
return d_ptr->m_CreateFileSystemJob;
}
SetPartFlagsJob* NewOperation::setPartFlagsJob()
{
return d_ptr->m_SetPartFlagsJob;
}
SetFileSystemLabelJob* NewOperation::setLabelJob()
{
return d_ptr->m_SetFileSystemLabelJob;
}
CheckFileSystemJob* NewOperation::checkJob()
{
return d_ptr->m_CheckFileSystemJob;
delete m_NewPartition;
}
bool NewOperation::targets(const Device& d) const
@ -226,7 +142,6 @@ Partition* NewOperation::createNew(const Partition& cloneFrom,
p->sectorSize()));
p->setState(Partition::State::New);
p->setPartitionPath(QString());
p->setAttributes(0);
return p;
}

View File

@ -17,7 +17,6 @@
#include <QString>
struct NewOperationPrivate;
class Device;
class OperationStack;
@ -61,23 +60,56 @@ public:
static Partition* createNew(const Partition& cloneFrom, FileSystem::Type type);
protected:
Partition& newPartition();
const Partition& newPartition() const;
Partition& newPartition() {
return *m_NewPartition;
}
const Partition& newPartition() const {
return *m_NewPartition;
}
Device& targetDevice();
const Device& targetDevice() const;
Device& targetDevice() {
return m_TargetDevice;
}
const Device& targetDevice() const {
return m_TargetDevice;
}
CreatePartitionJob* createPartitionJob();
SetPartitionLabelJob* setPartitionLabelJob();
SetPartitionUUIDJob* setPartitionUUIDJob();
SetPartitionAttributesJob* setPartitionAttributesJob();
CreateFileSystemJob* createFileSystemJob();
SetPartFlagsJob* setPartFlagsJob();
SetFileSystemLabelJob* setLabelJob();
CheckFileSystemJob* checkJob();
CreatePartitionJob* createPartitionJob() {
return m_CreatePartitionJob;
}
SetPartitionLabelJob* setPartitionLabelJob() {
return m_SetPartitionLabelJob;
}
SetPartitionUUIDJob* setPartitionUUIDJob() {
return m_SetPartitionUUIDJob;
}
SetPartitionAttributesJob* setPartitionAttributesJob() {
return m_SetPartitionAttributesJob;
}
CreateFileSystemJob* createFileSystemJob() {
return m_CreateFileSystemJob;
}
SetPartFlagsJob* setPartFlagsJob() {
return m_SetPartFlagsJob;
}
SetFileSystemLabelJob* setLabelJob() {
return m_SetFileSystemLabelJob;
}
CheckFileSystemJob* checkJob() {
return m_CheckFileSystemJob;
}
private:
std::unique_ptr<NewOperationPrivate> d_ptr;
Device& m_TargetDevice;
Partition* m_NewPartition;
CreatePartitionJob* m_CreatePartitionJob;
SetPartitionLabelJob* m_SetPartitionLabelJob;
SetPartitionUUIDJob* m_SetPartitionUUIDJob;
SetPartitionAttributesJob* m_SetPartitionAttributesJob;
CreateFileSystemJob* m_CreateFileSystemJob;
SetPartFlagsJob* m_SetPartFlagsJob;
SetFileSystemLabelJob* m_SetFileSystemLabelJob;
CheckFileSystemJob* m_CheckFileSystemJob;
};
#endif

View File

@ -85,7 +85,7 @@ public:
protected:
Operation();
~Operation() override;
virtual ~Operation();
Q_SIGNALS:
void progress(int);

View File

@ -1,6 +1,6 @@
/*
SPDX-FileCopyrightText: 2016 Chantara Tith <tith.chantara@gmail.com>
SPDX-FileCopyrightText: 2016-2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2016-2018 Andrius Štikonas <andrius@stikonas.eu>
SPDX-License-Identifier: GPL-3.0-or-later
*/
@ -14,8 +14,6 @@
#include "jobs/movephysicalvolumejob.h"
#include "util/helpers.h"
#include <utility>
#include <QString>
#include <KLocalizedString>
@ -57,20 +55,20 @@ ResizeVolumeGroupOperation::ResizeVolumeGroupOperation(LvmDevice& d, const QVect
currentFreePE += lvm2PVFs->freePE();
}
qint64 removedFreePE = 0;
for (const auto &p : std::as_const(toRemoveList)) {
for (const auto &p : qAsConst(toRemoveList)) {
FS::lvm2_pv *lvm2PVFs;
innerFS(p, lvm2PVFs);
removedFreePE += lvm2PVFs->freePE();
}
qint64 freePE = currentFreePE - removedFreePE;
qint64 movePE = 0;
for (const auto &p : std::as_const(toRemoveList)) {
for (const auto &p : qAsConst(toRemoveList)) {
FS::lvm2_pv *lvm2PVFs;
innerFS(p, lvm2PVFs);
movePE += lvm2PVFs->allocatedPE();
}
qint64 growPE = 0;
for (const auto &p : std::as_const(toInsertList)) {
for (const auto &p : qAsConst(toInsertList)) {
growPE += p->capacity() / device().peSize();
}

View File

@ -3,11 +3,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
function(kpmcore_add_plugin name)
kcoreaddons_add_plugin(${name} INSTALL_NAMESPACE "kpmcore")
endfunction()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
option(PARTMAN_SFDISKBACKEND "Build the sfdisk backend plugin." ON)

View File

@ -1,15 +1,17 @@
# SPDX-FileCopyrightText: 2010 Volker Lanz <vl@fidra.de>
# SPDX-FileCopyrightText: 2016-2021 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2016-2018 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-License-Identifier: GPL-3.0-or-later
kpmcore_add_plugin(pmdummybackendplugin)
target_sources(pmdummybackendplugin PRIVATE
set (pmdummybackendplugin_SRCS
dummybackend.cpp
dummydevice.cpp
dummypartitiontable.cpp
${CMAKE_SOURCE_DIR}/src/backend/corebackenddevice.cpp
)
add_library(pmdummybackendplugin SHARED ${pmdummybackendplugin_SRCS})
target_link_libraries(pmdummybackendplugin kpmcore KF5::I18n KF5::CoreAddons)
install(TARGETS pmdummybackendplugin DESTINATION ${KDE_INSTALL_PLUGINDIR})

View File

@ -25,7 +25,7 @@
#include <KLocalizedString>
#include <KPluginFactory>
K_PLUGIN_CLASS_WITH_JSON(DummyBackend, "pmdummybackendplugin.json")
K_PLUGIN_FACTORY_WITH_JSON(DummyBackendFactory, "pmdummybackendplugin.json", registerPlugin<DummyBackend>();)
DummyBackend::DummyBackend(QObject*, const QList<QVariant>&) :
@ -51,7 +51,7 @@ QList<Device*> DummyBackend::scanDevices(const ScanFlags scanFlags)
emitScanProgress(QStringLiteral("/dev/sda"), 100);
return result;
return scanDevices(false);
}
Device* DummyBackend::scanDevice(const QString& deviceNode)

View File

@ -24,9 +24,11 @@ class QString;
*/
class DummyBackend : public CoreBackend
{
friend class KPluginFactory;
Q_DISABLE_COPY(DummyBackend)
public:
private:
DummyBackend(QObject* parent, const QList<QVariant>& args);
public:

View File

@ -18,7 +18,6 @@
"Name[fi]": "Volker Lanz",
"Name[fr]": "Volker Lanz",
"Name[gl]": "Volker Lanz",
"Name[hu]": "Volker Lanz",
"Name[id]": "Volker Lanz",
"Name[it]": "Volker Lanz",
"Name[ko]": "Volker Lanz",
@ -40,7 +39,7 @@
],
"Category": "BackendPlugin",
"Description": "A KDE Partition Manager dummy backend for testing purposes.",
"Description[ca@valencia]": "Un dorsal fals per al gestor de particions de KDE amb la finalitat de fer proves.",
"Description[ca@valencia]": "Un dorsal fals per al gestor de particions del KDE amb la finalitat de fer proves.",
"Description[ca]": "Un dorsal fals per al gestor de particions del KDE amb la finalitat de fer proves.",
"Description[cs]": "Falešná podpůrná vrstva pro správce diskových oddílů KDE pro testovací účely.",
"Description[da]": "En KDE-partitionshåndtering med attrap-backend til testformål.",
@ -53,7 +52,6 @@
"Description[fi]": "KDE:n osionhallinnan valetaustaosa testaustarkoituksiin.",
"Description[fr]": "Un moteur de test pour le gestionnaire de partitions de KDE pour faire des essais.",
"Description[gl]": "Unha infraestrutura de probas para o xestor de particións de KDE.",
"Description[hu]": "KDE partíciókezelő üres modul tesztelési célokra.",
"Description[id]": "Sebuah backend dumi Pengelola Partisi KDE untuk tujuan pengujian.",
"Description[it]": "Un motore fittizio del gestore delle partizioni di KDE per scopi di prova.",
"Description[ko]": "테스트용 KDE 파티션 관리자 더미 백엔드입니다.",
@ -68,15 +66,15 @@
"Description[sv]": "Ett bakgrundsprogram till KDE:s partitionshanterare i testsyfte.",
"Description[uk]": "Тестовий додаток сервера Керування розділами KDE.",
"Description[x-test]": "xxA KDE Partition Manager dummy backend for testing purposes.xx",
"Description[zh_CN]": "用于测试的 KDE 分区管理器虚拟后端程序。",
"Description[zh_CN]": "测试的 KDE 分区管理器虚拟后端",
"Description[zh_TW]": "使用虛設後端的 KDE 磁碟分割區管理員,可用來測試。",
"EnabledByDefault": true,
"Icon": "preferences-plugin",
"Id": "pmdummybackendplugin",
"License": "GPL",
"Name": "KDE Partition Manager Dummy Backend",
"Name[ca@valencia]": "Dorsal fals del gestor de particions de KDE",
"Name[ca]": "Dorsal fals del gestor de particions del KDE",
"Name[ca@valencia]": "Dorsal fals per al gestor de particions del KDE",
"Name[ca]": "Dorsal fals per al gestor de particions del KDE",
"Name[cs]": "Podpůrná vrstva pro správce diskových oddílů pro KDE",
"Name[da]": "KDE-partitionshåndtering med attrap-backend",
"Name[de]": "KDE-Partitionsverwaltung Dummy-Backend",
@ -88,7 +86,6 @@
"Name[fi]": "KDE:n osionhallinnan valetaustaosa",
"Name[fr]": "Moteur de test pour le gestionnaire de partitions de KDE",
"Name[gl]": "Infraestrutura de probas para o xestor de particións de KDE",
"Name[hu]": "KDE partíciókezelő üres modul",
"Name[id]": "Backend Dumi Pengelola Partisi KDE",
"Name[it]": "Motore fittizio del gestore delle partizioni di KDE",
"Name[ko]": "KDE 파티션 관리자 더미 백엔드",
@ -104,8 +101,11 @@
"Name[sv]": "KDE:s partitionshanterare bakgrundsprogram för test",
"Name[uk]": "Тестовий додаток сервера Керування розділами KDE",
"Name[x-test]": "xxKDE Partition Manager Dummy Backendxx",
"Name[zh_CN]": "KDE 分区管理器虚拟后端程序",
"Name[zh_CN]": "KDE 分区管理器虚拟后端",
"Name[zh_TW]": "KDE 磁碟分割區管理員 (虛設後端)",
"ServiceTypes": [
"PartitionManager/Plugin"
],
"Version": "1",
"Website": "http://www.partitionmanager.org"
}

View File

@ -1,11 +1,9 @@
# SPDX-FileCopyrightText: 2020 Gaël PORTAY <gael.portay@collabora.com>
# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2018 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-License-Identifier: GPL-3.0-or-later
kpmcore_add_plugin(pmsfdiskbackendplugin)
target_sources(pmsfdiskbackendplugin PRIVATE
set (pmsfdiskbackendplugin_SRCS
sfdiskbackend.cpp
sfdiskdevice.cpp
sfdiskgptattributes.cpp
@ -16,4 +14,8 @@ target_sources(pmsfdiskbackendplugin PRIVATE
${CMAKE_SOURCE_DIR}/src/core/copytargetbytearray.cpp
)
add_library(pmsfdiskbackendplugin SHARED ${pmsfdiskbackendplugin_SRCS})
target_link_libraries(pmsfdiskbackendplugin kpmcore KF5::I18n KF5::CoreAddons)
install(TARGETS pmsfdiskbackendplugin DESTINATION ${KDE_INSTALL_PLUGINDIR})

View File

@ -18,7 +18,6 @@
"Name[fi]": "Andrius Štikonas",
"Name[fr]": "Andrius Štikonas",
"Name[gl]": "Andrius Štikonas",
"Name[hu]": "Andrius Štikonas",
"Name[id]": "Andrius Štikonas",
"Name[it]": "Andrius Štikonas",
"Name[ko]": "Andrius Štikonas",
@ -40,7 +39,7 @@
],
"Category": "BackendPlugin",
"Description": "A KDE Partition Manager sfdisk backend.",
"Description[ca@valencia]": "Un dorsal «sfdisk» del gestor de particions de KDE.",
"Description[ca@valencia]": "Un dorsal «sfdisk» del gestor de particions del KDE.",
"Description[ca]": "Un dorsal «sfdisk» del gestor de particions del KDE.",
"Description[cs]": "Podpůrná vrstva sfdisk pro správce diskových oddílů pro KDE.",
"Description[da]": "En KDE-partitionshåndtering med sfdisk-backend.",
@ -53,7 +52,6 @@
"Description[fi]": "KDE:n osionhallinnan sfdisk-taustaosa",
"Description[fr]": "Moteur sfdisk pour le gestionnaire de partitions de KDE.",
"Description[gl]": "Unha infraestrutura de sfdisk para o xestor de particións de KDE.",
"Description[hu]": "KDE partíciókezelő sfdisk modul.",
"Description[id]": "Sebuah backend sfdisk Pengelola Partisi KDE",
"Description[it]": "Un motore sfdisk del gestore delle partizioni di KDE.",
"Description[ko]": "KDE 파티션 관리자 sfdisk 백엔드입니다.",
@ -68,14 +66,13 @@
"Description[sv]": "Ett sfdisk bakgrundsprogram till KDE:s partitionshanterare",
"Description[uk]": "Додаток sfdisk сервера Керування розділами KDE.",
"Description[x-test]": "xxA KDE Partition Manager sfdisk backend.xx",
"Description[zh_CN]": "KDE 分区管理器 sfdisk 后端程序。",
"Description[zh_TW]": "使用 sfdisk 作為後端的 KDE 磁碟分割區管理員。",
"EnabledByDefault": true,
"Icon": "preferences-plugin",
"Id": "pmsfdiskbackendplugin",
"License": "GPL",
"Name": "KDE Partition Manager sfdisk Backend",
"Name[ca@valencia]": "Dorsal «sfdisk» del gestor de particions de KDE",
"Name[ca@valencia]": "Dorsal «sfdisk» del gestor de particions del KDE",
"Name[ca]": "Dorsal «sfdisk» del gestor de particions del KDE",
"Name[cs]": "Podpůrná vrstva sfdisk pro správce diskových oddílů pro KDE",
"Name[da]": "KDE-partitionshåndtering med sfdisk-backend",
@ -88,7 +85,6 @@
"Name[fi]": "KDE:n osionhallinnan sfdisk-taustaosa",
"Name[fr]": "Moteur sfdisk pour le gestionnaire de partitions de KDE",
"Name[gl]": "Infraestrutura de sfdisk para o xestor de particións de KDE",
"Name[hu]": "KDE partíciókezelő sfdisk modul",
"Name[id]": "Backend sfdisk Pengelola Partisi KDE",
"Name[it]": "Motore sfdisk del gestore delle partizioni di KDE",
"Name[ko]": "KDE 파티션 관리자 sfdisk 백엔드",
@ -103,8 +99,10 @@
"Name[sv]": "KDE:s partitionshanterare sfdisk bakgrundsprogram",
"Name[uk]": "Додаток sfdisk сервера Керування розділами KDE",
"Name[x-test]": "xxKDE Partition Manager sfdisk Backendxx",
"Name[zh_CN]": "KDE 分区管理器 sfdisk 后端程序",
"Name[zh_TW]": "KDE 磁碟分割區管理員 (sfdisk 後端)",
"ServiceTypes": [
"PartitionManager/Plugin"
],
"Version": "1",
"Website": "http://www.partitionmanager.org"
}

View File

@ -31,8 +31,6 @@
#include "util/externalcommand.h"
#include "util/helpers.h"
#include <utility>
#include <QDataStream>
#include <QDebug>
#include <QFile>
@ -47,7 +45,7 @@
#include <KLocalizedString>
#include <KPluginFactory>
K_PLUGIN_CLASS_WITH_JSON(SfdiskBackend, "pmsfdiskbackendplugin.json")
K_PLUGIN_FACTORY_WITH_JSON(SfdiskBackendFactory, "pmsfdiskbackendplugin.json", registerPlugin<SfdiskBackend>();)
SfdiskBackend::SfdiskBackend(QObject*, const QList<QVariant>&) :
CoreBackend()
@ -280,7 +278,7 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode)
{
QList<Device *> availableDevices = scanDevices();
for (Device *device : std::as_const(availableDevices))
for (Device *device : qAsConst(availableDevices))
if (device->deviceNode() == deviceNode)
return device;
}
@ -342,7 +340,7 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit
if (d.partitionTable()->isSectorBased(d))
d.partitionTable()->setType(d, PartitionTable::msdos_sectorbased);
for (const Partition *part : std::as_const(partitions))
for (const Partition *part : qAsConst(partitions))
PartitionAlignment::isAligned(d, *part);
}
@ -451,12 +449,11 @@ bool SfdiskBackend::updateDevicePartitionTable(Device &d, const QJsonObject &jso
// Read the maximum number of GPT partitions
qint32 maxEntries;
QByteArray gptHeader;
qint64 sectorSize = d.logicalSize();
CopySourceDevice source(d, sectorSize, sectorSize * 2 - 1);
CopySourceDevice source(d, 512, 1023);
CopyTargetByteArray target(gptHeader);
ExternalCommand readCmd;
gptHeader = readCmd.readData(source);
if (gptHeader != QByteArray()) {
ExternalCommand copyCmd;
if (copyCmd.copyBlocks(source, target)) {
QByteArray gptMaxEntries = gptHeader.mid(80, 4);
QDataStream stream(&gptMaxEntries, QIODevice::ReadOnly);
stream.setByteOrder(QDataStream::LittleEndian);

View File

@ -27,9 +27,11 @@ class QString;
*/
class SfdiskBackend : public CoreBackend
{
friend class KPluginFactory;
Q_DISABLE_COPY(SfdiskBackend)
public:
private:
SfdiskBackend(QObject* parent, const QList<QVariant>& args);
public:

View File

@ -60,7 +60,7 @@ bool SfdiskDevice::createPartitionTable(Report& report, const PartitionTable& pt
else
tableType = ptable.typeName().toLocal8Bit();
ExternalCommand createCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--wipe=always"), m_device->deviceNode() } );
ExternalCommand createCommand(report, QStringLiteral("sfdisk"), { m_device->deviceNode() } );
if ( createCommand.write(QByteArrayLiteral("label: ") + tableType +
QByteArrayLiteral("\nwrite\n")) && createCommand.start(-1) ) {
return createCommand.output().contains(QStringLiteral("Script header accepted."));

View File

@ -20,7 +20,7 @@ class CoreBackendPartitionTable;
class SfdiskDevice : public CoreBackendDevice
{
Q_DISABLE_COPY(SfdiskDevice)
Q_DISABLE_COPY(SfdiskDevice);
public:
explicit SfdiskDevice(const Device& d);

View File

@ -8,7 +8,6 @@
#include <QString>
#include <QStringList>
#include <QStringView>
const static QString requiredPartition = QStringLiteral("RequiredPartition");
const static QString noBlockIoProtocol = QStringLiteral("NoBlockIOProtocol");
@ -26,7 +25,7 @@ quint64 SfdiskGptAttributes::toULongLong(const QStringList& attrs)
else if (attr.compare(legacyBiosBootable) == 0)
attributes |= 0x4ULL;
else if (attr.startsWith(guid))
attributes |= 1ULL << QStringView{ attr }.mid(guid.length(), attr.length() - guid.length()).toULongLong();
attributes |= 1ULL << QStringRef(&attr, guid.length(), attr.length() - guid.length()).toULongLong();
return attributes;
}

View File

@ -8,7 +8,8 @@
#define SFDISKGPTATTRIBUTES__H
#include <QtGlobal>
#include <QStringList>
class QStringList;
/** Sfdisk GPT Attributes helpers.
@author Gaël PORTAY <gael.portay@collabora.com>

View File

@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2008,2012 Volker Lanz <vl@fidra.de>
# SPDX-FileCopyrightText: 2015 Chris Campbell <c.j.campbell@ed.ac.uk>
# SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
# SPDX-FileCopyrightText: 2015-2020 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2015 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2018 Huzaifa Faruqui <huzaifafaruqui@gmail.com>
# SPDX-FileCopyrightText: 2019 Albert Astals Cid <aacid@kde.org>
# SPDX-FileCopyrightText: 2019 Antonio Rojas <arojas@archlinux.org>
@ -11,29 +11,19 @@
set(helper_interface_xml org.kde.kpmcore.helperinterface.xml)
file(READ "util/trustedprefixes" TRUSTED_PREFIXES)
string(REGEX REPLACE ";" "\\\\;" TRUSTED_PREFIXES "${TRUSTED_PREFIXES}")
string(REGEX REPLACE "\n" ";" TRUSTED_PREFIXES "${TRUSTED_PREFIXES}")
foreach(TRUSTED_PREFIX ${TRUSTED_PREFIXES})
list(APPEND TRUSTED_PREFIXES_LIST " QStringLiteral(\"${TRUSTED_PREFIX}\")")
endforeach()
string(REPLACE "; QStringLiteral(" ",\n QStringLiteral(" TRUSTED_PREFIXES_LIST "${TRUSTED_PREFIXES_LIST}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS util/trustedprefixes)
configure_file(util/externalcommand_trustedprefixes.h.in util/externalcommand_trustedprefixes.h)
qt_generate_dbus_interface(
qt5_generate_dbus_interface(
util/externalcommand.h
${application_interface_xml}
OPTIONS -a
)
qt_generate_dbus_interface(
qt5_generate_dbus_interface(
util/externalcommandhelper.h
${helper_interface_xml}
OPTIONS -a
)
qt_add_dbus_interface(HelperInterface_SRCS ${CMAKE_CURRENT_BINARY_DIR}/${helper_interface_xml} externalcommandhelper_interface)
qt5_add_dbus_interface(HelperInterface_SRCS ${CMAKE_CURRENT_BINARY_DIR}/${helper_interface_xml} externalcommandhelper_interface)
set(UTIL_SRC
${HelperInterface_SRCS}
@ -46,6 +36,7 @@ set(UTIL_SRC
)
set(UTIL_LIB_HDRS
util/libpartitionmanagerexport.h
util/capacity.h
util/externalcommand.h
util/globallog.h
@ -59,16 +50,16 @@ add_executable(kpmcore_externalcommand
)
target_link_libraries(kpmcore_externalcommand
Qt${QT_MAJOR_VERSION}::Core
Qt${QT_MAJOR_VERSION}::DBus
Qt5::Core
Qt5::DBus
KF5::I18n
PolkitQt${QT_MAJOR_VERSION}-1::Core
PolkitQt5-1::Core
)
install(TARGETS kpmcore_externalcommand DESTINATION ${KDE_INSTALL_LIBEXECDIR})
install( FILES util/org.kde.kpmcore.helperinterface.conf DESTINATION ${KDE_INSTALL_DBUSDIR}/system.d )
install( FILES util/org.kde.kpmcore.externalcommand.policy DESTINATION ${POLKITQT-1_POLICY_FILES_INSTALL_DIR})
kauth_install_actions(org.kde.kpmcore.externalcommand util/org.kde.kpmcore.externalcommand.actions)
ecm_install_configured_files(
INPUT util/org.kde.kpmcore.helperinterface.service.in
DESTINATION ${KDE_INSTALL_DBUSDIR}/system-services

View File

@ -160,7 +160,7 @@ bool ExternalCommand::copyBlocks(const CopySource& source, CopyTarget& target)
connect(interface, &OrgKdeKpmcoreExternalcommandInterface::progress, this, &ExternalCommand::progress);
connect(interface, &OrgKdeKpmcoreExternalcommandInterface::report, this, &ExternalCommand::reportSignal);
QDBusPendingCall pcall = interface->CopyFileData(source.path(), source.firstByte(), source.length(),
QDBusPendingCall pcall = interface->CopyBlocks(source.path(), source.firstByte(), source.length(),
target.path(), target.firstByte(), blockSize);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
@ -187,38 +187,6 @@ bool ExternalCommand::copyBlocks(const CopySource& source, CopyTarget& target)
return rval;
}
QByteArray ExternalCommand::readData(const CopySourceDevice& source)
{
auto interface = helperInterface();
if (!interface)
return {};
// Helper is restricted not to resolve symlinks
QFileInfo sourceInfo(source.path());
QDBusPendingCall pcall = interface->ReadData(sourceInfo.canonicalFilePath(), source.firstByte(), source.length());
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
QEventLoop loop;
QByteArray target;
auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) {
loop.exit();
if (watcher->isError())
qWarning() << watcher->error();
else {
QDBusPendingReply<QByteArray> reply = *watcher;
target = reply.value();
}
};
connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop);
loop.exec();
return target;
}
bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte)
{
d->m_Report = commandReport.newChild();
@ -233,13 +201,13 @@ bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer,
return waitForDbusReply(pcall);
}
bool ExternalCommand::writeFstab(const QByteArray& fileContents)
bool ExternalCommand::createFile(const QByteArray& fileContents, const QString& filePath)
{
auto interface = helperInterface();
if (!interface)
return false;
QDBusPendingCall pcall = interface->WriteFstab(fileContents);
QDBusPendingCall pcall = interface->CreateFile(filePath, fileContents);
return waitForDbusReply(pcall);
}

View File

@ -27,7 +27,6 @@
class KJob;
class Report;
class CopySource;
class CopySourceDevice;
class CopyTarget;
class QDBusInterface;
class QDBusPendingCall;
@ -51,13 +50,12 @@ 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() override;
~ExternalCommand();
public:
bool copyBlocks(const CopySource& source, CopyTarget& target);
QByteArray readData(const CopySourceDevice& source);
bool writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte); // same as copyBlocks but from QByteArray
bool writeFstab(const QByteArray& fileContents);
bool createFile(const QByteArray& filePath, const QString& fileContents); // similar to writeData but creates a new file
/**< @param cmd the command to run */
void setCommand(const QString& cmd);
@ -74,6 +72,7 @@ public:
bool write(const QByteArray& input); /**< @param input the input for the program */
bool startCopyBlocks();
bool start(int timeout = 30000);
bool run(int timeout = 30000);

View File

@ -1,8 +0,0 @@
/*
SPDX-FileCopyrightText: 2022 Andrius Štikonas <andrius@stikonas.eu>
SPDX-License-Identifier: GPL-3.0-or-later
*/
const std::unordered_set<QString> trustedPrefixes {
@TRUSTED_PREFIXES_LIST@
};

View File

@ -8,10 +8,7 @@
#ifndef KPMCORE_EXTERNALCOMMAND_WHITELIST_H
#define KPMCORE_EXTERNALCOMMAND_WHITELIST_H
#include <unordered_set>
#include "util/externalcommand_trustedprefixes.h"
const std::unordered_set<QString> allowedCommands {
QString allowedCommands[] = {
// TODO no root needed
QStringLiteral("lsblk"),
QStringLiteral("udevadm"),
@ -19,7 +16,6 @@ QStringLiteral("udevadm"),
//Core programs
QStringLiteral("blockdev"),
QStringLiteral("blkid"),
QStringLiteral("chmod"),
QStringLiteral("partx"),
QStringLiteral("sfdisk"),
QStringLiteral("wipefs"),
@ -33,11 +29,9 @@ QStringLiteral("smartctl"),
QStringLiteral("btrfs"),
QStringLiteral("mkfs.btrfs"),
QStringLiteral("btrfstune"),
QStringLiteral("fsck.exfat"),
QStringLiteral("mkexfatfs"),
QStringLiteral("exfatfsck"),
QStringLiteral("mkfs.exfat"),
QStringLiteral("exfatlabel"),
QStringLiteral("tune.exfat"),
QStringLiteral("dumpe2fs"),
QStringLiteral("e2fsck"),
QStringLiteral("mkfs.ext2"),
@ -76,7 +70,6 @@ QStringLiteral("nilfs-resize"),
QStringLiteral("ntfsresize"),
QStringLiteral("mkfs.ntfs"),
QStringLiteral("ntfsclone"),
QStringLiteral("ntfsinfo"),
QStringLiteral("ntfslabel"),
QStringLiteral("fsck.ocfs2"),
QStringLiteral("mkfs.ocfs2"),

View File

@ -1,5 +1,5 @@
/*
SPDX-FileCopyrightText: 2017-2022 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2017-2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2018 Huzaifa Faruqui <huzaifafaruqui@gmail.com>
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
SPDX-FileCopyrightText: 2018-2019 Harald Sitter <sitter@kde.org>
@ -13,16 +13,12 @@
#include "externalcommandhelper.h"
#include "externalcommand_whitelist.h"
#include <filesystem>
#include <QtDBus>
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QElapsedTimer>
#include <QFile>
#include <QFileInfo>
#include <QString>
#include <QVariant>
@ -46,11 +42,11 @@
ExternalCommandHelper::ExternalCommandHelper()
{
if (!QDBusConnection::systemBus().registerObject(QStringLiteral("/Helper"), this, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals)) {
exit(-1);
::exit(-1);
}
if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.helperinterface"))) {
exit(-1);
::exit(-1);
}
// we know this service must be registered already as DBus policy blocks calls from anyone else
@ -73,85 +69,83 @@ ExternalCommandHelper::ExternalCommandHelper()
@param size the number of bytes to read
@return true on success
*/
bool ExternalCommandHelper::readData(QFile& device, QByteArray& buffer, const qint64 offset, const qint64 size)
bool ExternalCommandHelper::readData(const QString& sourceDevice, QByteArray& buffer, const qint64 offset, const qint64 size)
{
if (!device.isOpen()) {
if (!device.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) {
qCritical() << xi18n("Could not open device <filename>%1</filename> for reading.", device.fileName());
return false;
}
QFile device(sourceDevice);
if (!device.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) {
qCritical() << xi18n("Could not open device <filename>%1</filename> for reading.", sourceDevice);
return false;
}
// Sequential devices such as /dev/zero or /dev/urandom return false on seek().
if (!device.isSequential() && !device.seek(offset)) {
qCritical() << xi18n("Could not seek position %1 on device <filename>%2</filename>.", offset, device.fileName());
if (!device.seek(offset)) {
qCritical() << xi18n("Could not seek position %1 on device <filename>%2</filename>.", offset, sourceDevice);
return false;
}
buffer = device.read(size);
if (size != buffer.size()) {
qCritical() << xi18n("Could not read from device <filename>%1</filename>.", device.fileName());
return false;
qCritical() << xi18n("Could not read from device <filename>%1</filename>.", sourceDevice);
return false;
}
return true;
}
/** Writes the data from buffer to a given device.
@param device device or file to write to
@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(QFile& device, const QByteArray& buffer, const qint64 offset)
bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteArray& buffer, const qint64 offset)
{
auto flags = QIODevice::WriteOnly | QIODevice::Unbuffered;
if (!device.isOpen()) {
if (!device.open(flags)) {
qCritical() << xi18n("Could not open device <filename>%1</filename> for writing.", device.fileName());
return false;
}
QFile device(targetDevice);
auto flags = QIODevice::WriteOnly | QIODevice::Unbuffered | QIODevice::Append;
if (!device.open(flags)) {
qCritical() << xi18n("Could not open device <filename>%1</filename> for writing.", targetDevice);
return false;
}
if (!device.seek(offset)) {
qCritical() << xi18n("Could not seek position %1 on device <filename>%2</filename>.", offset, device.fileName());
qCritical() << xi18n("Could not seek position %1 on device <filename>%2</filename>.", offset, targetDevice);
return false;
}
if (device.write(buffer) != buffer.size()) {
qCritical() << xi18n("Could not write to device <filename>%1</filename>.", device.fileName());
qCritical() << xi18n("Could not write to device <filename>%1</filename>.", targetDevice);
return false;
}
return true;
}
/** Creates a new fstab file with given contents.
@param Contents the data that we write
/** Creates a new file with given contents.
@param filePath file to write to
@param fileContents the data that we write
@return true on success
*/
bool ExternalCommandHelper::WriteFstab(const QByteArray& fstabContents)
bool ExternalCommandHelper::CreateFile(const QString &filePath, const QByteArray& fileContents)
{
if (!isCallerAuthorized()) {
return false;
}
if (fstabContents.size() > MiB) {
qCritical() << QStringLiteral("/etc/fstab size limit exceeded.");
// Do not allow using this helper for writing to arbitrary location
if ( !filePath.contains(QStringLiteral("/etc/fstab")) )
return false;
}
QString fstabPath = QStringLiteral("/etc/fstab");
QFile fstabFile(fstabPath);
// WriteOnly implies O_TRUNC
QFile device(filePath);
auto flags = QIODevice::WriteOnly | QIODevice::Unbuffered;
if (!fstabFile.open(flags)) {
qCritical() << xi18n("Could not open file <filename>%1</filename> for writing.", fstabPath);
if (!device.open(flags)) {
qCritical() << xi18n("Could not open file <filename>%1</filename> for writing.", filePath);
return false;
}
if (fstabFile.write(fstabContents) != fstabContents.size()) {
qCritical() << xi18n("Could not write to file <filename>%1</filename>.", fstabPath);
if (device.write(fileContents) != fileContents.size()) {
qCritical() << xi18n("Could not write to file <filename>%1</filename>.", filePath);
return false;
}
@ -159,72 +153,29 @@ bool ExternalCommandHelper::WriteFstab(const QByteArray& fstabContents)
}
// If targetDevice is empty then return QByteArray with data that was read from disk.
QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, const qint64 sourceOffset, const qint64 sourceLength, const QString& targetDevice, const qint64 targetOffset, const qint64 chunkSize)
QVariantMap ExternalCommandHelper::CopyBlocks(const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize)
{
if (!isCallerAuthorized()) {
return {};
return QVariantMap();
}
// Avoid division by zero further down
if (!chunkSize) {
return {};
}
// Prevent some out of memory situations
if (chunkSize > 100 * MiB) {
return {};
}
// Check for relative paths
std::filesystem::path sourcePath(sourceDevice.toStdU16String());
std::filesystem::path targetPath(targetDevice.toStdU16String());
if(sourcePath.is_relative() || targetPath.is_relative()) {
return {};
}
// Only allow writing to existing files.
if(!std::filesystem::exists(targetPath)) {
return {};
}
QVariantMap reply;
reply[QStringLiteral("success")] = true;
// This enum specified whether individual data chunks are moved left or right
// When source and target devices are the same we have to be careful not to overwrite
// source data with newly written data. We don't have to do this if sourceDevice is not
// targetDevice but there are no disadvantages in applying the same scheme.
// When partition is moved to the left, we start with the leftmost chunk,
// and move it further left, then second leftmost chunk and so on.
// But when we move partition to the right, we start with rightmost chunk.
// To account for this difference, we introduce CopyDirection variable which takes
// care of some of the differences in offset calculation between these two cases.
enum CopyDirection : qint8 {
Left = 1,
Right = -1,
};
qint8 copyDirection = targetOffset > sourceOffset ? CopyDirection::Right : CopyDirection::Left;
const qint64 blocksToCopy = sourceLength / blockSize;
qint64 readOffset = sourceFirstByte;
qint64 writeOffset = targetFirstByte;
qint32 copyDirection = 1;
// Let readOffset (r) and writeOffset (w) be the offsets of the first chunk that we move.
// When we move data to the left:
// ______target______ ______source______
// r <- w=================
qint64 readOffset = sourceOffset;
qint64 writeOffset = targetOffset;
// When we move data to the right, we start moving data from the last chunk
// ______source______ ______target______
// =================r -> w
if (copyDirection == CopyDirection::Right) {
readOffset = sourceOffset + sourceLength - chunkSize;
writeOffset = targetOffset + sourceLength - chunkSize;
if (targetFirstByte > sourceFirstByte) {
readOffset = sourceFirstByte + sourceLength - blockSize;
writeOffset = targetFirstByte + sourceLength - blockSize;
copyDirection = -1;
}
const qint64 chunksToCopy = sourceLength / chunkSize;
const qint64 lastBlock = sourceLength % chunkSize;
const qint64 lastBlock = sourceLength % blockSize;
qint64 bytesWritten = 0;
qint64 chunksCopied = 0;
qint64 blocksCopied = 0;
QByteArray buffer;
int percent = 0;
@ -232,29 +183,27 @@ QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, con
timer.start();
QString reportText = xi18nc("@info:progress", "Copying %1 chunks (%2 bytes) from %3 to %4, direction: %5.", chunksToCopy,
sourceLength, readOffset, writeOffset, copyDirection == CopyDirection::Left ? i18nc("direction: left", "left")
QString reportText = 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"));
Q_EMIT report(reportText);
bool rval = true;
QFile target(targetDevice);
QFile source(sourceDevice);
while (chunksCopied < chunksToCopy) {
if (!(rval = readData(source, buffer, readOffset + chunkSize * chunksCopied * copyDirection, chunkSize)))
while (blocksCopied < blocksToCopy && !targetDevice.isEmpty()) {
if (!(rval = readData(sourceDevice, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize)))
break;
if (!(rval = writeData(target, buffer, writeOffset + chunkSize * chunksCopied * copyDirection)))
if (!(rval = writeData(targetDevice, buffer, writeOffset + blockSize * blocksCopied * copyDirection)))
break;
bytesWritten += buffer.size();
if (++chunksCopied * 100 / chunksToCopy != percent) {
percent = chunksCopied * 100 / chunksToCopy;
if (++blocksCopied * 100 / blocksToCopy != percent) {
percent = blocksCopied * 100 / blocksToCopy;
if (percent % 5 == 0 && timer.elapsed() > 1000) {
const qint64 mibsPerSec = (chunksCopied * chunkSize / 1024 / 1024) / (timer.elapsed() / 1000);
const qint64 mibsPerSec = (blocksCopied * blockSize / 1024 / 1024) / (timer.elapsed() / 1000);
const qint64 estSecsLeft = (100 - percent) * timer.elapsed() / percent / 1000;
reportText = xi18nc("@info:progress", "Copying %1 MiB/second, estimated time left: %2", mibsPerSec, QTime(0, 0).addSecs(estSecsLeft).toString());
Q_EMIT report(reportText);
@ -265,16 +214,19 @@ QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, con
// copy the remainder
if (rval && lastBlock > 0) {
Q_ASSERT(lastBlock < chunkSize);
Q_ASSERT(lastBlock < blockSize);
const qint64 lastBlockReadOffset = copyDirection == CopyDirection::Left ? readOffset + chunkSize * chunksCopied : sourceOffset;
const qint64 lastBlockWriteOffset = copyDirection == CopyDirection::Left ? writeOffset + chunkSize * chunksCopied : targetOffset;
reportText = xi18nc("@info:progress", "Copying remainder of chunk size %1 from %2 to %3.", lastBlock, lastBlockReadOffset, lastBlockWriteOffset);
const qint64 lastBlockReadOffset = copyDirection > 0 ? readOffset + blockSize * blocksCopied : sourceFirstByte;
const qint64 lastBlockWriteOffset = copyDirection > 0 ? writeOffset + blockSize * blocksCopied : targetFirstByte;
reportText = xi18nc("@info:progress", "Copying remainder of block size %1 from %2 to %3.", lastBlock, lastBlockReadOffset, lastBlockWriteOffset);
Q_EMIT report(reportText);
rval = readData(source, buffer, lastBlockReadOffset, lastBlock);
rval = readData(sourceDevice, buffer, lastBlockReadOffset, lastBlock);
if (rval) {
rval = writeData(target, buffer, lastBlockWriteOffset);
if (targetDevice.isEmpty())
reply[QStringLiteral("targetByteArray")] = buffer;
else
rval = writeData(targetDevice, buffer, lastBlockWriteOffset);
}
if (rval) {
@ -283,48 +235,14 @@ QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, con
}
}
reportText = xi18ncp("@info:progress argument 2 is a string such as 7 bytes (localized accordingly)", "Copying 1 chunk (%2) finished.", "Copying %1 chunks (%2) finished.", chunksCopied, i18np("1 byte", "%1 bytes", bytesWritten));
reportText = 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));
Q_EMIT report(reportText);
reply[QStringLiteral("success")] = rval;
return reply;
}
QByteArray ExternalCommandHelper::ReadData(const QString& device, const qint64 offset, const qint64 length)
{
if (!isCallerAuthorized()) {
return {};
}
if (length > MiB) {
return {};
}
if (!std::filesystem::is_block_file(device.toStdU16String())) {
qWarning() << "Not a block device";
return {};
}
// Do not follow symlinks
QFileInfo info(device);
if (info.isSymbolicLink()) {
qWarning() << "ReadData: device should not be symbolic link";
return {};
}
if (device.left(5) != QStringLiteral("/dev/") || device.left(9) != QStringLiteral("/dev/shm/")) {
qWarning() << "Error: trying to read data from device not in /dev";
return {};
}
QByteArray buffer;
QFile sourceDevice(device);
bool rval = readData(sourceDevice, buffer, offset, length);
if (rval) {
return buffer;
}
return QByteArray();
}
bool ExternalCommandHelper::WriteData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetOffset)
bool ExternalCommandHelper::WriteData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetFirstByte)
{
if (!isCallerAuthorized()) {
return false;
@ -333,74 +251,44 @@ bool ExternalCommandHelper::WriteData(const QByteArray& buffer, const QString& t
if ( targetDevice.left(5) != QStringLiteral("/dev/") )
return false;
auto targetPath = std::filesystem::path(targetDevice.toStdU16String());
if (!std::filesystem::is_block_file(targetDevice.toStdU16String())) {
qWarning() << "Not a block device";
return {};
}
auto canonicalTargetPath = std::filesystem::canonical(targetPath);
// TODO: Qt6 supports std::filesystem::path
QFile device(QLatin1String(canonicalTargetPath.c_str()));
return writeData(device, buffer, targetOffset);
return writeData(targetDevice, buffer, targetFirstByte);
}
QVariantMap ExternalCommandHelper::RunCommand(const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode)
{
if (!isCallerAuthorized()) {
return {};
return QVariantMap();
}
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
#endif
QVariantMap reply;
reply[QStringLiteral("success")] = false;
reply[QStringLiteral("success")] = true;
if (command.isEmpty()) {
return reply;
}
// Compare with command whitelist
QFileInfo fileInfo(command);
QString basename = fileInfo.fileName();
if (allowedCommands.find(basename) == allowedCommands.end()) { // TODO: C++20: replace with contains
qInfo() << command << "command is not one of the whitelisted commands";
reply[QStringLiteral("success")] = false;
return reply;
}
// Make sure command is located in the trusted prefix
QDir prefix = fileInfo.absoluteDir();
QString dirname = prefix.dirName();
if (dirname == QStringLiteral("bin") || dirname == QStringLiteral("sbin")) {
prefix.cdUp();
}
if (trustedPrefixes.find(prefix.path()) == trustedPrefixes.end()) { // TODO: C++20: replace with contains
qInfo() << prefix.path() << "prefix is not one of the trusted command prefixes";
// 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";
qApp->quit();
reply[QStringLiteral("success")] = false;
return reply;
}
// connect(&cmd, &QProcess::readyReadStandardOutput, this, &ExternalCommandHelper::onReadOutput);
QProcess cmd;
cmd.setEnvironment( { QStringLiteral("LVM_SUPPRESS_FD_WARNINGS=1") } );
if((processChannelMode != QProcess::SeparateChannels) && (processChannelMode != QProcess::MergedChannels)) {
return reply;
}
cmd.setProcessChannelMode(static_cast<QProcess::ProcessChannelMode>(processChannelMode));
cmd.start(command, arguments);
cmd.write(input);
cmd.closeWriteChannel();
cmd.waitForFinished(-1);
QByteArray output = cmd.readAllStandardOutput();
m_cmd.setEnvironment( { QStringLiteral("LVM_SUPPRESS_FD_WARNINGS=1") } );
m_cmd.setProcessChannelMode(static_cast<QProcess::ProcessChannelMode>(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")] = cmd.exitCode();
reply[QStringLiteral("exitCode")] = m_cmd.exitCode();
reply[QStringLiteral("success")] = true;
return reply;
}
@ -428,9 +316,6 @@ bool ExternalCommandHelper::isCallerAuthorized()
// Cache successful authentication requests, so that clients don't need
// to authenticate multiple times during long partitioning operations.
// auth_admin_keep is not used intentionally because with current architecture
// it might lead to data loss if user cancels sfdisk partition boundary adjustment
// after partition data was moved.
if (m_serviceWatcher->watchedServices().contains(message().service())) {
return true;
}

View File

@ -14,14 +14,12 @@
#include <memory>
#include <unordered_set>
#include <QDBusContext>
#include <QEventLoop>
#include <QFile>
#include <QProcess>
#include <QString>
#include <QProcess>
#include <QDBusContext>
class QDBusServiceWatcher;
constexpr qint64 MiB = 1 << 20;
class ExternalCommandHelper : public QObject, public QDBusContext
{
@ -34,21 +32,21 @@ Q_SIGNALS:
public:
ExternalCommandHelper();
bool readData(QFile& device, QByteArray& buffer, const qint64 offset, const qint64 size);
bool writeData(QFile& device, const QByteArray& buffer, const qint64 offset);
bool readData(const QString& sourceDevice, QByteArray& buffer, const qint64 offset, const qint64 size);
bool writeData(const QString& targetDevice, const QByteArray& buffer, const qint64 offset);
public Q_SLOTS:
Q_SCRIPTABLE QVariantMap RunCommand(const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode);
Q_SCRIPTABLE QVariantMap CopyFileData(const QString& sourceDevice, const qint64 sourceOffset, const qint64 sourceLength,
const QString& targetDevice, const qint64 targetOffset, const qint64 blockSize);
Q_SCRIPTABLE QByteArray ReadData(const QString& device, const qint64 offset, const qint64 length);
Q_SCRIPTABLE bool WriteData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetOffset);
Q_SCRIPTABLE bool WriteFstab(const QByteArray& fstabContents);
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 bool CreateFile(const QString& filePath, const QByteArray& fileContents);
private:
bool isCallerAuthorized();
void onReadOutput();
QProcess m_cmd;
QDBusServiceWatcher *m_serviceWatcher = nullptr;
};

View File

@ -48,7 +48,7 @@ KAboutData aboutKPMcore()
KAboutData aboutData( QStringLiteral("kpmcore"),
xi18nc("@title", "<application>KPMcore</application>"), QStringLiteral(VERSION),
xi18nc("@title", "Library for managing partitions"),
KAboutLicense::GPL_V3, xi18nc("@info:credit", "&copy; 2008-2022 KPMcore developers" ) );
KAboutLicense::GPL_V3, xi18nc("@info:credit", "&copy; 2008-2020 KPMcore developers" ) );
aboutData.setOrganizationDomain(QByteArray("kde.org"));
aboutData.setProductName(QByteArray("kpmcore"));
aboutData.setHomepage(QStringLiteral("https://commits.kde.org/kpmcore"));

View File

@ -0,0 +1,14 @@
/*
SPDX-FileCopyrightText: 2008 Volker Lanz <vl@fidra.de>
SPDX-FileCopyrightText: 2014-2018 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2015 Chris Campbell <c.j.campbell@ed.ac.uk>
SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef LIBKPMCORE_EXPORT
#include <QtGlobal>
#define LIBKPMCORE_EXPORT Q_DECL_EXPORT
#endif

View File

@ -0,0 +1,65 @@
[Domain]
Icon=partitionmanager
[org.kde.kpmcore.externalcommand.init]
Name=Start external command daemon
Name[ast]=Aniciu del degorriu de comandos esternos
Name[ca]=Inicia el dimoni d'ordres externes
Name[ca@valencia]=Inicia el dimoni d'ordres externes
Name[cs]=Spustit démona externích příkazů
Name[da]=Start ekstern kommando-dæmon
Name[de]=Externen Befehlsdienst starten
Name[el]=Εκκίνηση διεργασίας με εξωτερική εντολή
Name[en_GB]=Start external command daemon
Name[es]=Iniciar el demonio de órdenes externas
Name[et]=Välise käsu deemoni käivitamine
Name[eu]=Abiarazi kanpoko komandoen daimona
Name[fi]=Käynnistä ulkoinen komentopalvelu
Name[fr]=Lancer le démon de la commande externe
Name[gl]=Iniciar o servizo de orde externa
Name[it]=Avvia demone per comando esterno
Name[ko]=외부 명령 데몬 시작
Name[lt]=Paleisti išorinių komandų tarnybą
Name[nl]=Start externe opdrachtdaemon
Name[pl]=Rozpocznij usługę zewnętrznego polecenia
Name[pt]=Iniciar o servidor de comandos externos
Name[pt_BR]=Iniciar comando externo do daemon
Name[sk]=Spustiť externé démony príkazov
Name[sl]=Zaženite demon za zunanje ukaze
Name[sv]=Starta extern kommandodemon
Name[uk]=Запуск фонової служби зовнішньої команди
Name[x-test]=xxStart external command daemonxx
Name[zh_TW]=啟動外部指令守護程式
Description=Administrative privileges are required to manage disks
Description[ast]=Ríquense los privilexos alministrativos pa xestionar discos
Description[ca]=Es requereixen privilegis d'administrador per a gestionar els discs
Description[ca@valencia]=Es requereixen privilegis d'administrador per a gestionar els discs
Description[cs]=Pro správu disků jsou potřeba práva administrátora
Description[da]=Der kræves administrative rettigheder for at håndtere diske
Description[de]=Systemverwalterrechte sind zur Verwaltung von Festplatten erforderlich
Description[el]=Απαιτούνται δικαιώματα διαχειριστή για τη διαχείριση δίσκων
Description[en_GB]=Administrative privileges are required to manage disks
Description[es]=Se necesitan permisos de administrador para gestionar discos
Description[et]=Ketaste haldamiseks on tarvis administraatori õigusi
Description[eu]=Administrazio pribilegioak behar dira diskoak kudeatzeko
Description[fi]=Levyjen hallinta vaatii pääkäyttäjäoikeuksia
Description[fr]=Vous devez disposer des privilèges d'administrateur pour gérer les disques
Description[gl]=Requírense privilexios de administración para xestionar discos.
Description[it]=Per gestire il disco sono richiesti privilegi di amministratore
Description[ja]=ディスクを管理するには管理者権限が必要です
Description[ko]=디스크를 관리하려면 권한이 필요함
Description[lt]=Diskų tvarkymui reikalingos administratoriaus teisės
Description[nl]=Er zijn administratieve rechten vereist om schijven te beheren
Description[pl]=Do zarządzania dyskami wymagane są uprawnienia administratora
Description[pt]=São necessários privilégios de administrador para gerir os discos
Description[pt_BR]=São necessários privilégios administrativos para gerenciar discos
Description[ru]=Для управления дисками требуются права администратора
Description[sk]=Na správu diskov sa vyžadujú práva správcu
Description[sl]=Za upravljanje diskov so potrebne pravice upravljavca računalnika
Description[sv]=Administratörsprivilegier krävs för att hantera diskar
Description[uk]=Для керування дисками потрібні права доступу адміністратора (root)
Description[x-test]=xxAdministrative privileges are required to manage disksxx
Description[zh_CN]=管理磁盘需要管理权限
Description[zh_TW]=管理硬碟需要管理員權限
Policy=auth_admin
Persistence=session

View File

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: none
SPDX-License-Identifier: CC0-1.0
-->
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>
<icon_name>partitionmanager</icon_name>
<action id="org.kde.kpmcore.externalcommand.init" >
<description>Run privileged partition manager helper</description>
<description xml:lang="ca">Executa l'ajudant del gestor de particions amb privilegis</description>
<description xml:lang="ca@valencia">Executa l'ajudant del gestor de particions amb privilegis</description>
<description xml:lang="en_GB">Run privileged partition manager helper</description>
<description xml:lang="es">Ejecutar la aplicación auxiliar de gestión de particiones con privilegios</description>
<description xml:lang="fr">Lancer l'assistant de gestionnaire de partition en mode administrateur</description>
<description xml:lang="it">Esegui l'helper per la gestione delle partizioni privilegiate</description>
<description xml:lang="ko">상위 권한으로 파티션 관리자 도우미 실행</description>
<description xml:lang="nl">Hulpprogramma voor partitiebeheerder met extra rechten uitvoeren</description>
<description xml:lang="pl">Uruchom uprzywilejowane zarządzanie partycjami</description>
<description xml:lang="pt">Executar o utilitário privilegiado do gestor de partições</description>
<description xml:lang="pt_BR">Executa o auxiliar do gerenciador de partições com privilégios</description>
<description xml:lang="sl">Zaženi pooblaščenega pomočnika skrbnika particij</description>
<description xml:lang="sv">Kör hjälpverktyg för privilegierad partitionshanterare</description>
<description xml:lang="uk">Запуск привілейованої допоміжної програми з керування розділами</description>
<description xml:lang="zh_CN">使用管理员权限运行分区管理器辅助程序</description>
<message>Administrative privileges are required to manage disks</message>
<message xml:lang="ast">Ríquense los privilexos alministrativos pa xestionar discos</message>
<message xml:lang="ca">Es requereixen privilegis d'administrador per a gestionar els discs</message>
<message xml:lang="ca@valencia">Es requerixen privilegis d'administrador per a gestionar els discs</message>
<message xml:lang="cs">Pro správu disků jsou potřeba práva administrátora</message>
<message xml:lang="de">Systemverwalterrechte sind zur Verwaltung von Festplatten erforderlich</message>
<message xml:lang="el">Απαιτούνται δικαιώματα διαχειριστή για τη διαχείριση των δίσκων</message>
<message xml:lang="en_GB">Administrative privileges are required to manage disks</message>
<message xml:lang="es">Se necesitan permisos de administrador para gestionar discos</message>
<message xml:lang="fr">Vous devez disposer des privilèges d'administrateur pour gérer les disques.</message>
<message xml:lang="hu">A lemzek kezeléséhez adminisztrátori jogosultságok szükségesek</message>
<message xml:lang="it">Per gestire il disco sono richiesti privilegi amministrativi</message>
<message xml:lang="ko">디스크를 관리하려면 권한이 필요함</message>
<message xml:lang="lt">Diskų tvarkymui reikalingos administratoriaus teisės</message>
<message xml:lang="nl">Er zijn administratieve rechten vereist om schijven te beheren</message>
<message xml:lang="pl">Do zarządzania dyskami wymagane są uprawnienia administratora</message>
<message xml:lang="pt">São necessários privilégios de administração para gerir os discos</message>
<message xml:lang="pt_BR">São necessários privilégios administrativos para gerenciar discos</message>
<message xml:lang="sk">Na správu diskov sa vyžadujú oprávnenia správcu</message>
<message xml:lang="sl">Za upravljanje diskov so potrebne pravice upravljavca računalnika</message>
<message xml:lang="sv">Administratörsprivilegier krävs för att hantera diskar</message>
<message xml:lang="uk">Для керування дисками потрібні права доступу адміністратора (root)</message>
<message xml:lang="zh_CN">管理磁盘需要管理员权限</message>
<defaults>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>

View File

@ -36,7 +36,7 @@ class LIBKPMCORE_EXPORT Report : public QObject
public:
explicit Report(Report* p, const QString& cmd = QString());
~Report() override;
~Report();
Q_SIGNALS:
void outputChanged();

View File

@ -1,2 +0,0 @@
/
/usr

View File

@ -14,6 +14,7 @@ set(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
include_directories(${CMAKE_SOURCE_DIR}/src) # To get at KPMcore headers
add_compile_options(-fPIC)
###
@ -22,11 +23,11 @@ add_compile_options(-fPIC)
# and to add a test with the given name.
#
add_library(testhelpers STATIC helpers.cpp)
target_link_libraries(testhelpers PRIVATE kpmcore)
target_link_libraries(testhelpers)
macro (kpm_test name)
add_executable(${name} ${ARGN})
target_link_libraries(${name} testhelpers kpmcore Qt${QT_MAJOR_VERSION}::Core)
target_link_libraries(${name} testhelpers kpmcore Qt5::Core)
endmacro()
###
@ -34,15 +35,15 @@ endmacro()
# Tests of initialization: try explicitly loading some backends
kpm_test(testinit testinit.cpp) # Default backend
if(TARGET pmdummybackendplugin)
add_test(NAME testinit-dummy COMMAND testinit $<TARGET_FILE_NAME:pmdummybackendplugin>)
add_test(NAME testinit-dummy COMMAND testinit $<TARGET_FILE:pmdummybackendplugin>)
endif()
if(TARGET pmsfdiskbackendplugin)
add_test(NAME testinit-sfdisk COMMAND testinit $<TARGET_FILE_NAME:pmsfdiskbackendplugin>)
add_test(NAME testinit-sfdisk COMMAND testinit $<TARGET_FILE:pmsfdiskbackendplugin>)
else()
return() # All the rest really needs a working backend
endif()
set(BACKEND $<TARGET_FILE_NAME:pmsfdiskbackendplugin>)
set(BACKEND $<TARGET_FILE:pmsfdiskbackendplugin>)
###
#