milestone: Phase 4-5 completion + KF6 honesty + KDE session + GPU CS ioctl
Phase 4 KDE Plasma: - 20 KF6 + kglobalacceld + plasma-workspace + plasma-desktop + plasma-framework enabled - kf6-kio honest reduced build (package-local QtNetwork compat headers, no sysroot fakery) - kf6-kdeclarative enabled - redbear-kde-session launcher (DRM/virtual backend, plasmashell/kded6, readiness markers) - Phase 4 checker: required plasmashell/kded6 process checks (FAIL on absence) Phase 5 Hardware GPU: - CS ioctl checker (GEM allocation, PRIME sharing, private CS submit/wait over /scheme/drm/card0) - Enhanced GPU checker with hardware rendering readiness summary - test-phase5-cs-runtime.sh harness Qt6Quick honesty: qtdeclarative exports Qt6Quick metadata; downstream QML/Kirigami/KWin proof still insufficient. Oracle-verified: Phase 4-5 (5 rounds). Build: zero warnings.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#TODO: KDeclarative — KDE QtQuick integration. QML disabled for Redox.
|
||||
# KDeclarative — reduced real build for Red Bear OS.
|
||||
# QML-backed runtime pieces stay disabled with BUILD_WITH_QML=OFF.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kdeclarative/-/archive/v6.10.0/kdeclarative-v6.10.0.tar.gz"
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
#TODO: KIO — file I/O abstraction, network transparency, job system. Core KDE framework.
|
||||
# KIO — reduced real KIOCore build for Red Bear OS.
|
||||
#
|
||||
# Honesty boundary:
|
||||
# - KIOCORE_ONLY=ON, BUILD_WITH_QML=OFF, USE_DBUS=OFF stay intentional.
|
||||
# - QtNetwork is still unavailable on Redox, so KIOCore uses source-local
|
||||
# Redox compatibility headers for the small QHostInfo/QHostAddress surface it needs.
|
||||
# - This recipe no longer forges QtNetwork headers into the shared sysroot.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kio/-/archive/v6.10.0/kio-v6.10.0.tar.gz"
|
||||
|
||||
@@ -42,613 +48,6 @@ for qtdir in plugins mkspecs metatypes modules; do
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${COOKBOOK_SYSROOT}/lib/cmake/Qt6Network" ]; then
|
||||
cat > "${COOKBOOK_SYSROOT}/include/QHostAddress" <<'EOF'
|
||||
#pragma once
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
|
||||
class QHostAddress
|
||||
{
|
||||
public:
|
||||
enum NetworkLayerProtocol {
|
||||
UnknownNetworkLayerProtocol = -1,
|
||||
AnyIPProtocol,
|
||||
IPv4Protocol,
|
||||
IPv6Protocol,
|
||||
};
|
||||
|
||||
QHostAddress() = default;
|
||||
explicit QHostAddress(const QString &address)
|
||||
: m_address(address)
|
||||
{
|
||||
}
|
||||
|
||||
QString toString() const
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
NetworkLayerProtocol protocol() const
|
||||
{
|
||||
return AnyIPProtocol;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_address;
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &stream, const QHostAddress &address)
|
||||
{
|
||||
stream << address.m_address;
|
||||
return stream;
|
||||
}
|
||||
|
||||
friend QDataStream &operator>>(QDataStream &stream, QHostAddress &address)
|
||||
{
|
||||
stream >> address.m_address;
|
||||
return stream;
|
||||
}
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QHostAddress)
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_SYSROOT}/include/QHostInfo" <<'EOF'
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
|
||||
#include <QHostAddress>
|
||||
|
||||
class QHostInfo
|
||||
{
|
||||
public:
|
||||
enum HostInfoError {
|
||||
NoError = 0,
|
||||
HostNotFound = 1,
|
||||
UnknownError = 2,
|
||||
};
|
||||
|
||||
QHostInfo() = default;
|
||||
explicit QHostInfo(const QString &hostName)
|
||||
: m_hostName(hostName)
|
||||
{
|
||||
}
|
||||
|
||||
static QString localHostName()
|
||||
{
|
||||
return QStringLiteral("redox");
|
||||
}
|
||||
|
||||
void setHostName(const QString &hostName)
|
||||
{
|
||||
m_hostName = hostName;
|
||||
}
|
||||
|
||||
QString hostName() const
|
||||
{
|
||||
return m_hostName;
|
||||
}
|
||||
|
||||
void setAddresses(const QList<QHostAddress> &addresses)
|
||||
{
|
||||
m_addresses = addresses;
|
||||
}
|
||||
|
||||
QList<QHostAddress> addresses() const
|
||||
{
|
||||
return m_addresses;
|
||||
}
|
||||
|
||||
void setError(HostInfoError error)
|
||||
{
|
||||
m_error = error;
|
||||
}
|
||||
|
||||
HostInfoError error() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
void setErrorString(const QString &errorString)
|
||||
{
|
||||
m_errorString = errorString;
|
||||
}
|
||||
|
||||
QString errorString() const
|
||||
{
|
||||
return m_errorString;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_hostName;
|
||||
QList<QHostAddress> m_addresses;
|
||||
HostInfoError m_error = UnknownError;
|
||||
QString m_errorString;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QHostInfo)
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_SYSROOT}/include/QLocalSocket" <<'EOF'
|
||||
#pragma once
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QIODevice>
|
||||
#include <QString>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
class QLocalSocket : public QIODevice
|
||||
{
|
||||
public:
|
||||
enum LocalSocketState {
|
||||
UnconnectedState,
|
||||
ConnectingState,
|
||||
ConnectedState,
|
||||
ClosingState,
|
||||
};
|
||||
|
||||
enum LocalSocketError {
|
||||
ConnectionRefusedError,
|
||||
PeerClosedError,
|
||||
ServerNotFoundError,
|
||||
SocketAccessError,
|
||||
SocketResourceError,
|
||||
SocketTimeoutError,
|
||||
DatagramTooLargeError,
|
||||
ConnectionError,
|
||||
UnsupportedSocketOperationError,
|
||||
OperationError,
|
||||
UnknownSocketError,
|
||||
};
|
||||
|
||||
explicit QLocalSocket(QObject *parent = nullptr)
|
||||
: QIODevice(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void connectToServer(const QString &)
|
||||
{
|
||||
m_state = UnconnectedState;
|
||||
m_errorString = QStringLiteral("QtNetwork disabled on Redox");
|
||||
setOpenMode(ReadWrite);
|
||||
}
|
||||
|
||||
void setReadBufferSize(qint64 size)
|
||||
{
|
||||
m_readBufferSize = size;
|
||||
}
|
||||
|
||||
LocalSocketState state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
LocalSocketError error() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
QString errorString() const
|
||||
{
|
||||
return m_errorString;
|
||||
}
|
||||
|
||||
qint64 bytesAvailable() const override
|
||||
{
|
||||
return m_buffer.size() + QIODevice::bytesAvailable();
|
||||
}
|
||||
|
||||
bool waitForReadyRead(int) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool waitForBytesWritten(int) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void disconnected();
|
||||
|
||||
protected:
|
||||
qint64 readData(char *data, qint64 maxSize) override
|
||||
{
|
||||
const qint64 toRead = qMin<qint64>(maxSize, m_buffer.size());
|
||||
if (toRead <= 0) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(data, m_buffer.constData(), static_cast<size_t>(toRead));
|
||||
m_buffer.remove(0, static_cast<int>(toRead));
|
||||
return toRead;
|
||||
}
|
||||
|
||||
qint64 writeData(const char *data, qint64 maxSize) override
|
||||
{
|
||||
m_written.append(data, static_cast<int>(maxSize));
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
private:
|
||||
QByteArray m_buffer;
|
||||
QByteArray m_written;
|
||||
qint64 m_readBufferSize = 0;
|
||||
LocalSocketState m_state = UnconnectedState;
|
||||
LocalSocketError m_error = ConnectionError;
|
||||
QString m_errorString;
|
||||
};
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_SYSROOT}/include/QLocalServer" <<'EOF'
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class QLocalSocket;
|
||||
|
||||
class QLocalServer : public QObject
|
||||
{
|
||||
public:
|
||||
explicit QLocalServer(QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool listen(const QString &name)
|
||||
{
|
||||
m_name = name;
|
||||
return false;
|
||||
}
|
||||
|
||||
QString errorString() const
|
||||
{
|
||||
return QStringLiteral("QtNetwork disabled on Redox");
|
||||
}
|
||||
|
||||
QLocalSocket *nextPendingConnection()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void newConnection();
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
};
|
||||
EOF
|
||||
|
||||
python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
source = Path(os.environ["COOKBOOK_SOURCE"])
|
||||
|
||||
|
||||
def replace(path: Path, old: str, new: str) -> None:
|
||||
text = path.read_text()
|
||||
if old in text:
|
||||
path.write_text(text.replace(old, new))
|
||||
elif new not in text:
|
||||
raise SystemExit(f"missing pattern in {path}: {old!r}")
|
||||
|
||||
|
||||
replace(
|
||||
source / "CMakeLists.txt",
|
||||
"find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets Network Concurrent Xml Test)",
|
||||
"find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets Concurrent Xml)",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "CMakeLists.txt",
|
||||
"find_package(LibMount REQUIRED)",
|
||||
"find_package(LibMount)",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "CMakeLists.txt",
|
||||
'''if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
find_package(LibMount)
|
||||
set(HAVE_LIB_MOUNT ${LibMount_FOUND})
|
||||
endif()''',
|
||||
'''if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT REDOX)
|
||||
find_package(LibMount)
|
||||
set(HAVE_LIB_MOUNT ${LibMount_FOUND})
|
||||
endif()''',
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "KF6KIOConfig.cmake.in",
|
||||
'''find_dependency(Qt6Network "@REQUIRED_QT_VERSION@")''',
|
||||
'''find_dependency(Qt6Concurrent "@REQUIRED_QT_VERSION@")
|
||||
find_dependency(Qt6Xml "@REQUIRED_QT_VERSION@")''',
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/CMakeLists.txt",
|
||||
'''# KIOCore-only executables
|
||||
if (NOT ANDROID)
|
||||
add_subdirectory(kioworkers)
|
||||
add_subdirectory(schemehandlers)
|
||||
endif()
|
||||
|
||||
if (HAVE_QTDBUS)
|
||||
add_subdirectory(kiod)
|
||||
add_subdirectory(kssld)
|
||||
endif()
|
||||
add_subdirectory(kioworker)
|
||||
''',
|
||||
'''# KIOCore-only executables
|
||||
if (NOT KIOCORE_ONLY)
|
||||
if (NOT ANDROID)
|
||||
add_subdirectory(kioworkers)
|
||||
add_subdirectory(schemehandlers)
|
||||
endif()
|
||||
|
||||
if (HAVE_QTDBUS)
|
||||
add_subdirectory(kiod)
|
||||
add_subdirectory(kssld)
|
||||
endif()
|
||||
add_subdirectory(kioworker)
|
||||
endif()
|
||||
''',
|
||||
)
|
||||
|
||||
core_cmake = source / "src/core/CMakeLists.txt"
|
||||
core_text = core_cmake.read_text()
|
||||
for line in [
|
||||
" hostinfo.cpp\\n",
|
||||
" ksslcertificatemanager.cpp\\n",
|
||||
" Qt6::Network\\n",
|
||||
]:
|
||||
core_text = core_text.replace(line, "")
|
||||
core_cmake.write_text(core_text)
|
||||
|
||||
replace(
|
||||
source / "src/core/askuseractioninterface.h",
|
||||
"#include <QSsl>\\n\\n",
|
||||
"",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/slavebase.h",
|
||||
"#include <QByteArray>\\n#include <QHostInfo>\\n#include <QSsl>\\n\\n#include <memory>\\n\\nclass KConfigGroup;\\nclass KRemoteEncoding;\\nclass QUrl;\\n",
|
||||
"#include <QByteArray>\\n\\n#include <memory>\\n\\nclass KConfigGroup;\\nclass KRemoteEncoding;\\nclass QHostInfo;\\nclass QUrl;\\n",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/slavebase.cpp",
|
||||
"#include <QMap>\\n#include <QSsl>\\n#include <QtGlobal>\\n",
|
||||
"#include <QMap>\\n#include <QHostInfo>\\n#include <QtGlobal>\\n",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/workerinterface_p.h",
|
||||
"#include <QHostInfo>\\n#include <QObject>\\n",
|
||||
"#include <QObject>\\n",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/workerinterface_p.h",
|
||||
"private Q_SLOTS:\\n void slotHostInfo(const QHostInfo &info);\\n\\nprotected:\\n",
|
||||
"protected:\\n",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/workerinterface.cpp",
|
||||
'''#include "connection_p.h"\n#include "kiocoredebug.h"\n''',
|
||||
'''#include "connection_p.h"\n#include "kiocoredebug.h"\n\n#include <QHostInfo>\n''',
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/workerinterface.cpp",
|
||||
''' case MSG_HOST_INFO_REQ: {
|
||||
QString hostName;
|
||||
stream >> hostName;
|
||||
HostInfo::lookupHost(hostName, this, SLOT(slotHostInfo(QHostInfo)));
|
||||
break;
|
||||
}
|
||||
''',
|
||||
''' case MSG_HOST_INFO_REQ: {
|
||||
QString hostName;
|
||||
stream >> hostName;
|
||||
QByteArray replyData;
|
||||
QDataStream replyStream(&replyData, QIODevice::WriteOnly);
|
||||
replyStream << hostName << QList<QHostAddress>() << int(QHostInfo::UnknownError) << QStringLiteral("Host lookup unavailable on Redox");
|
||||
m_connection->send(CMD_HOST_INFO, replyData);
|
||||
break;
|
||||
}
|
||||
''',
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/workerinterface.cpp",
|
||||
'''
|
||||
void WorkerInterface::slotHostInfo(const QHostInfo &info)
|
||||
{
|
||||
QByteArray data;
|
||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||
stream << info.hostName() << info.addresses() << info.error() << info.errorString();
|
||||
m_connection->send(CMD_HOST_INFO, data);
|
||||
}
|
||||
|
||||
''',
|
||||
"\\n",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/ksslerroruidata_p.h",
|
||||
"#include <QSslCertificate>\\n#include <QSslError>\\n#include <QString>\\n",
|
||||
"#include <QString>\\n",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/ksslerroruidata_p.h",
|
||||
''' QList<QSslCertificate> certificateChain;
|
||||
QList<QSslError> sslErrors; // parallel list to certificateChain
|
||||
QString ip;
|
||||
''',
|
||||
''' QString ip;
|
||||
''',
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/ksslerroruidata.cpp",
|
||||
"#include <QHostAddress>\\n#include <QNetworkReply>\\n#include <QSslCipher>\\n\\n",
|
||||
"",
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/ksslerroruidata.cpp",
|
||||
'''KSslErrorUiData::KSslErrorUiData(const QSslSocket *socket)
|
||||
: d(new Private())
|
||||
{
|
||||
d->certificateChain = socket->peerCertificateChain();
|
||||
d->sslErrors = socket->sslHandshakeErrors();
|
||||
d->ip = socket->peerAddress().toString();
|
||||
d->host = socket->peerName();
|
||||
if (socket->isEncrypted()) {
|
||||
d->sslProtocol = socket->sessionCipher().protocolString();
|
||||
}
|
||||
d->cipher = socket->sessionCipher().name();
|
||||
d->usedBits = socket->sessionCipher().usedBits();
|
||||
d->bits = socket->sessionCipher().supportedBits();
|
||||
}
|
||||
''',
|
||||
'''KSslErrorUiData::KSslErrorUiData(const QSslSocket *socket)
|
||||
: d(new Private())
|
||||
{
|
||||
d->usedBits = 0;
|
||||
d->bits = 0;
|
||||
(void)socket;
|
||||
}
|
||||
''',
|
||||
)
|
||||
|
||||
replace(
|
||||
source / "src/core/ksslerroruidata.cpp",
|
||||
'''KSslErrorUiData::KSslErrorUiData(const QNetworkReply *reply, const QList<QSslError> &sslErrors)
|
||||
: d(new Private())
|
||||
{
|
||||
const auto sslConfig = reply->sslConfiguration();
|
||||
d->certificateChain = sslConfig.peerCertificateChain();
|
||||
d->sslErrors = sslErrors;
|
||||
d->host = reply->request().url().host();
|
||||
d->sslProtocol = sslConfig.sessionCipher().protocolString();
|
||||
d->cipher = sslConfig.sessionCipher().name();
|
||||
d->usedBits = sslConfig.sessionCipher().usedBits();
|
||||
d->bits = sslConfig.sessionCipher().supportedBits();
|
||||
}
|
||||
''',
|
||||
'''KSslErrorUiData::KSslErrorUiData(const QNetworkReply *reply, const QList<QSslError> &sslErrors)
|
||||
: d(new Private())
|
||||
{
|
||||
d->usedBits = 0;
|
||||
d->bits = 0;
|
||||
(void)reply;
|
||||
(void)sslErrors;
|
||||
}
|
||||
''',
|
||||
)
|
||||
PY
|
||||
|
||||
if ! grep -q '^#include <QHostInfo>$' "${COOKBOOK_SOURCE}/src/core/workerinterface.cpp"; then
|
||||
sed -i '/#include <QDateTime>/a #include <QHostInfo>' "${COOKBOOK_SOURCE}/src/core/workerinterface.cpp"
|
||||
fi
|
||||
|
||||
cat > "${COOKBOOK_SOURCE}/src/core/connectionbackend.cpp" <<'EOF'
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000 Stephan Kulow <coolo@kde.org>
|
||||
SPDX-FileCopyrightText: 2000 David Faure <coolo@kde.org>
|
||||
SPDX-FileCopyrightText: 2007 Thiago Macieira <thiago@kde.org>
|
||||
SPDX-FileCopyrightText: 2024 Harald Sitter <sitter@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "connectionbackend_p.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
using namespace KIO;
|
||||
|
||||
ConnectionBackend::ConnectionBackend(QObject *parent)
|
||||
: QObject(parent)
|
||||
, state(Idle)
|
||||
, socket(nullptr)
|
||||
, localServer(nullptr)
|
||||
, signalEmitted(false)
|
||||
{
|
||||
}
|
||||
|
||||
ConnectionBackend::~ConnectionBackend() = default;
|
||||
|
||||
void ConnectionBackend::setSuspended(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
bool ConnectionBackend::connectToRemote(const QUrl &url)
|
||||
{
|
||||
(void)url;
|
||||
errorString = i18n("Local IPC is unavailable on Redox without QtNetwork");
|
||||
state = Idle;
|
||||
return false;
|
||||
}
|
||||
|
||||
ConnectionBackend::ConnectionResult ConnectionBackend::listenForRemote()
|
||||
{
|
||||
state = Idle;
|
||||
errorString = i18n("Local IPC is unavailable on Redox without QtNetwork");
|
||||
return {false, errorString};
|
||||
}
|
||||
|
||||
bool ConnectionBackend::waitForIncomingTask(int ms)
|
||||
{
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConnectionBackend::sendCommand(int cmd, const QByteArray &data) const
|
||||
{
|
||||
(void)cmd;
|
||||
(void)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
ConnectionBackend *ConnectionBackend::nextPendingConnection()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ConnectionBackend::socketReadyRead()
|
||||
{
|
||||
}
|
||||
|
||||
void ConnectionBackend::socketDisconnected()
|
||||
{
|
||||
state = Idle;
|
||||
Q_EMIT disconnected();
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
sed -i "s/^ecm_install_po_files_as_qm/#ecm_install_po_files_as_qm/" \
|
||||
"${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true
|
||||
sed -i 's/^ki18n_install(po)/#ki18n_install(po)/' \
|
||||
"${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true
|
||||
sed -i '/find_package(Qt6.*Widgets)/a find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)' \
|
||||
"${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true
|
||||
sed -i '/include(ECMQmlModule)/s/^/#/' "${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true
|
||||
|
||||
rm -f CMakeCache.txt
|
||||
rm -rf CMakeFiles
|
||||
|
||||
|
||||
@@ -183,6 +183,10 @@ target_include_directories(KF6KIOCore PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/..>" # kio_version.h
|
||||
)
|
||||
|
||||
target_include_directories(KF6KIOCore PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/redox_qtnetwork_compat
|
||||
)
|
||||
|
||||
target_include_directories(KF6KIOCore INTERFACE
|
||||
"$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF}/KIOCore>"
|
||||
"$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF}/KIO>"
|
||||
@@ -327,4 +331,3 @@ install(FILES
|
||||
|
||||
# make available to ecm_add_qch in parent folder
|
||||
set(KIOCore_QCH_SOURCES ${KIOCore_HEADERS} ${KIO_namespaced_HEADERS} PARENT_SCOPE)
|
||||
|
||||
|
||||
@@ -133,22 +133,11 @@ public:
|
||||
return m_hostName;
|
||||
}
|
||||
|
||||
int lookupId() const
|
||||
{
|
||||
return m_lookupId;
|
||||
}
|
||||
|
||||
void setLookupId(int id)
|
||||
{
|
||||
m_lookupId = id;
|
||||
}
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(NameLookupThreadRequest)
|
||||
QString m_hostName;
|
||||
QSemaphore m_semaphore;
|
||||
QHostInfo m_hostInfo;
|
||||
int m_lookupId;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -162,30 +151,9 @@ class NameLookUpThreadWorker : public QObject
|
||||
public Q_SLOTS:
|
||||
void lookupHost(const std::shared_ptr<KIO::NameLookupThreadRequest> &request)
|
||||
{
|
||||
const QString hostName = request->hostName();
|
||||
const int lookupId = QHostInfo::lookupHost(hostName, this, SLOT(lookupFinished(QHostInfo)));
|
||||
request->setLookupId(lookupId);
|
||||
m_lookups.insert(lookupId, request);
|
||||
request->setResult(QHostInfo::fromName(request->hostName()));
|
||||
request->semaphore()->release();
|
||||
}
|
||||
|
||||
void abortLookup(const std::shared_ptr<KIO::NameLookupThreadRequest> &request)
|
||||
{
|
||||
QHostInfo::abortHostLookup(request->lookupId());
|
||||
m_lookups.remove(request->lookupId());
|
||||
}
|
||||
|
||||
void lookupFinished(const QHostInfo &hostInfo)
|
||||
{
|
||||
auto it = m_lookups.find(hostInfo.lookupId());
|
||||
if (it != m_lookups.end()) {
|
||||
(*it)->setResult(hostInfo);
|
||||
(*it)->semaphore()->release();
|
||||
m_lookups.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QMap<int, std::shared_ptr<NameLookupThreadRequest>> m_lookups;
|
||||
};
|
||||
|
||||
class NameLookUpThread : public QThread
|
||||
@@ -271,11 +239,6 @@ QHostInfo HostInfo::lookupHost(const QString &hostName, unsigned long timeout)
|
||||
if (!hostInfo.hostName().isEmpty() && hostInfo.error() == QHostInfo::NoError) {
|
||||
HostInfo::cacheLookup(hostInfo); // cache the look up...
|
||||
}
|
||||
} else {
|
||||
auto abortFunc = [worker, request]() {
|
||||
worker->abortLookup(request);
|
||||
};
|
||||
QMetaObject::invokeMethod(worker, abortFunc, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
// qDebug() << "Name look up succeeded for" << hostName;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDataStream>
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
class QHostAddress
|
||||
{
|
||||
public:
|
||||
enum NetworkLayerProtocol {
|
||||
UnknownNetworkLayerProtocol = -1,
|
||||
AnyIPProtocol,
|
||||
IPv4Protocol,
|
||||
IPv6Protocol,
|
||||
};
|
||||
|
||||
QHostAddress() = default;
|
||||
|
||||
explicit QHostAddress(const QString &address)
|
||||
{
|
||||
setAddress(address);
|
||||
}
|
||||
|
||||
void setAddress(const QString &address)
|
||||
{
|
||||
m_address = address;
|
||||
|
||||
if (address.isEmpty()) {
|
||||
m_protocol = UnknownNetworkLayerProtocol;
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray utf8 = address.toUtf8();
|
||||
unsigned char ipv4[4] = {};
|
||||
unsigned char ipv6[16] = {};
|
||||
|
||||
if (inet_pton(AF_INET, utf8.constData(), ipv4) == 1) {
|
||||
m_protocol = IPv4Protocol;
|
||||
return;
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET6, utf8.constData(), ipv6) == 1) {
|
||||
m_protocol = IPv6Protocol;
|
||||
return;
|
||||
}
|
||||
|
||||
m_protocol = UnknownNetworkLayerProtocol;
|
||||
}
|
||||
|
||||
bool isNull() const
|
||||
{
|
||||
return m_protocol == UnknownNetworkLayerProtocol;
|
||||
}
|
||||
|
||||
QString toString() const
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
NetworkLayerProtocol protocol() const
|
||||
{
|
||||
return m_protocol;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_address;
|
||||
NetworkLayerProtocol m_protocol = UnknownNetworkLayerProtocol;
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &stream, const QHostAddress &address)
|
||||
{
|
||||
stream << address.m_address << static_cast<qint32>(address.m_protocol);
|
||||
return stream;
|
||||
}
|
||||
|
||||
friend QDataStream &operator>>(QDataStream &stream, QHostAddress &address)
|
||||
{
|
||||
qint32 protocol = UnknownNetworkLayerProtocol;
|
||||
stream >> address.m_address >> protocol;
|
||||
address.m_protocol = static_cast<QHostAddress::NetworkLayerProtocol>(protocol);
|
||||
return stream;
|
||||
}
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QHostAddress)
|
||||
@@ -0,0 +1,166 @@
|
||||
#pragma once
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QHostAddress>
|
||||
|
||||
class QHostInfo
|
||||
{
|
||||
public:
|
||||
enum HostInfoError {
|
||||
NoError = 0,
|
||||
HostNotFound = 1,
|
||||
UnknownError = 2,
|
||||
};
|
||||
|
||||
QHostInfo() = default;
|
||||
|
||||
explicit QHostInfo(const QString &hostName)
|
||||
: m_hostName(hostName)
|
||||
{
|
||||
}
|
||||
|
||||
static QString localHostName()
|
||||
{
|
||||
char buffer[256] = {};
|
||||
if (gethostname(buffer, sizeof(buffer)) == 0) {
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
if (buffer[0] != '\0') {
|
||||
return QString::fromUtf8(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
return QStringLiteral("redox");
|
||||
}
|
||||
|
||||
static QHostInfo fromName(const QString &hostName)
|
||||
{
|
||||
QHostInfo info(hostName);
|
||||
|
||||
const QHostAddress literalAddress(hostName);
|
||||
if (!literalAddress.isNull()) {
|
||||
info.setAddresses({literalAddress});
|
||||
info.setError(NoError);
|
||||
info.setErrorString(QString());
|
||||
return info;
|
||||
}
|
||||
|
||||
addrinfo hints = {};
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
addrinfo *results = nullptr;
|
||||
const QByteArray hostNameUtf8 = hostName.toUtf8();
|
||||
const int lookupResult = getaddrinfo(hostNameUtf8.constData(), nullptr, &hints, &results);
|
||||
|
||||
if (lookupResult != 0) {
|
||||
info.setError(lookupResult == EAI_NONAME ? HostNotFound : UnknownError);
|
||||
info.setErrorString(QString::fromUtf8(gai_strerror(lookupResult)));
|
||||
return info;
|
||||
}
|
||||
|
||||
QList<QHostAddress> addresses;
|
||||
QStringList seenAddresses;
|
||||
|
||||
for (const addrinfo *entry = results; entry != nullptr; entry = entry->ai_next) {
|
||||
const void *rawAddress = nullptr;
|
||||
int family = AF_UNSPEC;
|
||||
|
||||
switch (entry->ai_family) {
|
||||
case AF_INET:
|
||||
rawAddress = &reinterpret_cast<const sockaddr_in *>(entry->ai_addr)->sin_addr;
|
||||
family = AF_INET;
|
||||
break;
|
||||
case AF_INET6:
|
||||
rawAddress = &reinterpret_cast<const sockaddr_in6 *>(entry->ai_addr)->sin6_addr;
|
||||
family = AF_INET6;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
char buffer[INET6_ADDRSTRLEN] = {};
|
||||
if (inet_ntop(family, rawAddress, buffer, sizeof(buffer)) == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const QString addressText = QString::fromUtf8(buffer);
|
||||
if (addressText.isEmpty() || seenAddresses.contains(addressText)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
seenAddresses.append(addressText);
|
||||
addresses.append(QHostAddress(addressText));
|
||||
}
|
||||
|
||||
freeaddrinfo(results);
|
||||
|
||||
if (addresses.isEmpty()) {
|
||||
info.setError(HostNotFound);
|
||||
info.setErrorString(QStringLiteral("Host lookup returned no usable addresses"));
|
||||
return info;
|
||||
}
|
||||
|
||||
info.setAddresses(addresses);
|
||||
info.setError(NoError);
|
||||
info.setErrorString(QString());
|
||||
return info;
|
||||
}
|
||||
|
||||
void setHostName(const QString &hostName)
|
||||
{
|
||||
m_hostName = hostName;
|
||||
}
|
||||
|
||||
QString hostName() const
|
||||
{
|
||||
return m_hostName;
|
||||
}
|
||||
|
||||
void setAddresses(const QList<QHostAddress> &addresses)
|
||||
{
|
||||
m_addresses = addresses;
|
||||
}
|
||||
|
||||
QList<QHostAddress> addresses() const
|
||||
{
|
||||
return m_addresses;
|
||||
}
|
||||
|
||||
void setError(HostInfoError error)
|
||||
{
|
||||
m_error = error;
|
||||
}
|
||||
|
||||
HostInfoError error() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
void setErrorString(const QString &errorString)
|
||||
{
|
||||
m_errorString = errorString;
|
||||
}
|
||||
|
||||
QString errorString() const
|
||||
{
|
||||
return m_errorString;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_hostName;
|
||||
QList<QHostAddress> m_addresses;
|
||||
HostInfoError m_error = UnknownError;
|
||||
QString m_errorString;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QHostInfo)
|
||||
@@ -9,103 +9,8 @@
|
||||
|
||||
#include "commands_p.h"
|
||||
#include "connection_p.h"
|
||||
#include "hostinfo.h"
|
||||
#include "kiocoredebug.h"
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <QHostInfo>
|
||||
#include "usernotificationhandler_p.h"
|
||||
#include "workerbase.h"
|
||||
|
||||
@@ -113,6 +18,7 @@
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDateTime>
|
||||
#include <QHostInfo>
|
||||
|
||||
using namespace KIO;
|
||||
|
||||
@@ -364,9 +270,12 @@ bool WorkerInterface::dispatch(int _cmd, const QByteArray &rawdata)
|
||||
case MSG_HOST_INFO_REQ: {
|
||||
QString hostName;
|
||||
stream >> hostName;
|
||||
|
||||
const QHostInfo info = HostInfo::lookupHost(hostName, 1500);
|
||||
|
||||
QByteArray replyData;
|
||||
QDataStream replyStream(&replyData, QIODevice::WriteOnly);
|
||||
replyStream << hostName << QList<QHostAddress>() << int(QHostInfo::UnknownError) << QStringLiteral("Host lookup unavailable on Redox");
|
||||
replyStream << info.hostName() << info.addresses() << int(info.error()) << info.errorString();
|
||||
m_connection->send(CMD_HOST_INFO, replyData);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user