Paste P266

Masterwork From Distant Lands
ActivePublic

Authored by sitter on Oct 12 2018, 2:40 PM.
From e9fa39a9b4d11654dfbc2271c75f3a883c2b4ac8 Mon Sep 17 00:00:00 2001
From: Harald Sitter <sitter@kde.org>
Date: Fri, 12 Oct 2018 16:39:18 +0200
Subject: [PATCH] fallback to dnssd service discovery if smb listing failed
---
smb/CMakeLists.txt | 14 +++++++--
smb/kio_smb_browse.cpp | 65 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 74 insertions(+), 5 deletions(-)
diff --git a/smb/CMakeLists.txt b/smb/CMakeLists.txt
index e5526720..f61b6356 100644
--- a/smb/CMakeLists.txt
+++ b/smb/CMakeLists.txt
@@ -23,14 +23,24 @@ include_directories(${SAMBA_INCLUDE_DIR})
add_library(kio_smb MODULE ${kio_smb_PART_SRCS})
-target_link_libraries(kio_smb KF5::KIOCore KF5::I18n ${SAMBA_LIBRARIES} Qt5::Network)
+target_link_libraries(kio_smb
+ KF5::KIOCore
+ KF5::I18n
+ ${SAMBA_LIBRARIES}
+ Qt5::Network
+ KF5::DNSSD)
else()
set(kio_smb_PART_SRCS
kio_smb_win.cpp)
add_library(kio_smb MODULE ${kio_smb_PART_SRCS})
-target_link_libraries(kio_smb KF5::KIOCore KF5::I18n mpr Qt5::Network)
+target_link_libraries(kio_smb
+ KF5::KIOCore
+ KF5::I18n
+ mpr
+ Qt5::Network
+ KF5::DNSSD)
endif()
set_target_properties(kio_smb PROPERTIES OUTPUT_NAME "smb")
diff --git a/smb/kio_smb_browse.cpp b/smb/kio_smb_browse.cpp
index 1fa0e6fb..a0dbbe2c 100644
--- a/smb/kio_smb_browse.cpp
+++ b/smb/kio_smb_browse.cpp
@@ -13,6 +13,7 @@
//---------------------------------------------------------------------------
//
// Copyright (c) 2000 Caldera Systems, Inc.
+// Copyright (c) 2018 Harald Sitter <sitter@kde.org>
//
// 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
@@ -30,14 +31,19 @@
//
/////////////////////////////////////////////////////////////////////////////
-#include <pwd.h>
-#include <grp.h>
-
#include "kio_smb.h"
#include "kio_smb_internal.h"
+
+#include <DNSSD/ServiceBrowser>
+#include <DNSSD/RemoteService>
#include <KLocalizedString>
#include <KIO/Job>
+#include <QEventLoop>
+
+#include <pwd.h>
+#include <grp.h>
+
using namespace KIO;
int SMBSlave::cache_stat(const SMBUrl &url, struct stat* st )
@@ -328,12 +334,15 @@ void SMBSlave::listDir( const QUrl& kurl )
qCDebug(KIO_SMB) << "open " << m_current_url.toSmbcUrl() << " " << m_current_url.getType() << " " << dirfd;
if(dirfd >= 0)
{
+ uint direntCount = 0;
do {
qCDebug(KIO_SMB) << "smbc_readdir ";
dirp = smbc_readdir(dirfd);
if(dirp == 0)
break;
+ ++direntCount;
+
// Set name
QString udsName;
const QString dirpName = QString::fromUtf8( dirp->name );
@@ -445,6 +454,56 @@ void SMBSlave::listDir( const QUrl& kurl )
udsentry.clear();
} while (dirp); // checked already in the head
+ // FIXME: possibly should construct urls or structs? or qhash it?
+ // one hostName may have multiple services on different ports!
+ // should we create multiple UDS entries?
+ // FIXME: no way to determine workgroups?
+ QStringList hosts;
+ auto normalizedUrl = url.adjusted(QUrl::NormalizePathSegments);
+ if (direntCount <= 0 && normalizedUrl.path().isEmpty()) {
+ // Slaves have no event loop, start one for the poll.
+ // KDNSSD has an internal timeout which will trigger.
+ // Bit shitty. Possibly should use the mollet thing of the network: slave
+ QEventLoop e;
+ KDNSSD::ServiceBrowser* browser = new KDNSSD::ServiceBrowser("_smb._tcp");
+ connect(browser, &KDNSSD::ServiceBrowser::serviceAdded,
+ this, [&hosts](KDNSSD::RemoteService::Ptr service){
+ qDebug() << "ADDED" << service->serviceName() << service->type() << service->domain() << service->hostName() << service->port();
+ auto addr = service->serviceName() + "." + service->domain();
+ if (hosts.contains(addr)) {
+ return;
+ }
+ hosts.append(addr);
+ });
+ connect(browser, &KDNSSD::ServiceBrowser::serviceRemoved,
+ this, [&hosts](KDNSSD::RemoteService::Ptr service){
+ qDebug() << "REMOVED" << service->serviceName() << service->type() << service->domain() << service->hostName() << service->port();
+ hosts.removeAll(service->serviceName() + "." + service->domain());
+ });
+ connect(browser, &KDNSSD::ServiceBrowser::finished,
+ &e, &QEventLoop::quit);
+ browser->startBrowse();
+ e.exec();
+
+ for (auto host : hosts) {
+ // FIXME: Should be servicename rather than host address maybe?
+ udsentry.insert( KIO::UDSEntry::UDS_NAME, host);
+
+ udsentry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
+ udsentry.insert(KIO::UDSEntry::UDS_ACCESS, (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH));
+
+ QUrl u("smb://");
+ u.setHost(host);
+
+ qCDebug(KIO_SMB) << "list item " << u << "--" << host;
+ udsentry.insert(KIO::UDSEntry::UDS_URL, u.url());
+ udsentry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QString::fromLatin1("application/x-smb-server"));
+
+ listEntry(udsentry);
+ udsentry.clear();
+ }
+ }
+
if (dir_is_root) {
udsentry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
udsentry.insert(KIO::UDSEntry::UDS_NAME, ".");
--
2.17.1
sitter edited the content of this paste. (Show Details)Oct 12 2018, 2:40 PM
sitter changed the title of this paste from untitled to Masterwork From Distant Lands.