diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 156c7cd..52ee0b9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,65 +1,65 @@ # Copyright (C) 2008, 2012 by Volker Lanz # Copyright (C) 2015 by Teo Mrnjavac # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 3 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ############################################ add_definitions(-DTRANSLATION_DOMAIN=\"kpmcore\") include(backend/CMakeLists.txt) include(core/CMakeLists.txt) include(util/CMakeLists.txt) include(ops/CMakeLists.txt) include(jobs/CMakeLists.txt) include(fs/CMakeLists.txt) include(gui/CMakeLists.txt) set(kpmcore_SRCS ${BACKEND_SRC} ${FS_SRC} ${CORE_SRC} ${OPS_SRC} ${JOBS_SRC} ${UTIL_SRC} ${GUI_SRC} ) ki18n_wrap_ui(kpmcore_SRCS ${gui_UIFILES}) add_library(kpmcore SHARED ${kpmcore_SRCS}) target_link_libraries( kpmcore PUBLIC - PRIVATE Qt5::Core + PRIVATE Qt5::DBus Qt5::Gui KF5::I18n KF5::CoreAddons KF5::WidgetsAddons ${BLKID_LIBRARIES} KF5::Auth ) 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) ############################################ add_subdirectory(plugins) diff --git a/src/backend/corebackend.cpp b/src/backend/corebackend.cpp index 5360610..fbd3410 100644 --- a/src/backend/corebackend.cpp +++ b/src/backend/corebackend.cpp @@ -1,75 +1,79 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #include "backend/corebackend.h" #include "core/device.h" #include "core/partitiontable.h" #include "util/globallog.h" #include struct CoreBackendPrivate { QString m_id, m_version; }; CoreBackend::CoreBackend() : d(std::make_unique()) { } CoreBackend::~CoreBackend() { } void CoreBackend::emitProgress(int i) { emit progress(i); } void CoreBackend::emitScanProgress(const QString& deviceNode, int i) { emit scanProgress(deviceNode, i); } void CoreBackend::setPartitionTableForDevice(Device& d, PartitionTable* p) { d.setPartitionTable(p); } void CoreBackend::setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_primaries) { p.setMaxPrimaries(max_primaries); } -QString CoreBackend::id() { +QString CoreBackend::id() +{ return d->m_id; } -QString CoreBackend::version() { +QString CoreBackend::version() +{ return d->m_version; } -void CoreBackend::setId(const QString& id) { +void CoreBackend::setId(const QString& id) +{ d->m_id = id; } -void CoreBackend::setVersion(const QString& version) { +void CoreBackend::setVersion(const QString& version) +{ d->m_version = version; } diff --git a/src/backend/corebackendmanager.cpp b/src/backend/corebackendmanager.cpp index 1fbca68..62322f2 100644 --- a/src/backend/corebackendmanager.cpp +++ b/src/backend/corebackendmanager.cpp @@ -1,144 +1,147 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * Copyright (C) 2015 by Teo Mrnjavac * * Copyright (C) 2016-2018 by Andrius Štikonas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #include "backend/corebackendmanager.h" #include "backend/corebackend.h" #include #include #include #include #include #include #include #include #include #include #include #include struct CoreBackendManagerPrivate { KAuth::ExecuteJob *m_job; CoreBackend *m_Backend; QString m_Uuid; }; CoreBackendManager::CoreBackendManager() : d(std::make_unique()) { startExternalCommandHelper(); } CoreBackendManager* CoreBackendManager::self() { static CoreBackendManager* instance = nullptr; if (instance == nullptr) instance = new CoreBackendManager; return instance; } -CoreBackend* CoreBackendManager::backend() { +CoreBackend* CoreBackendManager::backend() +{ return d->m_Backend; } QVector CoreBackendManager::list() const { 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); } void CoreBackendManager::startExternalCommandHelper() { KAuth::Action action = KAuth::Action(QStringLiteral("org.kde.kpmcore.externalcommand.init")); action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand")); action.setTimeout(10 * 24 * 3600 * 1000); // 10 days QVariantMap arguments; d->m_Uuid = QUuid::createUuid().toString(); arguments.insert(QStringLiteral("callerUuid"), Uuid()); action.setArguments(arguments); d->m_job = action.execute(); job()->start(); // Wait until ExternalCommand Helper is ready (helper sends newData signal just before it enters event loop) QEventLoop loop; auto exitLoop = [&] () { loop.exit(); }; auto conn = QObject::connect(job(), &KAuth::ExecuteJob::newData, exitLoop); QObject::connect(job(), &KJob::finished, [=] () { if(d->m_job->error()) exitLoop(); } ); loop.exec(); QObject::disconnect(conn); } void CoreBackendManager::stopExternalCommandHelper() { QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); if (iface.isValid()) iface.call(QStringLiteral("exit"), CoreBackendManager::self()->Uuid()); } -KAuth::ExecuteJob* CoreBackendManager::job() { +KAuth::ExecuteJob* CoreBackendManager::job() +{ return d->m_job; } -QString& CoreBackendManager::Uuid() { +QString& CoreBackendManager::Uuid() +{ return d->m_Uuid; } bool CoreBackendManager::load(const QString& name) { if (backend()) unload(); KPluginLoader loader(name); KPluginFactory* factory = loader.factory(); if (factory != nullptr) { d->m_Backend = factory->create(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; } qWarning() << "Could not load plugin for core backend " << name << ": " << loader.errorString(); return false; } void CoreBackendManager::unload() { } diff --git a/src/core/fstab.cpp b/src/core/fstab.cpp index ebbad89..4cf9ee4 100644 --- a/src/core/fstab.cpp +++ b/src/core/fstab.cpp @@ -1,210 +1,287 @@ /************************************************************************* * Copyright (C) 2009, 2010 by Volker Lanz * * Copyright (C) 2016 by Teo Mrnjavac * * Copyright (C) 2017 by Andrius Štikonas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #include "core/fstab.h" #include "util/externalcommand.h" #if defined(Q_OS_LINUX) #include #endif #include #include #include #include #include #include static void parseFsSpec(const QString& m_fsSpec, FstabEntryType& m_entryType, QString& m_deviceNode); static QString findBlkIdDevice(const char *token, const QString& value); -FstabEntry::FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq, int passNumber, const QString& comment) - : m_fsSpec(fsSpec) - , m_mountPoint(mountPoint) - , m_type(type) - , m_dumpFreq(dumpFreq) - , m_passNumber(passNumber) - , m_comment(comment) +struct FstabEntryPrivate { - m_options = options.split(QLatin1Char(',')); - parseFsSpec(m_fsSpec, m_entryType, m_deviceNode); -} + QString m_fsSpec; + QString m_deviceNode; + QString m_mountPoint; + QString m_type; + QStringList m_options; + int m_dumpFreq; + int m_passNumber; + QString m_comment; + FstabEntryType m_entryType; +}; -/** - @param s the new value for the fs_spec field of fstab entry -*/ -void FstabEntry::setFsSpec(const QString& s) +FstabEntry::FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq, int passNumber, const QString& comment) : + d(std::make_unique()) { - m_fsSpec = s; - parseFsSpec(m_fsSpec, m_entryType, m_deviceNode); + d->m_fsSpec = fsSpec; + d->m_mountPoint = mountPoint; + d->m_type = type; + d->m_dumpFreq = dumpFreq; + d->m_passNumber = passNumber; + d->m_comment = comment; + + d->m_options = options.split(QLatin1Char(',')); + parseFsSpec(d->m_fsSpec, d->m_entryType, d->m_deviceNode); } FstabEntryList readFstabEntries( const QString& fstabPath ) { FstabEntryList fstabEntries; QFile fstabFile( fstabPath ); if ( fstabFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) { const QStringList fstabLines = QString::fromLocal8Bit(fstabFile.readAll()).split( QLatin1Char('\n') ); for ( const QString& rawLine : fstabLines ) { QString line = rawLine.trimmed(); if ( line.startsWith( QLatin1Char('#') ) || line.isEmpty()) { - fstabEntries.append( { {}, {}, {}, {}, {}, {}, line } ); + fstabEntries.push_back( { {}, {}, {}, {}, {}, {}, line } ); continue; } QString comment = line.section( QLatin1Char('#'), 1 ); QStringList splitLine = line.section( QLatin1Char('#'), 0, 0 ).split( QRegularExpression(QStringLiteral("[\\s]+")), QString::SkipEmptyParts ); // We now split the standard components of /etc/fstab entry: // (0) path, or UUID, or LABEL, etc, // (1) mount point, // (2) file system type, // (3) options, // (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). switch (splitLine.length()) { case 4: - fstabEntries.append( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3) } ); + fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3) } ); break; case 5: - fstabEntries.append( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt() } ); + fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt() } ); break; case 6: - fstabEntries.append( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt(), splitLine.at(5).toInt(), comment.isEmpty() ? QString() : QLatin1Char('#') + comment } ); + fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt(), splitLine.at(5).toInt(), comment.isEmpty() ? QString() : QLatin1Char('#') + comment } ); break; default: - fstabEntries.append( { {}, {}, {}, {}, {}, {}, QLatin1Char('#') + line } ); + fstabEntries.push_back( { {}, {}, {}, {}, {}, {}, QLatin1Char('#') + line } ); } } fstabFile.close(); - if (fstabEntries.last().entryType() == comment && fstabEntries.last().comment().isEmpty()) - fstabEntries.removeLast(); + if (fstabEntries.back().entryType() == comment && fstabEntries.back().comment().isEmpty()) + fstabEntries.pop_back(); } return fstabEntries; } +void FstabEntry::setFsSpec(const QString& s) +{ + d->m_fsSpec = s; + parseFsSpec(d->m_fsSpec, d->m_entryType, d->m_deviceNode); +} + +const QString& FstabEntry::fsSpec() const +{ + return d->m_fsSpec; +} + +const QString& FstabEntry::deviceNode() const +{ + return d->m_deviceNode; +} + +const QString& FstabEntry::mountPoint() const +{ + return d->m_mountPoint; +} + +const QString& FstabEntry::type() const +{ + return d->m_type; +} + +const QStringList& FstabEntry::options() const +{ + return d->m_options; +} + +int FstabEntry::dumpFreq() const +{ + return d->m_dumpFreq; +} + +int FstabEntry::passNumber() const +{ + return d->m_passNumber; +} + +const QString& FstabEntry::comment() const +{ + return d->m_comment; +} + +FstabEntryType FstabEntry::entryType() const +{ + return d->m_entryType; +} + +void FstabEntry::setMountPoint(const QString& s) +{ + d->m_mountPoint = s; +} + +void FstabEntry::setOptions(const QStringList& s) +{ + d->m_options = s; +} + +void FstabEntry::setDumpFreq(int s) +{ + d->m_dumpFreq = s; +} + +void FstabEntry::setPassNumber(int s) +{ + d->m_passNumber = s; +} + QStringList possibleMountPoints(const QString& deviceNode, const QString& fstabPath) { QStringList mountPoints; QString canonicalPath = QFileInfo(deviceNode).canonicalFilePath(); const FstabEntryList fstabEntryList = readFstabEntries( fstabPath ); for (const FstabEntry &entry : fstabEntryList) if (QFileInfo(entry.deviceNode()).canonicalFilePath() == canonicalPath) mountPoints.append(entry.mountPoint()); return mountPoints; } static QString findBlkIdDevice(const char *token, const QString& value) { QString rval; #if defined(Q_OS_LINUX) if (char* c = blkid_evaluate_tag(token, value.toLocal8Bit().constData(), nullptr)) { rval = QString::fromLocal8Bit(c); free(c); } #endif return rval; } static void parseFsSpec(const QString& m_fsSpec, FstabEntryType& m_entryType, QString& m_deviceNode) { m_entryType = FstabEntryType::comment; if (m_fsSpec.startsWith(QStringLiteral("UUID="))) { m_entryType = FstabEntryType::uuid; m_deviceNode = findBlkIdDevice("UUID", QString(m_fsSpec).remove(QStringLiteral("UUID="))); } else if (m_fsSpec.startsWith(QStringLiteral("LABEL="))) { m_entryType = FstabEntryType::label; m_deviceNode = findBlkIdDevice("LABEL", QString(m_fsSpec).remove(QStringLiteral("LABEL="))); } else if (m_fsSpec.startsWith(QStringLiteral("PARTUUID="))) { m_entryType = FstabEntryType::uuid; m_deviceNode = findBlkIdDevice("PARTUUID", QString(m_fsSpec).remove(QStringLiteral("PARTUUID="))); } else if (m_fsSpec.startsWith(QStringLiteral("PARTLABEL="))) { m_entryType = FstabEntryType::label; m_deviceNode = findBlkIdDevice("PARTLABEL", QString(m_fsSpec).remove(QStringLiteral("PARTLABEL="))); } else if (m_fsSpec.startsWith(QStringLiteral("/"))) { m_entryType = FstabEntryType::deviceNode; m_deviceNode = m_fsSpec; } } static void writeEntry(QFile& output, const FstabEntry& entry) { QTextStream s(&output); if (entry.entryType() == FstabEntryType::comment) { s << entry.comment() << "\n"; return; } QString options; if (entry.options().size() > 0) { options = entry.options().join(QLatin1Char(',')); if (options.isEmpty()) options = QStringLiteral("defaults"); } else options = QStringLiteral("defaults"); s << entry.fsSpec() << "\t" << (entry.mountPoint().isEmpty() ? QStringLiteral("none") : entry.mountPoint()) << "\t" << entry.type() << "\t" << options << "\t" << entry.dumpFreq() << "\t" << entry.passNumber() << "\t" << entry.comment() << "\n"; } -bool writeMountpoints(const FstabEntryList fstabEntries, const QString& filename) +bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename) { QTemporaryFile out; out.setAutoRemove(false); if (!out.open()) { qWarning() << "could not open output file " << out.fileName(); return false; } else { for (const auto &e : fstabEntries) writeEntry(out, e); out.close(); const QString bakFilename = QStringLiteral("%1.bak").arg(filename); ExternalCommand mvCmd(QStringLiteral("mv"), { filename, bakFilename } ); if ( !(mvCmd.run(-1) && mvCmd.exitCode() == 0) ) { qWarning() << "could not backup " << filename << " to " << bakFilename; return false; } ExternalCommand mvCmd2(QStringLiteral("mv"), { out.fileName(), filename } ); if ( !(mvCmd2.run(-1) && mvCmd2.exitCode() == 0) ) { qWarning() << "could not move " << out.fileName() << " to " << filename; return false; } } return true; } diff --git a/src/core/fstab.h b/src/core/fstab.h index b813c64..ca3c8b6 100644 --- a/src/core/fstab.h +++ b/src/core/fstab.h @@ -1,99 +1,124 @@ /************************************************************************* - * Copyright (C) 2017 by Andrius Štikonas * + * Copyright (C) 2017-2018 by Andrius Štikonas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #ifndef KPMCORE_FSTAB_H #define KPMCORE_FSTAB_H #include "util/libpartitionmanagerexport.h" +#include + #include #include +struct FstabEntryPrivate; + enum FstabEntryType { deviceNode, uuid, label, partlabel, partuuid, comment }; /** Base class for fstab handling. FstabEntry stores a single line of /etc/fstab file which can be a comment @author Andrius Štikonas */ class LIBKPMCORE_EXPORT FstabEntry { public: FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq = 0, int passNumber = 0, const QString& comment = QString()); - const QString& fsSpec() const { - return m_fsSpec; /**< @return the fs_spec field of fstab entry */ - } - const QString& deviceNode() const { - return m_deviceNode; /**< @return the device node corresponding to fs_spec entry */ - } - const QString& mountPoint() const { - return m_mountPoint; /**< @return the mount point (target) for the file system */ - } - const QString& type() const { - return m_type; /**< @return the type of the file system */ - } - const QStringList& options() const { - return m_options; /**< @return the mount options associated with the file system */ - } - int dumpFreq() const { - return m_dumpFreq; /**< @return the fs_freq field of fstab entry */ - } - int passNumber() const { - return m_passNumber; /**< @return the fs_passno field of fstab entry */ - } - const QString& comment() const { - return m_comment; /**< @return commented part of the line in fstab file */ - } - FstabEntryType entryType() const { - return m_entryType; /**< @return the type of fstab entry, e.g. device node or UUID or comment only */ - } + /** + * @return the fs_spec field of fstab entry + */ + const QString& fsSpec() const; + + /** + * @return the device node corresponding to fs_spec entry + */ + const QString& deviceNode() const; + + /** + * @return the mount point (target) for the file system + */ + const QString& mountPoint() const; + + /** + * @return the type of the file system + */ + const QString& type() const; + + /** + * @return the mount options associated with the file system + */ + const QStringList& options() const; + + /** + * @return the fs_freq field of fstab entry + */ + int dumpFreq() const; + + /** + * @return the fs_passno field of fstab entry + */ + int passNumber() const; + /** + * @return commented part of the line in fstab file + */ + const QString& comment() const; + + /** + * @return the type of fstab entry, e.g. device node or UUID or comment only + */ + FstabEntryType entryType() const; + + /** + * @param s the new value for the fs_spec field of fstab entry + */ void setFsSpec(const QString& s); - void setMountPoint(const QString& s) { - m_mountPoint = s; /**< @param s the new value for the mount point */ - } - void setOptions(const QStringList& s) { - m_options = s; /**< @param s the new list with the mount options */ - } - void setDumpFreq(int s) { - m_dumpFreq = s; /**< @param s the new value for the dump frequency */ - } - void setPassNumber(int s) { - m_passNumber = s; /**< @param s the new value for the pass number */ - } + + /** + * @param s the new value for the mount point + */ + void setMountPoint(const QString& s); + + /** + * @param s the new list with the mount options + */ + void setOptions(const QStringList& s); + + /** + * @param s the new value for the dump frequency + */ + void setDumpFreq(int s); + + /** + * @param s the new value for the pass number + */ + void setPassNumber(int s); + private: - QString m_fsSpec; - QString m_deviceNode; - QString m_mountPoint; - QString m_type; - QStringList m_options; - int m_dumpFreq; - int m_passNumber; - QString m_comment; - FstabEntryType m_entryType; + std::shared_ptr d; }; typedef QList FstabEntryList; 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, const QString& filename = QStringLiteral("/etc/fstab")); +LIBKPMCORE_EXPORT bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename = QStringLiteral("/etc/fstab")); #endif