generic: reimplement kdnssd library

works as expected, services queries include two for IPv4 and one for
the advertised IPv6 address which have to be filtered:
https://ibb.co/4VpJK9V

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-05-05 16:35:55 +03:00
parent 4011699ace
commit 6af9b55738
71 changed files with 577 additions and 5159 deletions

View file

@ -133,17 +133,9 @@ set_package_properties(ACL
macro_optional_find_package(Avahi)
set_package_properties(Avahi PROPERTIES
DESCRIPTION "Facilities for service discovery on a local network (DNSSD)"
URL "http://avahi.org"
URL "https://avahi.org/"
TYPE OPTIONAL
PURPOSE "Either Avahi or DNSSD is required for KDE applications to make use of multicast DNS/DNS-SD service discovery"
)
macro_optional_find_package(DNSSD)
set_package_properties(DNSSD PROPERTIES
DESCRIPTION "Facilities for service discovery on a local network"
URL "http://avahi.org"
TYPE OPTIONAL
PURPOSE "Either Avahi or DNSSD is required for KDE applications to make use of multicast DNS/DNS-SD service discovery"
PURPOSE "Avahi is required for KDE applications to make use of multicast DNS/DNS-SD service discovery"
)
macro_optional_find_package(BZip2)
@ -359,7 +351,6 @@ set(KDE4_KPARTS_INCLUDES
add_subdirectory( cmake )
add_subdirectory( dnssd )
add_subdirectory( includes )
add_subdirectory( interfaces )
add_subdirectory( kdeclarative )

View file

@ -9,7 +9,6 @@ set(cmakeFilesDontInstall
FindMPV.cmake
FindUDev.cmake
FindAvahi.cmake
FindDNSSD.cmake
FindENCHANT.cmake
FindACL.cmake
FindLibCDIO.cmake

View file

@ -1,19 +1,40 @@
# Try to find the Avahi, once done this will define:
# Try to find Avahi library, once done this will define:
#
# AVAHI_FOUND - system has Avahi
# AVAHI_INCLUDE_DIR - the Avahi include directory
# AVAHI_LIBRARIES - the libraries needed to use Avahi
#
# Copyright (c) 2020 Ivailo Monev <xakepa10@gmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
find_path(AVAHI_INCLUDE_DIR
NAMES avahi-common/defs.h
HINTS $ENV{AVAHIDIR}/include
)
if(NOT WIN32)
include(FindPkgConfig)
pkg_check_modules(PC_AVAHI QUIET avahi-client)
set(AVAHI_INCLUDE_DIR ${PC_AVAHI_INCLUDE_DIRS})
set(AVAHI_LIBRARIES ${PC_AVAHI_LIBRARIES})
endif()
set(AVAHI_VERSION ${PC_AVAHI_VERSION})
if(NOT AVAHI_INCLUDE_DIR OR NOT AVAHI_LIBRARIES)
find_path(AVAHI_INCLUDE_DIR
NAMES avahi-client/client.h
HINTS $ENV{AVAHIDIR}/include
)
find_library(AVAHI_LIBRARIES
NAMES avahi-client
HINTS $ENV{AVAHIDIR}/lib
)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Avahi
REQUIRED_VARS AVAHI_INCLUDE_DIR
VERSION_VAR AVAHI_VERSION
REQUIRED_VARS AVAHI_LIBRARIES AVAHI_INCLUDE_DIR
)
mark_as_advanced(AVAHI_INCLUDE_DIR AVAHI_LIBRARIES)

View file

@ -1,46 +0,0 @@
# Try to find DNSSD, once done this will define:
#
# DNSSD_FOUND - system has DNSSD
# DNSSD_INCLUDE_DIR - the DNSSD include directory
# DNSSD_LIBRARIES - Link these to use dnssd
# DNSSD_DEFINITIONS - Compiler switches required for using DNSSD
#
# need more test: look at into dnssd/configure.in.in
# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
include(CMakePushCheckState)
find_path(DNSSD_INCLUDE_DIR
NAMES dns_sd.h
PATH_SUFFIXES avahi-compat-libdns_sd
)
if(DNSSD_INCLUDE_DIR)
find_library(DNSSD_LIBRARIES NAMES dns_sd)
cmake_reset_check_state()
set(CMAKE_REQUIRED_INCLUDES ${DNSSD_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${DNSSD_LIBRARIES})
CHECK_FUNCTION_EXISTS(DNSServiceRefDeallocate DNSSD_FUNCTION_FOUND)
cmake_reset_check_state()
if(DNSSD_INCLUDE_DIR AND DNSSD_LIBRARIES AND DNSSD_FUNCTION_FOUND)
set(DNSSD_FOUND TRUE)
endif()
endif()
if(DNSSD_FOUND)
if (NOT DNSSD_FIND_QUIETLY)
message(STATUS "Found DNSSD: ${DNSSD_LIBRARIES}")
endif()
else()
if(DNSSD_FIND_REQUIRED)
message(FATAL_ERROR "Could NOT find DNSSD")
endif()
endif()
MARK_AS_ADVANCED(DNSSD_INCLUDE_DIR DNSSD_LIBRARIES)

View file

@ -51,7 +51,6 @@
# KDE4_KIDLETIME_LIBS - the kidletime library and all depending libraries
# KDE4_KCMUTILS_LIBS - the kcmutils library and all depending libraries
# KDE4_KFILE_LIBS - the kfile library and all depending libraries
# KDE4_KDNSSD_LIBS - the kdnssd library and all depending libraries
# KDE4_KPTY_LIBS - the kpty library and all depending libraries
# KDE4_SOLID_LIBS - the solid library and all depending libraries
# KDE4_KNOTIFYCONFIG_LIBS - the knotify config library and all depending libraries
@ -61,6 +60,7 @@
# KDE4_KMEDIAPLAYER_LIBS - the kmediaplayer library and all depending libraries
# KDE4_KPASSWDSTORE_LIBS - the kpasswdstore library and all depending libraries
# KDE4_KPOWERMANAGER_LIBS - the kpowermanager library and all depending libraries
# KDE4_KDNSSD_LIBS - the kdnssd library and all depending libraries
#
# The variable INSTALL_TARGETS_DEFAULT_ARGS can be used when installing libraries
# or executables into the default locations.
@ -284,10 +284,10 @@ set(_kde_libraries
kdeclarative
kdecore
kdeui
kdnssd
kexiv2
kpasswdstore
kpowermanager
kdnssd
kfile
kidletime
kio

View file

@ -1,110 +0,0 @@
project(dnssd)
include_directories( ${KDE4_KDECORE_INCLUDES} )
set(kdnssd_LIB_SRCS
servicebase.cpp
servicemodel.cpp
domainmodel.cpp
)
kde4_add_kcfg_files(kdnssd_LIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/settings.kcfgc)
if(AVAHI_FOUND)
include_directories( ${AVAHI_INCLUDE_DIR} )
set(kdnssd_LIB_SRCS ${kdnssd_LIB_SRCS}
avahi-domainbrowser.cpp
avahi-servicebrowser.cpp
avahi-remoteservice.cpp
avahi-publicservice.cpp
avahi-servicetypebrowser.cpp
avahi_server_interface.cpp
avahi_serviceresolver_interface.cpp
avahi_entrygroup_interface.cpp
)
qt4_add_dbus_interface(
kdnssd_LIB_SRCS
org.freedesktop.Avahi.DomainBrowser.xml
avahi_domainbrowser_interface
)
qt4_add_dbus_interface(
kdnssd_LIB_SRCS
org.freedesktop.Avahi.ServiceBrowser.xml
avahi_servicebrowser_interface
)
qt4_add_dbus_interface(
kdnssd_LIB_SRCS
org.freedesktop.Avahi.ServiceTypeBrowser.xml
avahi_servicetypebrowser_interface
)
elseif(DNSSD_FOUND)
include_directories( ${DNSSD_INCLUDE_DIR} )
set(kdnssd_LIB_SRCS ${kdnssd_LIB_SRCS}
mdnsd-domainbrowser.cpp
mdnsd-remoteservice.cpp
mdnsd-publicservice.cpp
mdnsd-responder.cpp
mdnsd-servicebrowser.cpp
mdnsd-servicetypebrowser.cpp
)
else()
set(kdnssd_LIB_SRCS ${kdnssd_LIB_SRCS}
dummy-domainbrowser.cpp
dummy-remoteservice.cpp
dummy-publicservice.cpp
dummy-servicebrowser.cpp
dummy-servicetypebrowser.cpp
)
endif()
########### next target ###############
add_library(kdnssd ${LIBRARY_TYPE} ${kdnssd_LIB_SRCS})
target_link_libraries(kdnssd PRIVATE
${KDE4_KDECORE_LIBS}
${QT_QTNETWORK_LIBRARY}
)
if(DNSSD_FOUND)
target_link_libraries(kdnssd PRIVATE
${DNSSD_LIBRARIES}
)
endif()
target_link_libraries(kdnssd PUBLIC kdecore ${QT_QTCORE_LIBRARY} )
set_target_properties(kdnssd PROPERTIES
VERSION ${GENERIC_LIB_VERSION}
SOVERSION ${GENERIC_LIB_SOVERSION}
)
install(
TARGETS kdnssd
EXPORT kdelibsLibraryTargets
${INSTALL_TARGETS_DEFAULT_ARGS}
)
########### install files ###############
generate_export_header(kdnssd)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/kdnssd_export.h
domainbrowser.h
remoteservice.h
servicetypebrowser.h
publicservice.h
servicebase.h
servicebrowser.h
servicemodel.h
domainmodel.h
${CMAKE_CURRENT_BINARY_DIR}/settings.h
DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/dnssd
COMPONENT Devel
)

View file

@ -1,3 +0,0 @@
If you package kdnssd with Avahi support (default on Linux) make sure that NSS
module for mdns is also a dependency. Without nss-mdns working, users will be
able to see remote services but trying to access them will fail.

View file

@ -1,107 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "avahi-domainbrowser_p.h"
#include <QtCore/QSet>
#include <QtCore/QFile>
#include <QtCore/QIODevice>
#include <kstandarddirs.h>
#include <avahi-common/defs.h>
#include "avahi_server_interface.h"
#include "domainbrowser.h"
#include "avahi_domainbrowser_interface.h"
Q_DECLARE_METATYPE(QList<QByteArray>)
namespace DNSSD
{
DomainBrowser::DomainBrowser(DomainType type, QObject *parent) : QObject(parent), d(new DomainBrowserPrivate(type,this))
{}
DomainBrowser::~DomainBrowser()
{
delete d;
}
void DomainBrowser::startBrowse()
{
if (d->m_started) return;
d->m_started=true;
org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
QDBusReply<QDBusObjectPath> rep=s.DomainBrowserNew(-1, -1, "", (d->m_type==Browsing) ?
AVAHI_DOMAIN_BROWSER_BROWSE : AVAHI_DOMAIN_BROWSER_REGISTER,0);
if (!rep.isValid()) return;
org::freedesktop::Avahi::DomainBrowser *b=new org::freedesktop::Avahi::DomainBrowser("org.freedesktop.Avahi",rep.value().path(),
QDBusConnection::systemBus());
connect(b,SIGNAL(ItemNew(int,int,QString,uint)),d, SLOT(gotNewDomain(int,int,QString,uint)));
connect(b,SIGNAL(ItemRemove(int,int,QString,uint)),d, SLOT(gotRemoveDomain(int,int,QString,uint)));
d->m_browser=b;
if (d->m_type==Browsing) {
QString domains_evar=qgetenv("AVAHI_BROWSE_DOMAINS");
if (!domains_evar.isEmpty()) {
QStringList edomains=domains_evar.split(':');
Q_FOREACH(const QString &s, edomains) d->gotNewDomain(-1,-1,s,0);
}
KStandardDirs dirs;
//FIXME: watch this file and restart browser if it changes
QFile domains_cfg(dirs.localxdgconfdir()+"/avahi/browse-domains");
if (domains_cfg.open(QIODevice::ReadOnly | QIODevice::Text))
while (!domains_cfg.atEnd()) d->gotNewDomain(-1,-1,QString::fromUtf8(domains_cfg.readLine().data()).trimmed(),0);
}
}
void DomainBrowserPrivate::gotNewDomain(int,int,const QString& domain,uint)
{
QString decoded=DNSToDomain(domain);
if (m_domains.contains(decoded)) return;
m_domains+=decoded;
emit m_parent->domainAdded(decoded);
}
void DomainBrowserPrivate::gotRemoveDomain(int,int,const QString& domain,uint)
{
QString decoded=DNSToDomain(domain);
if (!m_domains.contains(decoded)) return;
emit m_parent->domainRemoved(decoded);
m_domains.remove(decoded);
}
QStringList DomainBrowser::domains() const
{
return d->m_domains.values();
}
bool DomainBrowser::isRunning() const
{
return d->m_started;
}
}
#include "moc_domainbrowser.cpp"
#include "moc_avahi-domainbrowser_p.cpp"

View file

@ -1,50 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef AVAHI_DOMAINBROWSER_P_H
#define AVAHI_DOMAINBROWSER_P_H
#include <QtCore/QSet>
#include "domainbrowser.h"
#include "avahi_domainbrowser_interface.h"
namespace DNSSD
{
class DomainBrowserPrivate : public QObject
{
Q_OBJECT
public:
DomainBrowserPrivate(DomainBrowser::DomainType type, DomainBrowser* parent) : m_type(type), m_browser(0), m_parent(parent),m_started(false) {}
~DomainBrowserPrivate() { if (m_browser) m_browser->Free(); }
DomainBrowser::DomainType m_type;
org::freedesktop::Avahi::DomainBrowser* m_browser;
DomainBrowser* m_parent;
bool m_started;
QSet<QString> m_domains;
public Q_SLOTS:
void gotNewDomain(int,int,const QString&, uint);
void gotRemoveDomain(int,int,const QString&, uint);
};
}
#endif

View file

@ -1,257 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "avahi-publicservice_p.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include "publicservice.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include "servicebrowser.h"
#include "settings.h"
#include "avahi_server_interface.h"
#include "avahi_entrygroup_interface.h"
Q_DECLARE_METATYPE(QList<QByteArray>)
namespace DNSSD
{
PublicService::PublicService(const QString& name, const QString& type, unsigned int port,
const QString& domain, const QStringList& subtypes)
: QObject(), ServiceBase(new PublicServicePrivate(this, name, type, domain, port))
{
K_D;
if (domain.isNull()) d->m_domain="local.";
d->m_subtypes=subtypes;
}
PublicService::~PublicService()
{
stop();
}
void PublicServicePrivate::tryApply()
{
if (fillEntryGroup()) commit();
else {
m_parent->stop();
emit m_parent->published(false);
}
}
void PublicService::setServiceName(const QString& serviceName)
{
K_D;
d->m_serviceName = serviceName;
if (d->m_running) {
d->m_group->Reset();
d->tryApply();
}
}
void PublicService::setDomain(const QString& domain)
{
K_D;
d->m_domain = domain;
if (d->m_running) {
d->m_group->Reset();
d->tryApply();
}
}
void PublicService::setType(const QString& type)
{
K_D;
d->m_type = type;
if (d->m_running) {
d->m_group->Reset();
d->tryApply();
}
}
void PublicService::setSubTypes(const QStringList& subtypes)
{
K_D;
d->m_subtypes = subtypes;
if (d->m_running) {
d->m_group->Reset();
d->tryApply();
}
}
QStringList PublicService::subtypes() const
{
K_D;
return d->m_subtypes;
}
void PublicService::setPort(unsigned short port)
{
K_D;
d->m_port = port;
if (d->m_running) {
d->m_group->Reset();
d->tryApply();
}
}
void PublicService::setTextData(const QMap<QString,QByteArray>& textData)
{
K_D;
d->m_textData = textData;
if (d->m_running) {
d->m_group->Reset();
d->tryApply();
}
}
bool PublicService::isPublished() const
{
K_D;
return d->m_published;
}
bool PublicService::publish()
{
K_D;
publishAsync();
while (d->m_running && !d->m_published) QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
return d->m_published;
}
void PublicService::stop()
{
K_D;
if (d->m_group) d->m_group->Reset();
d->m_running = false;
d->m_published = false;
}
bool PublicServicePrivate::fillEntryGroup()
{
registerTypes();
if (!m_group) {
QDBusReply<QDBusObjectPath> rep=m_server->EntryGroupNew();
if (!rep.isValid()) return false;
m_group=new org::freedesktop::Avahi::EntryGroup("org.freedesktop.Avahi",rep.value().path(), QDBusConnection::systemBus());
connect(m_group,SIGNAL(StateChanged(int,QString)), this, SLOT(groupStateChanged(int,QString)));
}
if (m_serviceName.isNull()) {
QDBusReply<QString> rep=m_server->GetHostName();
if (!rep.isValid()) return false;
m_serviceName=rep.value();
}
QList<QByteArray> txt;
QMap<QString,QByteArray>::ConstIterator itEnd = m_textData.constEnd();
for (QMap<QString,QByteArray>::ConstIterator it = m_textData.constBegin(); it!=itEnd ; ++it)
if (it.value().isNull()) txt.append(it.key().toLatin1());
else txt.append(it.key().toLatin1()+'='+it.value());
for (;;) {
QDBusReply<void> ret = m_group->AddService(-1,-1, 0, m_serviceName, m_type , domainToDNS(m_domain) ,
m_hostName, m_port,txt);
if (ret.isValid()) break;
// serious error, bail out
if (ret.error().name()!=QLatin1String("org.freedesktop.Avahi.CollisionError")) return false;
// name collision, try another
QDBusReply<QString> rep=m_server->GetAlternativeServiceName(m_serviceName);
if (rep.isValid()) m_serviceName = rep.value();
else return false;
}
Q_FOREACH(const QString &subtype, m_subtypes)
m_group->AddServiceSubtype(-1,-1, 0, m_serviceName, m_type, domainToDNS(m_domain) , subtype);
return true;
}
void PublicServicePrivate::serverStateChanged(int s,const QString&)
{
if (!m_running) return;
switch (s) {
case AVAHI_SERVER_INVALID:
m_parent->stop();
emit m_parent->published(false);
break;
case AVAHI_SERVER_REGISTERING:
case AVAHI_SERVER_COLLISION:
if (m_group) m_group->Reset();
m_collision=true;
break;
case AVAHI_SERVER_RUNNING:
if (m_collision) {
m_collision=false;
tryApply();
}
}
}
void PublicService::publishAsync()
{
K_D;
if (d->m_running) stop();
if (!d->m_server) {
d->m_server = new org::freedesktop::Avahi::Server("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
connect(d->m_server,SIGNAL(StateChanged(int,QString)),d,SLOT(serverStateChanged(int,QString)));
}
int state=AVAHI_SERVER_INVALID;
QDBusReply<int> rep=d->m_server->GetState();
if (rep.isValid()) state=rep.value();
d->m_running=true;
d->m_collision=true; // make it look like server is getting out of collision to force registering
d->serverStateChanged(state, QString());
}
void PublicServicePrivate::groupStateChanged(int s, const QString& reason)
{
switch (s) {
case AVAHI_ENTRY_GROUP_COLLISION: {
QDBusReply<QString> rep=m_server->GetAlternativeServiceName(m_serviceName);
if (rep.isValid()) m_parent->setServiceName(rep.value());
else serverStateChanged(AVAHI_SERVER_INVALID, reason);
break;
}
case AVAHI_ENTRY_GROUP_ESTABLISHED:
m_published=true;
emit m_parent->published(true);
break;
case AVAHI_ENTRY_GROUP_FAILURE:
serverStateChanged(AVAHI_SERVER_INVALID, reason);
default:
break;
}
}
}
#include "moc_publicservice.cpp"
#include "moc_avahi-publicservice_p.cpp"

View file

@ -1,73 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef AVAHI_PUBLICSERVICE_P_H
#define AVAHI_PUBLICSERVICE_P_H
#include <QtCore/QStringList>
#include "servicebase_p.h"
#include <avahi-common/defs.h>
#include "publicservice.h"
#include "avahi_server_interface.h"
#include "avahi_entrygroup_interface.h"
#define K_D PublicServicePrivate* d=static_cast<PublicServicePrivate*>(this->d)
namespace DNSSD
{
class PublicServicePrivate : public QObject, public ServiceBasePrivate
{
Q_OBJECT
public:
PublicServicePrivate(PublicService* parent, const QString& name, const QString& type, const QString& domain, unsigned int port) :
QObject(), ServiceBasePrivate(name, type, domain, QString(), port), m_published(false), m_running(false), m_group(0),
m_server(0), m_collision(false), m_parent(parent)
{}
~PublicServicePrivate() {
if (m_group) m_group->Free();
delete m_group;
delete m_server;
}
bool m_published;
bool m_running;
org::freedesktop::Avahi::EntryGroup* m_group;
org::freedesktop::Avahi::Server* m_server;
bool m_collision;
QStringList m_subtypes;
PublicService* m_parent;
void commit()
{
if (!m_collision) m_group->Commit();
}
void stop();
bool fillEntryGroup();
void tryApply();
public Q_SLOTS:
void serverStateChanged(int,const QString&);
void groupStateChanged(int,const QString&);
};
}
#endif

View file

@ -1,117 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "avahi-remoteservice_p.h"
#include <netinet/in.h>
#include <QtCore/QEventLoop>
#include <QtCore/QCoreApplication>
#include <kdebug.h>
#include "remoteservice.h"
#include "avahi_server_interface.h"
#include "avahi_serviceresolver_interface.h"
Q_DECLARE_METATYPE(QList<QByteArray>)
namespace DNSSD
{
RemoteService::RemoteService(const QString& name,const QString& type,const QString& domain)
: ServiceBase(new RemoteServicePrivate(this, name,type,domain))
{
}
RemoteService::~RemoteService()
{
}
bool RemoteService::resolve()
{
K_D;
resolveAsync();
while (d->m_running && !d->m_resolved) QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
return d->m_resolved;
}
void RemoteService::resolveAsync()
{
K_D;
if (d->m_running) return;
d->m_resolved = false;
registerTypes();
kDebug() << this << ":Starting resolve of : " << d->m_serviceName << " " << d->m_type << " " << d->m_domain << "\n";
org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
//FIXME: don't use LOOKUP_NO_ADDRESS if NSS unavailable
QDBusReply<QDBusObjectPath> rep=s.ServiceResolverNew(-1, -1, d->m_serviceName, d->m_type,
domainToDNS(d->m_domain), -1, 8 /*AVAHI_LOOKUP_NO_ADDRESS*/);
if (!rep.isValid()) {
emit resolved(false);
return;
}
org::freedesktop::Avahi::ServiceResolver *b=new org::freedesktop::Avahi::ServiceResolver("org.freedesktop.Avahi",rep.value().path(),
QDBusConnection::systemBus());
connect(b,SIGNAL(Found(int,int,const QString &,const QString &,const QString &,const QString &, int, const QString &,ushort,
const QList<QByteArray>&, uint)),d, SLOT(gotFound(int,int,const QString &,const QString &,const QString &,const QString &,
int, const QString &,ushort , const QList<QByteArray>&, uint)));
connect(b,SIGNAL(Failure(QString)),d, SLOT(gotError()));
d->m_running=true;
}
bool RemoteService::isResolved() const
{
K_D;
return d->m_resolved;
}
void RemoteServicePrivate::gotError()
{
m_resolved=false;
stop();
emit m_parent->resolved(false);
}
void RemoteServicePrivate::gotFound(int, int, const QString &name, const QString &, const QString &domain, const QString &host, int, const QString &, ushort port, const QList<QByteArray> &txt, uint)
{
m_serviceName = name;
m_hostName = host;
m_port = port;
m_domain=DNSToDomain(domain);
Q_FOREACH(const QByteArray &x, txt) {
int pos=x.indexOf("=");
if (pos==-1) m_textData[x]=QByteArray();
else m_textData[x.mid(0,pos)]=x.mid(pos+1,x.size()-pos);
}
m_resolved = true;
emit m_parent->resolved(true);
}
void RemoteServicePrivate::stop()
{
if (m_resolver) m_resolver->Free();
delete m_resolver;
m_resolver=0;
m_running=false;
}
}
#include "moc_remoteservice.cpp"
#include "moc_avahi-remoteservice_p.cpp"

View file

@ -1,58 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef AVAHI_REMOTESERVICE_P_H
#define AVAHI_REMOTESERVICE_P_H
#include <QtCore/QString>
#include <QtCore/QList>
#include <QtCore/QMap>
#include "servicebase_p.h"
#include "remoteservice.h"
#include "avahi_serviceresolver_interface.h"
#define K_D RemoteServicePrivate* d=static_cast<RemoteServicePrivate*>(this->d)
namespace DNSSD
{
class RemoteServicePrivate : public QObject, public ServiceBasePrivate
{
Q_OBJECT
public:
RemoteServicePrivate(RemoteService* parent, const QString& name, const QString& type, const QString& domain) : QObject(),
ServiceBasePrivate(name, type, domain, QString(), 0), m_resolved(false), m_running(false), m_resolver(0), m_parent(parent)
{}
~RemoteServicePrivate() { if (m_resolver) m_resolver->Free(); delete m_resolver; }
bool m_resolved;
bool m_running;
org::freedesktop::Avahi::ServiceResolver* m_resolver;
RemoteService* m_parent;
void stop();
private Q_SLOTS:
void gotFound(int, int, const QString &name, const QString &type, const QString &domain, const QString &host, int aprotocol, const QString &address, ushort port, const QList<QByteArray> &txt, uint flags);
void gotError();
};
}
#endif

View file

@ -1,188 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "avahi-servicebrowser_p.h"
#include <QtCore/QStringList>
#include "servicebrowser.h"
#include "avahi_servicebrowser_interface.h"
#include "avahi_server_interface.h"
#include <QtCore/QHash>
#include <QtNetwork/QHostAddress>
Q_DECLARE_METATYPE(QList<QByteArray>)
namespace DNSSD
{
ServiceBrowser::ServiceBrowser(const QString& type,bool autoResolve,const QString& domain, const QString& subtype)
:d(new ServiceBrowserPrivate(this))
{
d->m_type=type;
d->m_subtype=subtype;
d->m_autoResolve=autoResolve;
d->m_domain=domain;
d->m_timer.setSingleShot(true);
}
ServiceBrowser::State ServiceBrowser::isAvailable()
{
org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
QDBusReply<int> rep= s.GetState();
return (rep.isValid() && rep.value()==2) ? Working:Stopped;
}
ServiceBrowser::~ServiceBrowser()
{
delete d;
}
bool ServiceBrowser::isAutoResolving() const
{
return d->m_autoResolve;
}
void ServiceBrowser::startBrowse()
{
if (d->m_running) return;
org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
QString fullType=d->m_type;
if (!d->m_subtype.isEmpty()) fullType=d->m_subtype+"._sub."+d->m_type;
QDBusReply<QDBusObjectPath> rep=s.ServiceBrowserNew(-1, -1, fullType, domainToDNS(d->m_domain),0);
if (!rep.isValid()) {
emit finished();
return;
}
d->m_running=true;
d->m_browserFinished=true;
org::freedesktop::Avahi::ServiceBrowser *b=new org::freedesktop::Avahi::ServiceBrowser("org.freedesktop.Avahi",rep.value().path(),
QDBusConnection::systemBus());
connect(b,SIGNAL(ItemNew(int,int,QString,QString,QString,uint)),d,
SLOT(gotNewService(int,int,QString,QString,QString,uint)));
connect(b,SIGNAL(ItemRemove(int,int,QString,QString,QString,uint)),d,
SLOT(gotRemoveService(int,int,QString,QString,QString,uint)));
connect(b,SIGNAL(AllForNow()),d,SLOT(browserFinished()));
d->m_browser=b;
connect(&d->m_timer,SIGNAL(timeout()), d, SLOT(browserFinished()));
d->m_timer.start(domainIsLocal(d->m_domain) ? TIMEOUT_LAST_SERVICE : TIMEOUT_START_WAN);
}
void ServiceBrowserPrivate::serviceResolved(bool success)
{
QObject* sender_obj = const_cast<QObject*>(sender());
RemoteService* svr = static_cast<RemoteService*>(sender_obj);
disconnect(svr,SIGNAL(resolved(bool)),this,SLOT(serviceResolved(bool)));
QList<RemoteService::Ptr>::Iterator it = m_duringResolve.begin();
QList<RemoteService::Ptr>::Iterator itEnd = m_duringResolve.end();
while ( it!= itEnd && svr!= (*it).data()) ++it;
if (it != itEnd) {
if (success) {
m_services+=(*it);
emit m_parent->serviceAdded(RemoteService::Ptr(svr));
}
m_duringResolve.erase(it);
queryFinished();
}
}
RemoteService::Ptr ServiceBrowserPrivate::find(RemoteService::Ptr s, const QList<RemoteService::Ptr>& where) const
{
Q_FOREACH (const RemoteService::Ptr& i, where) if (*s==*i) return i;
return RemoteService::Ptr();
}
void ServiceBrowserPrivate::gotNewService(int,int,const QString& name, const QString& type, const QString& domain, uint)
{
m_timer.start(TIMEOUT_LAST_SERVICE);
RemoteService::Ptr svr(new RemoteService(name, type,domain));
if (m_autoResolve) {
connect(svr.data(),SIGNAL(resolved(bool)),this,SLOT(serviceResolved(bool)));
m_duringResolve+=svr;
svr->resolveAsync();
} else {
m_services+=svr;
emit m_parent->serviceAdded(svr);
}
}
void ServiceBrowserPrivate::gotRemoveService(int,int,const QString& name, const QString& type, const QString& domain, uint)
{
m_timer.start(TIMEOUT_LAST_SERVICE);
RemoteService::Ptr tmpl(new RemoteService(name, type,domain));
RemoteService::Ptr found=find(tmpl, m_duringResolve);
if (!found.isNull()) {
m_duringResolve.removeAll(found);
return;
}
found=find(tmpl, m_services);
if (found.isNull()) return;
emit m_parent->serviceRemoved(found);
m_services.removeAll(found);
}
void ServiceBrowserPrivate::browserFinished()
{
m_timer.stop();
m_browserFinished=true;
queryFinished();
}
void ServiceBrowserPrivate::queryFinished()
{
if (!m_duringResolve.count() && m_browserFinished) emit m_parent->finished();
}
QList<RemoteService::Ptr> ServiceBrowser::services() const
{
return d->m_services;
}
QHostAddress ServiceBrowser::resolveHostName(const QString &hostname)
{
org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
int protocol = 0;
QString name;
int aprotocol = 0;
QString address;
uint flags = 0;
QDBusReply<int> reply = s.ResolveHostName(-1, -1, hostname, 0, (unsigned int ) 0, protocol, name, aprotocol, address, flags);
if (reply.isValid())
return QHostAddress(address);
else
return QHostAddress();
}
QString ServiceBrowser::getLocalHostName()
{
org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
QDBusReply<QString> reply = s.GetHostName();
if (reply.isValid())
return reply.value();
else
return QString();
}
}
#include "moc_servicebrowser.cpp"
#include "moc_avahi-servicebrowser_p.cpp"

View file

@ -1,66 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef AVAHI_SERVICEBROWSER_P_H
#define AVAHI_SERVICEBROWSER_P_H
#include <QtCore/QString>
#include <QtCore/QList>
#include <QtCore/QTimer>
#include "servicebrowser.h"
#include "avahi_servicebrowser_interface.h"
namespace DNSSD
{
class ServiceBrowserPrivate : public QObject
{
Q_OBJECT
public:
ServiceBrowserPrivate(ServiceBrowser* parent) : QObject(), m_running(false), m_browser(0), m_parent(parent)
{}
~ServiceBrowserPrivate() { if (m_browser) m_browser->Free(); delete m_browser;}
QList<RemoteService::Ptr> m_services;
QList<RemoteService::Ptr> m_duringResolve;
QString m_type;
QString m_domain;
QString m_subtype;
bool m_autoResolve;
bool m_running;
bool m_finished;
bool m_browserFinished;
QTimer m_timer;
org::freedesktop::Avahi::ServiceBrowser* m_browser;
ServiceBrowser* m_parent;
// get already found service identical to s or null if not found
RemoteService::Ptr find(RemoteService::Ptr s, const QList<RemoteService::Ptr>& where) const;
private Q_SLOTS:
void browserFinished();
void queryFinished();
void serviceResolved(bool success);
void gotNewService(int,int,const QString&,const QString&,const QString&, uint);
void gotRemoveService(int,int,const QString&,const QString&,const QString&, uint);
};
}
#endif

View file

@ -1,94 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004,2007 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "avahi-servicetypebrowser_p.h"
#include <QtCore/QSet>
#include "avahi_server_interface.h"
#include "servicetypebrowser.h"
#include "avahi_servicetypebrowser_interface.h"
#define UNSPEC -1
Q_DECLARE_METATYPE(QList<QByteArray>)
namespace DNSSD
{
ServiceTypeBrowser::ServiceTypeBrowser(const QString& domain, QObject *parent) : QObject(parent), d(new ServiceTypeBrowserPrivate(this))
{
d->m_domain=domain;
d->m_timer.setSingleShot(true);
}
ServiceTypeBrowser::~ServiceTypeBrowser()
{
delete d;
}
void ServiceTypeBrowser::startBrowse()
{
if (d->m_started) return;
d->m_started=true;
org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
QDBusReply<QDBusObjectPath> rep=s.ServiceTypeBrowserNew(-1, -1, d->m_domain, 0);
if (!rep.isValid()) return;
org::freedesktop::Avahi::ServiceTypeBrowser *b=new org::freedesktop::Avahi::ServiceTypeBrowser("org.freedesktop.Avahi",rep.value().path(),
QDBusConnection::systemBus());
connect(b,SIGNAL(ItemNew(int,int,QString,QString,uint)),d, SLOT(gotNewServiceType(int,int,QString,QString,uint)));
connect(b,SIGNAL(ItemRemove(int,int,QString,QString,uint)),d, SLOT(gotRemoveServiceType(int,int,QString,QString,uint)));
connect(b,SIGNAL(AllForNow()),d,SLOT(finished()));
connect(&d->m_timer,SIGNAL(timeout()), d, SLOT(finished()));
d->m_browser=b;
d->m_timer.start(domainIsLocal(d->m_domain) ? TIMEOUT_LAST_SERVICE : TIMEOUT_START_WAN);
}
void ServiceTypeBrowserPrivate::finished()
{
m_timer.stop();
emit m_parent->finished();
}
void ServiceTypeBrowserPrivate::gotNewServiceType(int,int,const QString& type,const QString&,uint)
{
m_timer.start(TIMEOUT_LAST_SERVICE);
m_servicetypes+=type;
emit m_parent->serviceTypeAdded(type);
}
void ServiceTypeBrowserPrivate::gotRemoveServiceType(int,int,const QString& type,const QString&,uint)
{
m_timer.start(TIMEOUT_LAST_SERVICE);
m_servicetypes.removeAll(type);
emit m_parent->serviceTypeRemoved(type);
}
QStringList ServiceTypeBrowser::serviceTypes() const
{
return d->m_servicetypes;
}
}
#include "moc_servicetypebrowser.cpp"
#include "moc_avahi-servicetypebrowser_p.cpp"

View file

@ -1,53 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004,2007 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef AVAHI_SERVICETYPEBROWSER_P_H
#define AVAHI_SERVICETYPEBROWSER_P_H
#include <QtCore/QStringList>
#include <QtCore/QTimer>
#include "servicetypebrowser.h"
#include "avahi_servicetypebrowser_interface.h"
namespace DNSSD
{
class ServiceTypeBrowserPrivate : public QObject
{
Q_OBJECT
public:
ServiceTypeBrowserPrivate(ServiceTypeBrowser* parent) : m_browser(0), m_parent(parent),m_started(false) {}
~ServiceTypeBrowserPrivate() { if (m_browser) m_browser->Free(); }
org::freedesktop::Avahi::ServiceTypeBrowser* m_browser;
ServiceTypeBrowser* m_parent;
bool m_started;
QStringList m_servicetypes;
QString m_domain;
QTimer m_timer;
private Q_SLOTS:
void gotNewServiceType(int,int,const QString&, const QString&, uint);
void gotRemoveServiceType(int,int,const QString&, const QString&, uint);
void finished();
};
}
#endif

View file

@ -1,28 +0,0 @@
/*
* This file was generated by dbusxml2cpp version 0.6
* Command line was: dbusxml2cpp -m -p avahi_entrygroup_interface /home/qba/src/kdelibs/dnssd/org.freedesktop.Avahi.EntryGroup.xml
*
* dbusxml2cpp is Copyright (C) 2006 Trolltech ASA. All rights reserved.
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "avahi_entrygroup_interface.h"
Q_DECLARE_METATYPE(QList<QByteArray>)
/*
* Implementation of interface class OrgFreedesktopAvahiEntryGroupInterface
*/
OrgFreedesktopAvahiEntryGroupInterface::OrgFreedesktopAvahiEntryGroupInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
OrgFreedesktopAvahiEntryGroupInterface::~OrgFreedesktopAvahiEntryGroupInterface()
{
}
#include "moc_avahi_entrygroup_interface.cpp"

View file

@ -1,115 +0,0 @@
/*
* This file was generated by dbusxml2cpp version 0.6
* Command line was: dbusxml2cpp -m -p avahi_entrygroup_interface /home/qba/src/kdelibs/dnssd/org.freedesktop.Avahi.EntryGroup.xml
*
* dbusxml2cpp is Copyright (C) 2006 Trolltech ASA. All rights reserved.
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef AVAHI_ENTRYGROUP_INTERFACE_H_1175536773
#define AVAHI_ENTRYGROUP_INTERFACE_H_1175536773
#include <QtCore/QObject>
#include <QtCore/qbytearray.h>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
/*
* Proxy class for interface org.freedesktop.Avahi.EntryGroup
*/
class OrgFreedesktopAvahiEntryGroupInterface: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.freedesktop.Avahi.EntryGroup"; }
public:
OrgFreedesktopAvahiEntryGroupInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~OrgFreedesktopAvahiEntryGroupInterface();
public Q_SLOTS: // METHODS
inline QDBusReply<void> AddAddress(int interface, int protocol, uint flags, const QString &name, const QString &address)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(flags) << qVariantFromValue(name) << qVariantFromValue(address);
return callWithArgumentList(QDBus::Block, QLatin1String("AddAddress"), argumentList);
}
inline QDBusReply<void> AddRecord(int interface, int protocol, uint flags, const QString &name, ushort clazz, ushort type, uint ttl, const QByteArray &rdata)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(flags) << qVariantFromValue(name) << qVariantFromValue(clazz) << qVariantFromValue(type) << qVariantFromValue(ttl) << qVariantFromValue(rdata);
return callWithArgumentList(QDBus::Block, QLatin1String("AddRecord"), argumentList);
}
inline QDBusReply<void> AddService(int interface, int protocol, uint flags, const QString &name, const QString &type, const QString &domain, const QString &host, ushort port, const QList<QByteArray> &txt)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(flags) << qVariantFromValue(name) << qVariantFromValue(type) << qVariantFromValue(domain) << qVariantFromValue(host) << qVariantFromValue(port) << qVariantFromValue(txt);
return callWithArgumentList(QDBus::Block, QLatin1String("AddService"), argumentList);
}
inline QDBusReply<void> AddServiceSubtype(int interface, int protocol, uint flags, const QString &name, const QString &type, const QString &domain, const QString &subtype)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(flags) << qVariantFromValue(name) << qVariantFromValue(type) << qVariantFromValue(domain) << qVariantFromValue(subtype);
return callWithArgumentList(QDBus::Block, QLatin1String("AddServiceSubtype"), argumentList);
}
inline QDBusReply<void> Commit()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("Commit"), argumentList);
}
inline QDBusReply<void> Free()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("Free"), argumentList);
}
inline QDBusReply<int> GetState()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("GetState"), argumentList);
}
inline QDBusReply<bool> IsEmpty()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("IsEmpty"), argumentList);
}
inline QDBusReply<void> Reset()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("Reset"), argumentList);
}
inline QDBusReply<void> UpdateServiceTxt(int interface, int protocol, uint flags, const QString &name, const QString &type, const QString &domain, const QList<QByteArray> &txt)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(flags) << qVariantFromValue(name) << qVariantFromValue(type) << qVariantFromValue(domain) << qVariantFromValue(txt);
return callWithArgumentList(QDBus::Block, QLatin1String("UpdateServiceTxt"), argumentList);
}
Q_SIGNALS: // SIGNALS
void StateChanged(int state, const QString &error);
};
namespace org {
namespace freedesktop {
namespace Avahi {
typedef ::OrgFreedesktopAvahiEntryGroupInterface EntryGroup;
}
}
}
#endif

View file

@ -1,54 +0,0 @@
/*
* This file was generated by dbusxml2cpp version 0.6
* Command line was: dbusxml2cpp -m -p avahi_server_interface /home/qba/src/kdelibs/dnssd/org.freedesktop.Avahi.Server.xml
*
* dbusxml2cpp is Copyright (C) 2006 Trolltech ASA. All rights reserved.
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "avahi_server_interface.h"
#include "servicebase.h"
#include <QtCore/QUrl>
Q_DECLARE_METATYPE(QList<QByteArray>)
/*
* Implementation of interface class OrgFreedesktopAvahiServerInterface
*/
OrgFreedesktopAvahiServerInterface::OrgFreedesktopAvahiServerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
OrgFreedesktopAvahiServerInterface::~OrgFreedesktopAvahiServerInterface()
{
}
namespace DNSSD {
void registerTypes()
{
static bool registered=false;
if (!registered) {
qDBusRegisterMetaType<QList<QByteArray> >();
registered=true;
}
}
QString domainToDNS(const QString &domain)
{
if (domainIsLocal(domain)) return domain;
else return QUrl::toAce(domain);
}
QString DNSToDomain(const QString& domain)
{
if (domainIsLocal(domain)) return domain;
else return QUrl::fromAce(domain.toLatin1());
}
}
#include "moc_avahi_server_interface.cpp"

View file

@ -1,250 +0,0 @@
/*
* This file was generated by dbusxml2cpp version 0.6
* Command line was: dbusxml2cpp -m -p avahi_server_interface /home/qba/src/kdelibs/dnssd/org.freedesktop.Avahi.Server.xml
*
* dbusxml2cpp is Copyright (C) 2006 Trolltech ASA. All rights reserved.
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef AVAHI_SERVER_INTERFACE_H_1175535514
#define AVAHI_SERVER_INTERFACE_H_1175535514
#include <QtCore/QObject>
#include <QtCore/qbytearray.h>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
// wait 100ms after last service
#define TIMEOUT_LAST_SERVICE 100
// and at least 700ms for first WAN answer
#define TIMEOUT_START_WAN 700
/*
* Proxy class for interface org.freedesktop.Avahi.Server
*/
class OrgFreedesktopAvahiServerInterface: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.freedesktop.Avahi.Server"; }
public:
OrgFreedesktopAvahiServerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~OrgFreedesktopAvahiServerInterface();
public Q_SLOTS: // METHODS
inline QDBusReply<QDBusObjectPath> AddressResolverNew(int interface, int protocol, const QString &address, uint flags)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(address) << qVariantFromValue(flags);
return callWithArgumentList(QDBus::Block, QLatin1String("AddressResolverNew"), argumentList);
}
inline QDBusReply<QDBusObjectPath> DomainBrowserNew(int interface, int protocol, const QString &domain, int btype, uint flags)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(domain) << qVariantFromValue(btype) << qVariantFromValue(flags);
return callWithArgumentList(QDBus::Block, QLatin1String("DomainBrowserNew"), argumentList);
}
inline QDBusReply<QDBusObjectPath> EntryGroupNew()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("EntryGroupNew"), argumentList);
}
inline QDBusReply<uint> GetAPIVersion()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("GetAPIVersion"), argumentList);
}
inline QDBusReply<QString> GetAlternativeHostName(const QString &name)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(name);
return callWithArgumentList(QDBus::Block, QLatin1String("GetAlternativeHostName"), argumentList);
}
inline QDBusReply<QString> GetAlternativeServiceName(const QString &name)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(name);
return callWithArgumentList(QDBus::Block, QLatin1String("GetAlternativeServiceName"), argumentList);
}
inline QDBusReply<QString> GetDomainName()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("GetDomainName"), argumentList);
}
inline QDBusReply<QString> GetHostName()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("GetHostName"), argumentList);
}
inline QDBusReply<QString> GetHostNameFqdn()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("GetHostNameFqdn"), argumentList);
}
inline QDBusReply<uint> GetLocalServiceCookie()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("GetLocalServiceCookie"), argumentList);
}
inline QDBusReply<int> GetNetworkInterfaceIndexByName(const QString &name)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(name);
return callWithArgumentList(QDBus::Block, QLatin1String("GetNetworkInterfaceIndexByName"), argumentList);
}
inline QDBusReply<QString> GetNetworkInterfaceNameByIndex(int index)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(index);
return callWithArgumentList(QDBus::Block, QLatin1String("GetNetworkInterfaceNameByIndex"), argumentList);
}
inline QDBusReply<int> GetState()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("GetState"), argumentList);
}
inline QDBusReply<QString> GetVersionString()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("GetVersionString"), argumentList);
}
inline QDBusReply<QDBusObjectPath> HostNameResolverNew(int interface, int protocol, const QString &name, int aprotocol, uint flags)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(name) << qVariantFromValue(aprotocol) << qVariantFromValue(flags);
return callWithArgumentList(QDBus::Block, QLatin1String("HostNameResolverNew"), argumentList);
}
inline QDBusReply<bool> IsNSSSupportAvailable()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("IsNSSSupportAvailable"), argumentList);
}
inline QDBusReply<QDBusObjectPath> RecordBrowserNew(int interface, int protocol, const QString &name, ushort clazz, ushort type, uint flags)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(name) << qVariantFromValue(clazz) << qVariantFromValue(type) << qVariantFromValue(flags);
return callWithArgumentList(QDBus::Block, QLatin1String("RecordBrowserNew"), argumentList);
}
inline QDBusReply<int> ResolveAddress(int interface, int protocol, const QString &address, uint flags, int &protocol_, int &aprotocol, QString &address_, QString &name, uint &flags_)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(address) << qVariantFromValue(flags);
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("ResolveAddress"), argumentList);
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 6) {
protocol_ = qdbus_cast<int>(reply.arguments().at(1));
aprotocol = qdbus_cast<int>(reply.arguments().at(2));
address_ = qdbus_cast<QString>(reply.arguments().at(3));
name = qdbus_cast<QString>(reply.arguments().at(4));
flags_ = qdbus_cast<uint>(reply.arguments().at(5));
}
return reply;
}
inline QDBusReply<int> ResolveHostName(int interface, int protocol, const QString &name, int aprotocol, uint flags, int &protocol_, QString &name_, int &aprotocol_, QString &address, uint &flags_)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(name) << qVariantFromValue(aprotocol) << qVariantFromValue(flags);
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("ResolveHostName"), argumentList);
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 6) {
protocol_ = qdbus_cast<int>(reply.arguments().at(1));
name_ = qdbus_cast<QString>(reply.arguments().at(2));
aprotocol_ = qdbus_cast<int>(reply.arguments().at(3));
address = qdbus_cast<QString>(reply.arguments().at(4));
flags_ = qdbus_cast<uint>(reply.arguments().at(5));
}
return reply;
}
inline QDBusReply<int> ResolveService(int interface, int protocol, const QString &name, const QString &type, const QString &domain, int aprotocol, uint flags, int &protocol_, QString &name_, QString &type_, QString &domain_, QString &host, int &aprotocol_, QString &address, ushort &port, QList<QByteArray> &txt, uint &flags_)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(name) << qVariantFromValue(type) << qVariantFromValue(domain) << qVariantFromValue(aprotocol) << qVariantFromValue(flags);
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("ResolveService"), argumentList);
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 11) {
protocol_ = qdbus_cast<int>(reply.arguments().at(1));
name_ = qdbus_cast<QString>(reply.arguments().at(2));
type_ = qdbus_cast<QString>(reply.arguments().at(3));
domain_ = qdbus_cast<QString>(reply.arguments().at(4));
host = qdbus_cast<QString>(reply.arguments().at(5));
aprotocol_ = qdbus_cast<int>(reply.arguments().at(6));
address = qdbus_cast<QString>(reply.arguments().at(7));
port = qdbus_cast<ushort>(reply.arguments().at(8));
txt = qdbus_cast<QList<QByteArray> >(reply.arguments().at(9));
flags_ = qdbus_cast<uint>(reply.arguments().at(10));
}
return reply;
}
inline QDBusReply<QDBusObjectPath> ServiceBrowserNew(int interface, int protocol, const QString &type, const QString &domain, uint flags)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(type) << qVariantFromValue(domain) << qVariantFromValue(flags);
return callWithArgumentList(QDBus::Block, QLatin1String("ServiceBrowserNew"), argumentList);
}
inline QDBusReply<QDBusObjectPath> ServiceResolverNew(int interface, int protocol, const QString &name, const QString &type, const QString &domain, int aprotocol, uint flags)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(name) << qVariantFromValue(type) << qVariantFromValue(domain) << qVariantFromValue(aprotocol) << qVariantFromValue(flags);
return callWithArgumentList(QDBus::Block, QLatin1String("ServiceResolverNew"), argumentList);
}
inline QDBusReply<QDBusObjectPath> ServiceTypeBrowserNew(int interface, int protocol, const QString &domain, uint flags)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(interface) << qVariantFromValue(protocol) << qVariantFromValue(domain) << qVariantFromValue(flags);
return callWithArgumentList(QDBus::Block, QLatin1String("ServiceTypeBrowserNew"), argumentList);
}
inline QDBusReply<void> SetHostName(const QString &name)
{
QList<QVariant> argumentList;
argumentList << qVariantFromValue(name);
return callWithArgumentList(QDBus::Block, QLatin1String("SetHostName"), argumentList);
}
Q_SIGNALS: // SIGNALS
void StateChanged(int state, const QString &error);
};
namespace DNSSD {
void registerTypes();
QString domainToDNS(const QString &domain);
QString DNSToDomain(const QString &domain);
}
namespace org {
namespace freedesktop {
namespace Avahi {
typedef ::OrgFreedesktopAvahiServerInterface Server;
}
}
}
#endif

View file

@ -1,29 +0,0 @@
/*
* This file was generated by dbusxml2cpp version 0.6
* Command line was: dbusxml2cpp -m -p avahi_serviceresolver_interface /home/qba/src/kdelibs/dnssd/org.freedesktop.Avahi.ServiceResolver.xml
*
* dbusxml2cpp is Copyright (C) 2006 Trolltech ASA. All rights reserved.
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "avahi_serviceresolver_interface.h"
Q_DECLARE_METATYPE(QList<QByteArray>)
/*
* Implementation of interface class OrgFreedesktopAvahiServiceResolverInterface
*/
OrgFreedesktopAvahiServiceResolverInterface::OrgFreedesktopAvahiServiceResolverInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
OrgFreedesktopAvahiServiceResolverInterface::~OrgFreedesktopAvahiServiceResolverInterface()
{
}
#include "moc_avahi_serviceresolver_interface.cpp"

View file

@ -1,57 +0,0 @@
/*
* This file was generated by dbusxml2cpp version 0.6
* Command line was: dbusxml2cpp -m -p avahi_serviceresolver_interface /home/qba/src/kdelibs/dnssd/org.freedesktop.Avahi.ServiceResolver.xml
*
* dbusxml2cpp is Copyright (C) 2006 Trolltech ASA. All rights reserved.
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef AVAHI_SERVICERESOLVER_INTERFACE_H_1175536773
#define AVAHI_SERVICERESOLVER_INTERFACE_H_1175536773
#include <QtCore/QObject>
#include <QtCore/qbytearray.h>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
/*
* Proxy class for interface org.freedesktop.Avahi.ServiceResolver
*/
class OrgFreedesktopAvahiServiceResolverInterface: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.freedesktop.Avahi.ServiceResolver"; }
public:
OrgFreedesktopAvahiServiceResolverInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~OrgFreedesktopAvahiServiceResolverInterface();
public Q_SLOTS: // METHODS
inline QDBusReply<void> Free()
{
QList<QVariant> argumentList;
return callWithArgumentList(QDBus::Block, QLatin1String("Free"), argumentList);
}
Q_SIGNALS: // SIGNALS
void Failure(const QString &error);
void Found(int interface, int protocol, const QString &name, const QString &type, const QString &domain, const QString &host, int aprotocol, const QString &address, ushort port, const QList<QByteArray> &txt, uint flags);
};
namespace org {
namespace freedesktop {
namespace Avahi {
typedef ::OrgFreedesktopAvahiServiceResolverInterface ServiceResolver;
}
}
}
#endif

View file

@ -1,145 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef DNSSDDOMAINBROWSER_H
#define DNSSDDOMAINBROWSER_H
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <dnssd/remoteservice.h>
namespace DNSSD
{
class DomainBrowserPrivate;
/**
* @class DomainBrowser domainbrowser.h DNSSD/DomainBrowser
* @short Browses recommended domains for browsing or publishing to.
*
* Usage of this class is very simple. If you are interested in
* browsing for services, simple do
* @code
* DNSSD::DomainBrowser *browser =
* new DNSSD::DomainBrowser(DNSSD::DomainBrowser::Browsing, this);
* connect(browser, SIGNAL(domainAdded(QString)),
* this, SLOT(browsingDomainAdded(QString));
* connect(browser, SIGNAL(domainRemoved(QString)),
* this, SLOT(browsingDomainRemove(QString));
* browser->startBrowse();
* @endcode
*
* If you are interested in domains where you can register services,
* usage is identical except that you should pass
* <tt>DNSSD::DomainBrowser::Registering</tt> to the constructor.
*
* @author Jakub Stachowski
*/
class KDNSSD_EXPORT DomainBrowser : public QObject
{
Q_OBJECT
public:
/**
* A type of domain recommendation
*/
enum DomainType
{
/** Domains recommended for browsing for services on (using ServiceBrowser) */
Browsing,
/** Domains recommended for publishing to (using PublicService) */
Publishing
};
/**
* Standard constructor
*
* The global DNS-SD configuration (for example, the global Avahi
* configuration for the Avahi backend) will be used.
*
* @param type the type of domain to search for
* @param parent parent object (see QObject documentation)
*
* @see startBrowse() and ServiceBrowser::isAvailable()
*/
explicit DomainBrowser(DomainType type, QObject* parent = 0);
~DomainBrowser();
/**
* The current known list of domains of the requested DomainType
*
* @return a list of currently known domain names
*/
QStringList domains() const;
/**
* Starts browsing
*
* Only the first call to this function will have any effect.
*
* Browsing stops when the DomainBrowser object is destroyed.
*
* @warning The domainAdded() signal may be emitted before this
* function returns.
*
* @see domainAdded() and domainRemoved()
*/
void startBrowse();
/**
* Whether the browsing has been started
*
* @return @c true if startBrowse() has been called, @c false otherwise
*/
bool isRunning() const;
Q_SIGNALS:
/**
* A domain has disappeared from the browsed list
*
* Emitted when domain has been removed from browsing list
* or the publishing list (depending on which list was
* requested in the constructor).
*
* @param domain the name of the domain
*
* @see domainAdded()
*/
void domainRemoved(const QString& domain);
/**
* A new domain has been discovered
*
* If the requested DomainType is Browsing, this will
* also be emitted for the domains specified in the
* global configuration.
*
* @param domain the name of the domain
*
* @see domainRemoved()
*/
void domainAdded(const QString& domain);
private:
friend class DomainBrowserPrivate;
DomainBrowserPrivate* const d;
};
}
#endif

View file

@ -1,89 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2008 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "domainmodel.h"
#include "domainbrowser.h"
#include <qstringlist.h>
namespace DNSSD
{
struct DomainModelPrivate
{
DomainBrowser* m_browser;
};
DomainModel::DomainModel(DomainBrowser* browser, QObject* parent)
: QAbstractItemModel(parent), d(new DomainModelPrivate)
{
d->m_browser=browser;
browser->setParent(this);
connect(browser, SIGNAL(domainAdded(QString)), this,
SIGNAL(layoutChanged()));
connect(browser, SIGNAL(domainRemoved(QString)), this,
SIGNAL(layoutChanged()));
browser->startBrowse();
}
DomainModel::~DomainModel()
{
delete d;
}
int DomainModel::columnCount(const QModelIndex& parent) const
{
Q_UNUSED(parent);
return 1;
}
int DomainModel::rowCount(const QModelIndex& parent ) const
{
return (parent.isValid()) ? 0 : d->m_browser->domains().size();
}
QModelIndex DomainModel::parent(const QModelIndex& index ) const
{
Q_UNUSED(index);
return QModelIndex();
}
QModelIndex DomainModel::index(int row, int column, const QModelIndex& parent ) const
{
return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex();
}
bool DomainModel::hasIndex(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid()) return false;
if (column!=0) return false;
if (row<0 || row>=rowCount(parent)) return false;
return true;
}
QVariant DomainModel::data(const QModelIndex& index, int role ) const
{
if (!index.isValid()) return QVariant();
if (!hasIndex(index.row(), index.column(), index.parent())) return QVariant();
const QStringList domains=d->m_browser->domains();
if (role==Qt::DisplayRole) return domains[index.row()];
return QVariant();
}
}

View file

@ -1,97 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2008 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef DNSSDDOMAINMODEL_H
#define DNSSDDOMAINMODEL_H
#include <QtCore/QAbstractItemModel>
#include <dnssd/kdnssd_export.h>
namespace DNSSD
{
struct DomainModelPrivate;
class DomainBrowser;
/**
* @class DomainModel domainmodel.h DNSSD/DomainModel
* @short Model for list of Zeroconf domains
*
* This class provides a Qt Model for DomainBrowser to allow easy
* integration of domain discovery into a GUI. For example, to
* provide a combo box listing available domains, you can do:
* @code
* DNSSD::DomainModel *domainModel = new DomainModel(
* new DNSSD::DomainBrowser(DNSSD::DomainBrowser::Browsing)
* );
* QComboBox *domainCombo = new QComboBox();
* domainCombo->setModel(domainModel);
* @endcode
*
* @since 4.1
* @author Jakub Stachowski
*/
class KDNSSD_EXPORT DomainModel : public QAbstractItemModel
{
Q_OBJECT
public:
/**
* Creates a model for given domain browser and starts
* browsing for domains.
*
* The model takes ownership of the browser,
* so there is no need to delete it afterwards.
*
* You should @b not call DomainBrowser::startBrowse() on @p browser
* before passing it to DomainModel.
*
* @param browser the domain browser that will provide the domains
* to be listed by the model
* @param parent the parent object (see QObject documentation)
*/
explicit DomainModel(DomainBrowser* browser, QObject* parent = 0);
virtual ~DomainModel();
/** @reimp */
virtual int columnCount(const QModelIndex& parent = QModelIndex() ) const;
/** @reimp */
virtual int rowCount(const QModelIndex& parent = QModelIndex() ) const;
/** @reimp */
virtual QModelIndex parent(const QModelIndex& index ) const;
/** @reimp */
virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex() ) const;
/** @reimp */
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole ) const;
/** @reimp */
virtual bool hasIndex(int row, int column, const QModelIndex &parent) const;
private:
DomainModelPrivate* const d;
friend struct DomainModelPrivate;
};
}
#endif

View file

@ -1,48 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QStringList>
#include "domainbrowser.h"
namespace DNSSD
{
DomainBrowser::DomainBrowser(DomainType, QObject *parent) : QObject(parent), d(0)
{}
DomainBrowser::~DomainBrowser()
{}
void DomainBrowser::startBrowse()
{}
QStringList DomainBrowser::domains() const
{
return QStringList();
}
bool DomainBrowser::isRunning() const
{
return false;
}
}
#include "moc_domainbrowser.cpp"

View file

@ -1,94 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "publicservice.h"
#include "servicebase_p.h"
#include <QtCore/QStringList>
namespace DNSSD
{
PublicService::PublicService(const QString& name, const QString& type, unsigned int port,
const QString& domain, const QStringList&)
: QObject(), ServiceBase(name, type, QString(), domain, port)
{
if (domain.isNull()) d->m_domain=QLatin1String("local.");
}
PublicService::~PublicService()
{}
void PublicService::setServiceName(const QString& serviceName)
{
d->m_serviceName = serviceName;
}
void PublicService::setDomain(const QString& domain)
{
d->m_domain = domain;
}
void PublicService::setTextData(const QMap<QString,QByteArray>& textData)
{
d->m_textData = textData;
}
void PublicService::setType(const QString& type)
{
d->m_type = type;
}
void PublicService::setSubTypes(const QStringList&)
{
// dummy and empty
}
void PublicService::setPort(unsigned short port)
{
d->m_port = port;
}
QStringList PublicService::subtypes() const
{
return QStringList();
}
bool PublicService::isPublished() const
{
return false;
}
bool PublicService::publish()
{
return false;
}
void PublicService::stop()
{}
void PublicService::publishAsync()
{
emit published(false);
}
}
#include "moc_publicservice.cpp"

View file

@ -1,55 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "remoteservice.h"
#include <QtCore/QDataStream>
namespace DNSSD
{
RemoteService::RemoteService(const QString& name,const QString& type,const QString& domain)
: ServiceBase(name, type, domain)
{
}
RemoteService::~RemoteService()
{
}
bool RemoteService::resolve()
{
return false;
}
void RemoteService::resolveAsync()
{
emit resolved(false);
}
bool RemoteService::isResolved() const
{
return false;
}
}
#include "moc_remoteservice.cpp"

View file

@ -1,69 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QStringList>
#include "domainbrowser.h"
#include "servicebrowser.h"
#include <QtCore/QHash>
namespace DNSSD
{
ServiceBrowser::ServiceBrowser(const QString&,bool,const QString&, const QString&) : d(0)
{}
bool ServiceBrowser::isAutoResolving() const
{
return false;
}
ServiceBrowser::State ServiceBrowser::isAvailable()
{
return Unsupported;
}
ServiceBrowser::~ ServiceBrowser()
{
}
void ServiceBrowser::startBrowse()
{
emit finished();
}
QList<RemoteService::Ptr> ServiceBrowser::services() const
{
return QList<RemoteService::Ptr>();
}
QHostAddress ServiceBrowser::resolveHostName(const QString &hostname)
{
Q_UNUSED(hostname);
return QHostAddress();
}
QString ServiceBrowser::getLocalHostName()
{
return QString();
}
}
#include "moc_servicebrowser.cpp"

View file

@ -1,44 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QStringList>
#include "servicetypebrowser.h"
namespace DNSSD
{
ServiceTypeBrowser::ServiceTypeBrowser(const QString&, QObject *parent) : QObject(parent), d(0)
{}
ServiceTypeBrowser::~ServiceTypeBrowser()
{}
void ServiceTypeBrowser::startBrowse()
{}
QStringList ServiceTypeBrowser::serviceTypes() const
{
return QStringList();
}
}
#include "moc_servicetypebrowser.cpp"

View file

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name="kdnssdrc" />
<group name="browsing" >
<entry key="DomainList" type="StringList" >
<label>Additional domains for browsing</label>
<whatsthis>List of 'wide-area' (non link-local) domains that should be browsed.</whatsthis>
</entry>
</group>
</kcfg>

View file

@ -1,131 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "mdnsd-domainbrowser_p.h"
#include "domainbrowser.h"
#include "settings.h"
#include "remoteservice.h"
#include "mdnsd-responder.h"
#include "mdnsd-sdevent.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QHash>
#include <QtCore/QStringList>
#include <QtDBus/QtDBus>
namespace DNSSD
{
void domain_callback(DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode, const char *replyDomain, void *context);
DomainBrowser::DomainBrowser(DomainType type, QObject *parent) : QObject(parent),d(new DomainBrowserPrivate(type,this))
{
d->m_domains = Configuration::domainList();
// Those same names have to be used in the kcontrol module too.
const QString dbusPath = "/libdnssd";
const QString dbusInterface = "org.kde.DNSSD.DomainBrowser";
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.connect( QString(), dbusPath, dbusInterface, "domainListChanged", this, SLOT(domainListChanged()) );
}
DomainBrowser::~DomainBrowser()
{
delete d;
}
void DomainBrowser::startBrowse()
{
QStringList::const_iterator itEnd = d->m_domains.end();
for (QStringList::const_iterator it=d->m_domains.begin(); it!=itEnd; ++it ) emit domainAdded(*it);
if (d->isRunning()) return;
DNSServiceRef ref;
if (DNSServiceEnumerateDomains(&ref,(d->m_type==Browsing) ? kDNSServiceFlagsBrowseDomains:kDNSServiceFlagsBrowseDomains,
0, domain_callback,reinterpret_cast<void*>(d)) == kDNSServiceErr_NoError) d->setRef(ref);
}
void DomainBrowserPrivate::customEvent(QEvent* event)
{
if (event->type()==QEvent::User+SD_ERROR) stop();
if (event->type()==QEvent::User+SD_ADDREMOVE) {
AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event);
if (aev->m_op==AddRemoveEvent::Add) {
//FIXME: check if domain name is not name+domain (there was some mdnsd weirdness)
if (m_domains.contains(aev->m_domain)) return;
m_domains.append(aev->m_domain);
emit m_parent->domainAdded(aev->m_domain);
}
else {
m_domains.removeAll(aev->m_domain);
emit m_parent->domainRemoved(aev->m_domain);
}
}
}
void DomainBrowserPrivate::domainListChanged()
{
bool was_running = m_running;
m_running = false;
if (was_running) {
QStringList::const_iterator itEnd = m_domains.end();
for (QStringList::const_iterator it=m_domains.begin(); it!=itEnd; ++it )
emit m_parent->domainRemoved(*it);
}
m_domains.clear();
// now reread configuration and add domains
Configuration::self()->readConfig();
m_domains = Configuration::domainList();
// this will emit domainAdded() for every domain if necessary
if (was_running) m_parent->startBrowse();
}
QStringList DomainBrowser::domains() const
{
return d->m_domains;
}
bool DomainBrowser::isRunning() const
{
return d->isRunning();
}
void domain_callback(DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode, const char *replyDomain, void *context)
{
QObject *obj = reinterpret_cast<QObject*>(context);
if (errorCode != kDNSServiceErr_NoError) {
ErrorEvent err;
QCoreApplication::sendEvent(obj, &err);
} else {
// domain browser is supposed to return only _additional_ domains
if (flags&kDNSServiceFlagsDefault) return;
AddRemoveEvent arev((flags & kDNSServiceFlagsAdd) ? AddRemoveEvent::Add :
AddRemoveEvent::Remove, QString(), QString(),
DNSToDomain(replyDomain), !(flags & kDNSServiceFlagsMoreComing));
QCoreApplication::sendEvent(obj, &arev);
}
}
}
#include "moc_domainbrowser.cpp"
#include "moc_mdnsd-domainbrowser_p.cpp"

View file

@ -1,46 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef MDNSD_DOMAINBROWSER_P_H
#define MDNSD_DOMAINBROWSER_P_H
#include <QtCore/QStringList>
#include "mdnsd-responder.h"
#include "domainbrowser.h"
namespace DNSSD
{
class DomainBrowserPrivate : public Responder
{
Q_OBJECT
public:
DomainBrowserPrivate(DomainBrowser::DomainType type, DomainBrowser* parent): Responder(), m_type(type), m_parent(parent) {}
DomainBrowser::DomainType m_type;
DomainBrowser* m_parent;
QStringList m_domains;
virtual void customEvent(QEvent* event);
public Q_SLOTS:
void domainListChanged();
};
}
#endif

View file

@ -1,203 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <netinet/in.h>
#include "publicservice.h"
#include "servicebase_p.h"
#include "mdnsd-sdevent.h"
#include "mdnsd-responder.h"
#include "settings.h"
#define K_D PublicServicePrivate* d=static_cast<PublicServicePrivate*>(this->d)
namespace DNSSD
{
void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name,
const char*, const char*, void *context);
class PublicServicePrivate : public Responder, public ServiceBasePrivate
{
public:
PublicServicePrivate(PublicService* parent, const QString& name, const QString& type, unsigned int port,
const QString& domain) : Responder(), ServiceBasePrivate(name, type, domain, QString(), port),
m_published(false), m_parent(parent)
{}
bool m_published;
PublicService* m_parent;
QStringList m_subtypes;
virtual void customEvent(QEvent* event);
};
PublicService::PublicService(const QString& name, const QString& type, unsigned int port,
const QString& domain, const QStringList& subtypes)
: QObject(), ServiceBase(new PublicServicePrivate(this, name, type, port, domain))
{
K_D;
if (domain.isNull()) d->m_domain="local.";
d->m_subtypes=subtypes;
}
PublicService::~PublicService()
{
stop();
}
void PublicService::setServiceName(const QString& serviceName)
{
K_D;
d->m_serviceName = serviceName;
if (d->isRunning()) {
stop();
publishAsync();
}
}
void PublicService::setDomain(const QString& domain)
{
K_D;
d->m_domain = domain;
if (d->isRunning()) {
stop();
publishAsync();
}
}
QStringList PublicService::subtypes() const
{
K_D;
return d->m_subtypes;
}
void PublicService::setType(const QString& type)
{
K_D;
d->m_type = type;
if (d->isRunning()) {
stop();
publishAsync();
}
}
void PublicService::setSubTypes(const QStringList& subtypes)
{
K_D;
d->m_subtypes = subtypes;
if (d->isRunning()) {
stop();
publishAsync();
}
}
void PublicService::setPort(unsigned short port)
{
K_D;
d->m_port = port;
if (d->isRunning()) {
stop();
publishAsync();
}
}
bool PublicService::isPublished() const
{
K_D;
return d->m_published;
}
void PublicService::setTextData(const QMap<QString,QByteArray>& textData)
{
K_D;
d->m_textData = textData;
if (d->isRunning()) {
stop();
publishAsync();
}
}
bool PublicService::publish()
{
K_D;
publishAsync();
while (d->isRunning() && !d->m_published) d->process();
return d->m_published;
}
void PublicService::stop()
{
K_D;
d->stop();
d->m_published = false;
}
void PublicService::publishAsync()
{
K_D;
if (d->isRunning()) stop();
TXTRecordRef txt;
TXTRecordCreate(&txt,0,0);
QMap<QString,QByteArray>::ConstIterator itEnd = d->m_textData.end();
for (QMap<QString,QByteArray>::ConstIterator it = d->m_textData.begin(); it!=itEnd ; ++it) {
if (TXTRecordSetValue(&txt,it.key().toUtf8(),it.value().length(),it.value())!=kDNSServiceErr_NoError) {
TXTRecordDeallocate(&txt);
emit published(false);
return;
}
}
DNSServiceRef ref;
QString fullType=d->m_type;
Q_FOREACH(const QString &subtype, d->m_subtypes) fullType+=','+subtype;
if (DNSServiceRegister(&ref,0,0,d->m_serviceName.toUtf8(),fullType.toLatin1().constData(),domainToDNS(d->m_domain),NULL,
htons(d->m_port),TXTRecordGetLength(&txt),TXTRecordGetBytesPtr(&txt),publish_callback,
reinterpret_cast<void*>(d)) == kDNSServiceErr_NoError) d->setRef(ref);
TXTRecordDeallocate(&txt);
if (!d->isRunning()) emit published(false);
}
void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name,
const char*, const char*, void *context)
{
QObject *obj = reinterpret_cast<QObject*>(context);
if (errorCode != kDNSServiceErr_NoError) {
ErrorEvent err;
QCoreApplication::sendEvent(obj, &err);
} else {
PublishEvent pev(QString::fromUtf8(name));
QCoreApplication::sendEvent(obj, &pev);
}
}
void PublicServicePrivate::customEvent(QEvent* event)
{
if (event->type()==QEvent::User+SD_ERROR) {
m_parent->stop();
emit m_parent->published(false);
}
if (event->type()==QEvent::User+SD_PUBLISH) {
m_published=true;
emit m_parent->published(true);
m_serviceName = static_cast<PublishEvent*>(event)->m_name;
}
}
}
#include "moc_publicservice.cpp"

View file

@ -1,149 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <netinet/in.h>
#include <QtCore/QEventLoop>
#include <QtCore/QCoreApplication>
#include <kdebug.h>
#include "remoteservice.h"
#include "servicebase_p.h"
#include "mdnsd-responder.h"
#include "mdnsd-sdevent.h"
namespace DNSSD
{
void resolve_callback ( DNSServiceRef,
DNSServiceFlags,
uint32_t,
DNSServiceErrorType errorCode,
const char*,
const char *hosttarget,
uint16_t port,
uint16_t txtLen,
const unsigned char *txtRecord,
void *context
);
#define K_D RemoteServicePrivate* d=static_cast<RemoteServicePrivate*>(this->d)
class RemoteServicePrivate : public Responder, public ServiceBasePrivate
{
public:
RemoteServicePrivate(RemoteService* parent, const QString& name,const QString& type,const QString& domain) :
Responder(), ServiceBasePrivate(name, type, domain, QString(), 0), m_resolved(false), m_parent(parent)
{}
bool m_resolved;
RemoteService* m_parent;
virtual void customEvent(QEvent* event);
};
RemoteService::RemoteService(const QString& name,const QString& type,const QString& domain)
: ServiceBase(new RemoteServicePrivate(this, name, type, domain))
{
}
RemoteService::~RemoteService()
{}
bool RemoteService::resolve()
{
K_D;
resolveAsync();
while (d->isRunning() && !d->m_resolved) d->process();
d->stop();
return d->m_resolved;
}
void RemoteService::resolveAsync()
{
K_D;
if (d->isRunning()) return;
d->m_resolved = false;
kDebug() << this << ":Starting resolve of : " << d->m_serviceName << " " << d->m_type << " " << d->m_domain << "\n";
DNSServiceRef ref;
if (DNSServiceResolve(&ref,0,0,d->m_serviceName.toUtf8(), d->m_type.toLatin1().constData(),
domainToDNS(d->m_domain),(DNSServiceResolveReply)resolve_callback,reinterpret_cast<void*>(d))
== kDNSServiceErr_NoError) d->setRef(ref);
if (!d->isRunning()) emit resolved(false);
}
bool RemoteService::isResolved() const
{
K_D;
return d->m_resolved;
}
void RemoteServicePrivate::customEvent(QEvent* event)
{
if (event->type() == QEvent::User+SD_ERROR) {
stop();
m_resolved=false;
emit m_parent->resolved(false);
}
if (event->type() == QEvent::User+SD_RESOLVE) {
ResolveEvent* rev = static_cast<ResolveEvent*>(event);
m_hostName = rev->m_hostname;
m_port = rev->m_port;
m_textData = rev->m_txtdata;
m_resolved = true;
emit m_parent->resolved(true);
}
}
void resolve_callback ( DNSServiceRef,
DNSServiceFlags,
uint32_t,
DNSServiceErrorType errorCode,
const char*,
const char *hosttarget,
uint16_t port,
uint16_t txtLen,
const unsigned char *txtRecord,
void *context
)
{
QObject *obj = reinterpret_cast<QObject*>(context);
if (errorCode != kDNSServiceErr_NoError) {
ErrorEvent err;
QCoreApplication::sendEvent(obj, &err);
return;
}
char key[256];
int index=0;
unsigned char valueLen;
kDebug() << "Resolve callback\n";
QMap<QString,QByteArray> map;
const void *voidValue = 0;
while (TXTRecordGetItemAtIndex(txtLen,txtRecord,index++,256,key,&valueLen,
&voidValue) == kDNSServiceErr_NoError)
{
if (voidValue) map[QString::fromUtf8(key)]=QByteArray((const char*)voidValue,valueLen);
else map[QString::fromUtf8(key)].clear();
}
ResolveEvent rev(DNSToDomain(hosttarget),ntohs(port),map);
QCoreApplication::sendEvent(obj, &rev);
}
}
#include "moc_remoteservice.cpp"

View file

@ -1,85 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "mdnsd-responder.h"
#include "servicebase.h"
#include <kurl.h>
#include <QtCore/QCoreApplication>
namespace DNSSD
{
Responder::Responder(DNSServiceRef ref,QObject *parent)
: QObject(parent), m_ref(0), m_socket(0)
{
setRef(ref);
}
void Responder::setRef(DNSServiceRef ref)
{
if (m_socket || m_ref) stop();
m_running = false;
m_ref = ref;
if (m_ref == 0 ) return;
int fd = DNSServiceRefSockFD(ref);
if (fd == -1) return;
m_socket = new QSocketNotifier(fd,QSocketNotifier::Read,this);
connect(m_socket,SIGNAL(activated(int)),this,SLOT(process()));
m_running = true;
}
Responder::~Responder()
{
stop();
}
void Responder::stop()
{
delete m_socket;
m_socket = 0;
if (m_ref) DNSServiceRefDeallocate(m_ref);
m_ref = 0;
m_running = false;
}
void Responder::process()
{
if ( DNSServiceProcessResult(m_ref) != kDNSServiceErr_NoError) stop();
}
bool Responder::isRunning() const
{
return m_running;
}
QByteArray domainToDNS(const QString &domain)
{
if (domainIsLocal(domain)) return domain.toUtf8();
else return KUrl::toAce(domain);
}
QString DNSToDomain(const char* domain)
{
if (domainIsLocal(domain)) return QString::fromUtf8(domain);
else return KUrl::fromAce(domain);
}
}
#include "moc_mdnsd-responder.cpp"

View file

@ -1,69 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef MDNSD_RESPONDER_H
#define MDNSD_RESPONDER_H
#include <QtCore/QObject>
#include <QtCore/QSocketNotifier>
#include <dns_sd.h>
namespace DNSSD
{
/**
This class should not be used directly.
@author Jakub Stachowski
@short Internal class wrapping dns_sd.h interface
*/
class Responder : public QObject
{
Q_OBJECT
public:
explicit Responder(DNSServiceRef ref=0,QObject *parent = 0);
~Responder();
/**
Returns true if it is possible to use mDNS service publishing and discovery.
It needs mDNSResponder running.
*/
bool isRunning() const;
void setRef(DNSServiceRef ref);
void stop();
public Q_SLOTS:
void process();
protected:
DNSServiceRef m_ref;
bool m_running;
QSocketNotifier *m_socket;
};
/* Utils functions */
// Encodes domain name using utf8() or IDN
QByteArray domainToDNS(const QString &domain);
QString DNSToDomain(const char* domain);
}
#endif

View file

@ -1,81 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef MDNSD_SDEVENT_H
#define MDNSD_SDEVENT_H
#include <QtCore/QEvent>
#include <QtCore/QString>
#include <QtCore/QMap>
namespace DNSSD
{
enum Operation { SD_ERROR = 101,SD_ADDREMOVE, SD_PUBLISH, SD_RESOLVE};
class ErrorEvent : public QEvent
{
public:
ErrorEvent() : QEvent((QEvent::Type)(QEvent::User+SD_ERROR))
{}
};
class AddRemoveEvent : public QEvent
{
public:
enum Operation { Add, Remove };
AddRemoveEvent(Operation op,const QString& name,const QString& type,
const QString& domain, bool last) : QEvent((QEvent::Type)(QEvent::User+SD_ADDREMOVE)),
m_op(op), m_name(name), m_type(type), m_domain(domain), m_last(last)
{}
const Operation m_op;
const QString m_name;
const QString m_type;
const QString m_domain;
const bool m_last;
};
class PublishEvent : public QEvent
{
public:
PublishEvent(const QString& name) : QEvent((QEvent::Type)(QEvent::User+SD_PUBLISH)), m_name(name)
{}
const QString m_name;
};
class ResolveEvent : public QEvent
{
public:
ResolveEvent(const QString& hostname, unsigned short port,
const QMap<QString,QByteArray>& txtdata)
: QEvent((QEvent::Type)(QEvent::User+SD_RESOLVE)), m_hostname(hostname),
m_port(port), m_txtdata(txtdata)
{}
const QString m_hostname;
const unsigned short m_port;
const QMap<QString,QByteArray> m_txtdata;
};
}
#endif

View file

@ -1,198 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "mdnsd-servicebrowser_p.h"
#include "domainbrowser.h"
#include "servicebrowser.h"
#include "mdnsd-responder.h"
#include "remoteservice.h"
#include "mdnsd-sdevent.h"
#include <dns_sd.h>
#include <QtCore/QStringList>
#include <QtCore/QHash>
#include <QtCore/QCoreApplication>
#include <QtCore/QTimer>
#include <QtNetwork/QHostInfo>
#define TIMEOUT_WAN 2000
#define TIMEOUT_LAN 200
namespace DNSSD
{
void query_callback (DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode,
const char *serviceName, const char *regtype, const char *replyDomain, void *context);
ServiceBrowser::ServiceBrowser(const QString& type,bool autoResolve,const QString& domain, const QString& subtype)
:d(new ServiceBrowserPrivate(this))
{
d->m_type=type;
d->m_autoResolve=autoResolve;
d->m_domain=domain;
d->m_subtype=subtype;
d->timeout.setSingleShot(true);
connect(&d->timeout,SIGNAL(timeout()),d,SLOT(onTimeout()));
}
ServiceBrowser::State ServiceBrowser::isAvailable()
{
// DNSServiceRef ref;
// bool ok (DNSServiceCreateConnection(&ref)==kDNSServiceErr_NoError);
// if (ok) DNSServiceRefDeallocate(ref);
// return (ok) ? Working : Stopped;
return Working;
}
ServiceBrowser::~ ServiceBrowser()
{
delete d;
}
bool ServiceBrowser::isAutoResolving() const
{
return d->m_autoResolve;
}
void ServiceBrowserPrivate::serviceResolved(bool success)
{
QObject* sender_obj = const_cast<QObject*>(sender());
RemoteService* svr = static_cast<RemoteService*>(sender_obj);
disconnect(svr,SIGNAL(resolved(bool)),this,SLOT(serviceResolved(bool)));
QList<RemoteService::Ptr>::Iterator it = m_duringResolve.begin();
QList<RemoteService::Ptr>::Iterator itEnd = m_duringResolve.end();
while ( it!= itEnd && svr!= (*it).data()) ++it;
if (it != itEnd) {
if (success) {
m_services+=(*it);
emit m_parent->serviceAdded(RemoteService::Ptr(svr));
}
m_duringResolve.erase(it);
queryFinished();
}
}
void ServiceBrowser::startBrowse()
{
if (d->isRunning()) return;
d->m_finished = false;
DNSServiceRef ref;
QString fullType=d->m_type;
if (!d->m_subtype.isEmpty()) fullType=d->m_subtype+"._sub."+d->m_type;
if (DNSServiceBrowse(&ref,0,0, fullType.toLatin1().constData(),
domainToDNS(d->m_domain),query_callback,reinterpret_cast<void*>(d))
== kDNSServiceErr_NoError) d->setRef(ref);
if (!d->isRunning()) emit finished();
else d->timeout.start(domainIsLocal(d->m_domain) ? TIMEOUT_LAN : TIMEOUT_WAN);
}
void ServiceBrowserPrivate::queryFinished()
{
if (!m_duringResolve.count() && m_finished) emit m_parent->finished();
}
QList<RemoteService::Ptr> ServiceBrowser::services() const
{
return d->m_services;
}
RemoteService::Ptr ServiceBrowserPrivate::find(RemoteService::Ptr s, const QList<RemoteService::Ptr>& where) const
{
Q_FOREACH (const RemoteService::Ptr& i, where) if (*s==*i) return i;
return RemoteService::Ptr();
}
void ServiceBrowserPrivate::customEvent(QEvent* event)
{
if (event->type()==QEvent::User+SD_ERROR) {
stop();
m_finished=false;
queryFinished();
}
if (event->type()==QEvent::User+SD_ADDREMOVE) {
AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event);
// m_type has useless trailing dot
RemoteService::Ptr svr(new RemoteService(aev->m_name,aev->m_type.left(aev->m_type.length()-1),aev->m_domain));
if (aev->m_op==AddRemoveEvent::Add) {
if (m_autoResolve) {
connect(svr.data(),SIGNAL(resolved(bool)),this,SLOT(serviceResolved(bool)));
m_duringResolve+=svr;
svr->resolveAsync();
} else {
m_services+=svr;
emit m_parent->serviceAdded(svr);
}
}
else {
RemoteService::Ptr found=find(svr, m_duringResolve);
if (!found.isNull()) m_duringResolve.removeAll(found);
else {
found=find(svr, m_services);
if (!found.isNull()) {
emit m_parent->serviceRemoved(found);
m_services.removeAll(found);
}
}
}
m_finished = aev->m_last;
if (m_finished) queryFinished();
}
}
void ServiceBrowserPrivate::onTimeout()
{
m_finished=true;
queryFinished();
}
void query_callback (DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode,
const char *serviceName, const char *regtype, const char *replyDomain,
void *context)
{
QObject *obj = reinterpret_cast<QObject*>(context);
if (errorCode != kDNSServiceErr_NoError) {
ErrorEvent err;
QCoreApplication::sendEvent(obj, &err);
} else {
AddRemoveEvent arev((flags & kDNSServiceFlagsAdd) ? AddRemoveEvent::Add :
AddRemoveEvent::Remove, QString::fromUtf8(serviceName), regtype,
DNSToDomain(replyDomain), !(flags & kDNSServiceFlagsMoreComing));
QCoreApplication::sendEvent(obj, &arev);
}
}
// TODO: Please Implement Me - Using a KResolver (if not natively)
QHostAddress ServiceBrowser::resolveHostName(const QString &hostname)
{
return QHostAddress();
}
QString ServiceBrowser::getLocalHostName()
{
return QHostInfo::localHostName();
}
}
#include "moc_servicebrowser.cpp"
#include "moc_mdnsd-servicebrowser_p.cpp"

View file

@ -1,60 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef MDNSD_SERVICEBROWSER_P_H
#define MDNSD_SERVICEBROWSER_P_H
#include <QtCore/QObject>
#include <QtCore/QTimer>
#include "mdnsd-responder.h"
#include "servicebrowser.h"
namespace DNSSD
{
class ServiceBrowserPrivate : public Responder
{
Q_OBJECT
public:
ServiceBrowserPrivate(ServiceBrowser* parent) : Responder(), m_parent(parent)
{}
QList<RemoteService::Ptr> m_services;
QList<RemoteService::Ptr> m_duringResolve;
QString m_type;
QString m_domain;
QString m_subtype;
bool m_autoResolve;
bool m_finished;
ServiceBrowser* m_parent;
QTimer timeout;
// get already found service identical to s or null if not found
RemoteService::Ptr find(RemoteService::Ptr s, const QList<RemoteService::Ptr>& where) const;
virtual void customEvent(QEvent* event);
public Q_SLOTS:
void queryFinished();
void serviceResolved(bool success);
void onTimeout();
};
}
#endif

View file

@ -1,72 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "mdnsd-servicetypebrowser_p.h"
#include "servicetypebrowser.h"
#include "servicebrowser.h"
namespace DNSSD
{
ServiceTypeBrowser::ServiceTypeBrowser(const QString& domain,QObject *parent) : QObject(parent),d(new ServiceTypeBrowserPrivate(this))
{
d->m_browser=new ServiceBrowser("_services._dns-sd._udp",false, domain);
connect(d->m_browser,SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)), d, SLOT(newService(DNSSD::RemoteService::Ptr)));
connect(d->m_browser,SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)), d, SLOT(removeService(DNSSD::RemoteService::Ptr)));
connect(d->m_browser,SIGNAL(finished()), this, SIGNAL(finished()));
}
ServiceTypeBrowser::~ServiceTypeBrowser()
{
delete d;
}
QStringList ServiceTypeBrowser::serviceTypes() const
{
return d->m_servicetypes;
}
void ServiceTypeBrowser::startBrowse()
{
d->m_browser->startBrowse();
}
void ServiceTypeBrowserPrivate::newService(DNSSD::RemoteService::Ptr srv)
{
QString type=srv->serviceName()+'.'+srv->type();
m_servicetypes+=type;
emit m_parent->serviceTypeAdded(type);
}
void ServiceTypeBrowserPrivate::removeService(DNSSD::RemoteService::Ptr srv)
{
QString type=srv->serviceName()+'.'+srv->type();
m_servicetypes.removeAll(type);
emit m_parent->serviceTypeRemoved(type);
}
}
#include "moc_servicetypebrowser.cpp"
#include "moc_mdnsd-servicetypebrowser_p.cpp"

View file

@ -1,46 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef MDNSD_SERVICETYPEBROWSER_P_H
#define MDNSD_SERVICETYPEBROWSER_P_H
#include <QtCore/QStringList>
#include "servicebrowser.h"
#include "servicetypebrowser.h"
namespace DNSSD
{
class ServiceTypeBrowserPrivate : public QObject
{
Q_OBJECT
public:
ServiceTypeBrowserPrivate(ServiceTypeBrowser* parent): m_parent(parent) {}
ServiceTypeBrowser* m_parent;
ServiceBrowser* m_browser;
QStringList m_servicetypes;
public Q_SLOTS:
void newService(DNSSD::RemoteService::Ptr);
void removeService(DNSSD::RemoteService::Ptr);
};
}
#endif

View file

@ -1,56 +0,0 @@
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
<!DOCTYPE node SYSTEM "introspect.dtd">
<!-- $Id: DomainBrowser.introspect 948 2005-11-12 18:55:52Z lennart $ -->
<!--
This file is part of avahi.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
avahi 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 Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
-->
<node>
<interface name="org.freedesktop.Avahi.DomainBrowser">
<method name="Free"/>
<signal name="ItemNew">
<arg name="interface" type="i"/>
<arg name="protocol" type="i"/>
<arg name="domain" type="s"/>
<arg name="flags" type="u"/>
</signal>
<signal name="ItemRemove">
<arg name="interface" type="i"/>
<arg name="protocol" type="i"/>
<arg name="domain" type="s"/>
<arg name="flags" type="u"/>
</signal>
<signal name="Failure">
<arg name="error" type="s"/>
</signal>
<signal name="AllForNow"/>
<signal name="CacheExhausted"/>
</interface>
</node>

View file

@ -1,59 +0,0 @@
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
<!DOCTYPE node SYSTEM "introspect.dtd">
<!-- $Id: ServiceBrowser.introspect 948 2005-11-12 18:55:52Z lennart $ -->
<!--
This file is part of avahi.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
avahi 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 Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
-->
<node>
<interface name="org.freedesktop.Avahi.ServiceBrowser">
<method name="Free"/>
<signal name="ItemNew">
<arg name="interface" type="i"/>
<arg name="protocol" type="i"/>
<arg name="name" type="s"/>
<arg name="type" type="s"/>
<arg name="domain" type="s"/>
<arg name="flags" type="u"/>
</signal>
<signal name="ItemRemove">
<arg name="interface" type="i"/>
<arg name="protocol" type="i"/>
<arg name="name" type="s"/>
<arg name="type" type="s"/>
<arg name="domain" type="s"/>
<arg name="flags" type="u"/>
</signal>
<signal name="Failure">
<arg name="error" type="s"/>
</signal>
<signal name="AllForNow"/>
<signal name="CacheExhausted"/>
</interface>
</node>

View file

@ -1,57 +0,0 @@
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
<!DOCTYPE node SYSTEM "introspect.dtd">
<!-- $Id: ServiceTypeBrowser.introspect 948 2005-11-12 18:55:52Z lennart $ -->
<!--
This file is part of avahi.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
avahi 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 Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
-->
<node>
<interface name="org.freedesktop.Avahi.ServiceTypeBrowser">
<method name="Free"/>
<signal name="ItemNew">
<arg name="interface" type="i"/>
<arg name="protocol" type="i"/>
<arg name="type" type="s"/>
<arg name="domain" type="s"/>
<arg name="flags" type="u"/>
</signal>
<signal name="ItemRemove">
<arg name="interface" type="i"/>
<arg name="protocol" type="i"/>
<arg name="type" type="s"/>
<arg name="domain" type="s"/>
<arg name="flags" type="u"/>
</signal>
<signal name="Failure">
<arg name="error" type="s"/>
</signal>
<signal name="AllForNow"/>
<signal name="CacheExhausted"/>
</interface>
</node>

View file

@ -1,233 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef DNSSDPUBLICSERVICE_H
#define DNSSDPUBLICSERVICE_H
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <dnssd/servicebase.h>
namespace DNSSD
{
class PublicServicePrivate;
/**
* @class PublicService publicservice.h DNSSD/PublicService
* @short Represents a service to be published
*
* This class allows you to publish the existence of a network
* service provided by your application.
*
* If you are providing a web server and want to advertise it
* on the local network, you might do
* @code
* DNSSD::PublicService *service = new DNSSD::PublicService("My files", "_http._tcp", 80);
* bool isOK = service->publish();
* @endcode
*
* In this example publish() is synchronous: it will not return
* until publishing is complete. This is usually not too long
* but it can freeze an application's GUI for a moment.
* To publish asynchronously instead, do:
* @code
* DNSSD::PublicService *service = new DNSSD::PublicService("My files", "_http._tcp", 80);
* connect(service, SIGNAL(published(bool)), this, SLOT(wasPublished(bool)));
* service->publishAsync();
* @endcode
*
* @author Jakub Stachowski
*/
class KDNSSD_EXPORT PublicService : public QObject, public ServiceBase
{
Q_OBJECT
public:
/**
* Creates a service description that can be published
*
* If no @p name is given, the computer name is used instead. If there
* is already a service with the same name, type and domain a number will
* be appended to the name to make it unique.
*
* If no @p domain is specified, the service is published on the link-local
* domain (.local).
*
* The subtypes can be used to specify server attributes, such
* as "_anon" for anonymous FTP servers, or can specify a specific protocol
* (such as a web service interface) on top of a generic protocol like SOAP.
*
* There is
* <a href="http://www.dns-sd.org/ServiceTypes.html">a comprehensive list
* of possible types</a> available, but you are largely on your own for
* subtypes.
*
* @param name a service name to use instead of the computer name
* @param type service type, in the form _sometype._udp or _sometype._tcp
* @param port port number, or 0 to "reserve" the service name
* @param domain the domain to publish the service on (see DomainBrowser)
* @param subtypes optional list of subtypes, each with a leading underscore
*
* @see ServiceBrowser::ServiceBrowser()
*/
explicit PublicService(const QString& name = QString(),
const QString& type = QString(),
unsigned int port = 0,
const QString& domain = QString(),
const QStringList& subtypes = QStringList());
~PublicService();
/**
* Stops publishing or aborts an incomplete publish request.
*
* Useful when you want to disable the service for some time.
*
* Note that if you stop providing a service (without exiting the
* application), you should stop publishing it.
*/
void stop();
/**
* Publish the service synchronously
*
* The method will not return (and hence the application interface will
* freeze, since KDElibs code should be executed in the main thread)
* until either the service is published or publishing fails.
*
* published(bool) is emitted before this method returns.
*
* @return @c true if the service was successfully published, @c false otherwise
*/
bool publish();
/**
* Whether the service is currently published
*
* @return @c true if the service is being published to the domain,
* @c false otherwise
*/
bool isPublished() const;
/**
* Publish the service asynchronously
*
* Returns immediately and emits published(bool) when completed.
* Note that published(bool) may be emitted before this method
* returns when an error is detected immediately.
*/
void publishAsync();
/**
* Sets new text properties
*
* If the service is already published, it will be re-announced with
* the new data.
*
* @param textData the new text properties for the service
*
* @see ServiceBase::textData()
*/
void setTextData(const QMap<QString,QByteArray>& textData);
/**
* Sets the name of the service
*
* If the service is already published, it will be re-announced with
* the new name.
*
* @param serviceName the new name of the service
*/
void setServiceName(const QString &serviceName);
/**
* Sets the service type
*
* If the service is already published, it will be re-announced with
* the new type.
*
* @param type the new type of the service
*
* See PublicService() for details on the format of @p type
*/
void setType(const QString& type);
/**
* Sets the subtypetypes of the service
*
* If the service is already published, it will be re-announced with
* the new subtypes.
*
* The existing list of substypes is replaced, so an empty list will
* cause all existing subtypes to be removed.
*
* @param subtypes the new list of subtypes
*/
void setSubTypes(const QStringList& subtypes);
/**
* Sets the port
*
* If the service is already published, it will be re-announced with
* the new port.
*
* @param port the port of the service, or 0 to simply "reserve" the name
*/
void setPort(unsigned short port);
/**
* Sets the domain where the service is published
*
* "local." means link-local, ie: the IP subnet on the LAN containing
* this computer.
*
* If service is already published, it will be removed from the current
* domain and published on @p domain instead.
*
* @param domain the new domain to publish the service on
*/
void setDomain(const QString& domain);
/**
* The subtypes of service.
*
* @see setSubTypes()
*/
QStringList subtypes() const;
Q_SIGNALS:
/**
* Emitted when publishing is complete
*
* It will also emitted when an already-published service is
* republished after a property of the service (such as the
* name or port) is changed.
*/
void published(bool successful);
private:
friend class PublicServicePrivate;
};
}
#endif

View file

@ -1,138 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef DNSSDREMOTESERVICE_H
#define DNSSDREMOTESERVICE_H
#include <QtCore/QObject>
#include <QtCore/QMetaType>
#include <dnssd/servicebase.h>
namespace DNSSD
{
class RemoteServicePrivate;
/**
* @class RemoteService remoteservice.h DNSSD/RemoteService
* @short Describes a service published over DNS-SD,
* typically on a remote machine
*
* This class allows delayed or asynchronous resolution of
* services. As the name suggests, the service is normally
* on a remote machine, but the service could just as easily
* be published on the local machine.
*
* RemoteService instances are normally provided by ServiceBrowser,
* but can be used to resolve any service if you know the name, type
* and domain for it.
*
* @author Jakub Stachowski
*
* @see ServiceBrowser
*/
class KDNSSD_EXPORT RemoteService : public QObject, public ServiceBase
{
Q_OBJECT
public:
typedef KSharedPtr<RemoteService> Ptr;
/**
* Creates an unresolved RemoteService representing the service with
* the given name, type and domain
*
* @param name the name of the service
* @param type the type of the service (see ServiceBrowser::ServiceBrowser())
* @param domain the domain of the service
*
* @see ServiceBrowser::isAvailable()
*/
RemoteService(const QString& name, const QString& type, const QString& domain);
virtual ~RemoteService();
/**
* Resolves the host name and port of service asynchronously
*
* The host name is not resolved into an IP address - use KResolver
* for that.
*
* The resolved(bool) signal will be emitted when the
* resolution is complete, or when it fails.
*
* Note that resolved(bool) may be emitted before this function
* returns in case of immediate failure.
*
* RemoteService will keep monitoring the service for
* changes in hostname and port, and re-emit resolved(bool)
* when either changes.
*
* @see resolve(), hostName(), port()
*/
void resolveAsync();
/**
* Resolves the host name and port of service synchronously
*
* The host name is not resolved into an IP address - use KResolver
* for that.
*
* resolved(bool) is emitted before this function is returned.
*
* resolve() will not cause RemoteService to monitor for changes
* in the hostname or port of the service.
*
* @return @c true if successful, @c false on failure
*
* @see resolveAsync(), hostName(), port()
*/
bool resolve();
/**
* Whether the service has been successfully resolved
*
* @return @c true if hostName() and port() will return
* valid values, @c false otherwise
*/
bool isResolved() const;
Q_SIGNALS:
/**
* Emitted when resolving is complete
*
* If operating in asynchronous mode this signal can be
* emitted several times (when the hostName or port of
* the service changes).
*
* @param successful @c true if the hostName and port were
* successfully resolved, @c false otherwise
*/
void resolved(bool successful);
private:
friend class RemoteServicePrivate;
};
}
Q_DECLARE_METATYPE(DNSSD::RemoteService::Ptr)
#endif

View file

@ -1,88 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "servicebase.h"
#include "servicebase_p.h"
#include <QtCore/QRegExp>
#include <QtCore/QDataStream>
#include <QtCore/QUrl>
namespace DNSSD
{
ServiceBase::ServiceBase(const QString& name, const QString& type, const QString& domain,
const QString& host, unsigned short port)
: d(new ServiceBasePrivate(name,type,domain,host,port))
{}
ServiceBase::ServiceBase(ServiceBasePrivate* const _d)
: d(_d)
{}
ServiceBase::~ServiceBase()
{
delete d;
}
QString ServiceBase::serviceName() const
{
return d->m_serviceName;
}
QString ServiceBase::type() const
{
return d->m_type;
}
QString ServiceBase::domain() const
{
return d->m_domain;
}
QString ServiceBase::hostName() const
{
return d->m_hostName;
}
unsigned short ServiceBase::port() const
{
return d->m_port;
}
QMap<QString,QByteArray> ServiceBase::textData() const
{
return d->m_textData;
}
bool ServiceBase::operator==(const ServiceBase& o) const
{
return d->m_domain==o.d->m_domain && d->m_serviceName==o.d->m_serviceName && d->m_type==o.d->m_type;
}
bool ServiceBase::operator!=(const ServiceBase& o) const
{
return !(*this == o);
}
bool domainIsLocal(const QString& domain)
{
return domain.section('.',-1,-1).toLower()==QLatin1String("local");
}
}

View file

@ -1,203 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef DNSSDSERVICEBASE_H
#define DNSSDSERVICEBASE_H
#include <QtCore/QMap>
#include <QtCore/QString>
#include <ksharedptr.h>
#include <dnssd/kdnssd_export.h>
namespace DNSSD
{
class ServiceBasePrivate;
/**
* @class ServiceBase servicebase.h DNSSD/ServiceBase
* @short Describes a service
*
* This class is used to describe a service. The service
* can be published by the current application (in which
* case it is probably a PublicService) or by
* another application, either on the current machine or
* a remote machine, in which case it is probably a
* RemoteService returned by ServiceBrowser.
*
* You should not normally need to create a ServiceBase
* object yourself.
*
* @author Jakub Stachowski
*
* @see PublicService
*/
class KDNSSD_EXPORT ServiceBase : public QSharedData //krazy:exclude=dpointer (protected)
{
public:
typedef KSharedPtr<ServiceBase> Ptr;
/**
* Creates a ServiceBase object
*
* Note that @p name, @p type and @p domain uniquely identify
* the service in the DNS-SD system, and @p host and @p port
* provide the actual location of the service.
*
* For example, RemoteService populates @p host and @p port
* based on the @p name, @p type and @p domain attributes
* using the DNS-SD resolution system.
*
* @param name service name
* @param type service type
* @param domain the DNS-SD domain name for service
* @param host the host name of the service (a fully-qualified domain name)
* @param port the port number of the service
*/
explicit ServiceBase(const QString& name = QString(),
const QString& type = QString(),
const QString& domain = QString(),
const QString& host = QString(),
unsigned short port = 0);
virtual ~ServiceBase();
/**
* The name of the service
*/
QString serviceName() const;
/**
* The type of the service
*
* This is always in the format _sometype._udp or _sometype._tcp.
*
* See the <a href="http://www.dns-sd.org">DNS-SD website</a> for
* <a href="http://www.dns-sd.org/ServiceTypes.html">a full list of service types</a>.
*/
QString type() const;
/**
* The domain that the service belongs to
*
* It is "local." for link-local services.
*/
QString domain() const;
/**
* The hostname of the service
*
* Only valid for local and resolved remote services.
*
* Together with port(), this can be used to actually
* access the service.
*
* @see RemoteService::resolve() and RemoteService::resolveAsync()
*/
QString hostName() const;
/**
* The port number of the service
*
* Only valid for local and resolved remote services.
*
* Together with hostName(), this can be used to actually
* access the service.
*
* @see RemoteService::resolve() and RemoteService::resolveAsync()
*/
unsigned short port() const;
/**
* Additional text data associated with the service
*
* Only valid for local and resolved remote services.
*
* This is data that provides additional information about the
* service. For example, it might be used to specify a printer
* queue on the printer server specified by hostName() and port().
*
* You can check for the data that might be associated with a
* particular service on the <a
* href="http://www.dns-sd.org/ServiceTypes.html">service types list</a>.
* If a @c key=value pair is given, this will appear with the @c value
* in a QByteArray indexed by the @c key. If the data is on its own
* (does not have an @c = in it), it will be used to index an empty
* QByteArray, and can be checked for with QMap::contains().
*
* For example, if you are accessing the _ipp._tcp service, you might
* do something like
* @code
* QString printerModel = "unknown";
* if (service->textData().contains("ty")) {
* printQueue = QString::fromUtf8(service->textData()["ty"].constData());
* }
* @endcode
* since the TXT data of the IPP service may contain data like
* "ty=Apple LaserWriter Pro 630". Note that you actually have to be
* a bit more clever than this, since the key should usually be case
* insensitive.
*/
QMap<QString,QByteArray> textData() const;
/**
* Compares services based on name, type and domain
*
* This is enough to for unique identification and omitting
* port, host and text data allows to compare resolved and
* unresolved services
*
* @param o the service to compare this service to
* @return @c true if this service represents the same
* service (from the point of view of DNS-SD) as
* @p o, @c false otherwise
*/
bool operator==(const ServiceBase& o) const;
/**
* Compares services based on name, type and domain
*
* This is enough to for unique identification and omitting
* port, host and text data allows to compare resolved and
* unresolved services
*
* @param o the service to compare this service to
* @return @c false if this service represents the same
* service (from the point of view of DNS-SD) as
* @p o, @c true otherwise
*/
bool operator!=(const ServiceBase& o) const;
protected:
ServiceBase(ServiceBasePrivate* const d);
ServiceBasePrivate* const d;
};
/* Utility functions */
/**
* Check if the domain is link-local
*
* @return @c true if domain is link-local ('local.'), @c false otherwise
*/
bool domainIsLocal(const QString& domain);
}
#endif

View file

@ -1,50 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004, 2007 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef SERVICEBASE_P_H
#define SERVICEBASE_P_H
#include <QtCore/QMap>
#include <QtCore/QString>
namespace DNSSD {
class ServiceBasePrivate
{
public:
ServiceBasePrivate(const QString& name, const QString& type, const QString& domain,
const QString& host, unsigned short port) : m_serviceName(name), m_type(type),
m_domain(domain), m_hostName(host), m_port(port) {}
virtual ~ServiceBasePrivate() {}
QString m_serviceName;
QString m_type;
QString m_domain;
QString m_hostName;
unsigned short m_port;
/**
Map of TXT properties
*/
QMap<QString,QByteArray> m_textData;
};
}
#endif

View file

@ -1,290 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef DNSSDSERVICEBROWSER_H
#define DNSSDSERVICEBROWSER_H
#include <QtCore/QObject>
#include <QtNetwork/QHostAddress>
#include <dnssd/remoteservice.h>
namespace DNSSD
{
class DomainBrowser;
class ServiceBrowserPrivate;
/**
* @class ServiceBrowser servicebrowser.h DNSSD/ServiceBrowser
* @short Browses for network services advertised over DNS-SD
*
* This is the central class in the DNSSD library for applications
* that want to discover services on network.
*
* Suppose that you need list of web servers running. Then you
* might do something like
* @code
* DNSSD::ServiceBrowser* browser = new DNSSD::ServiceBrowser("_http._tcp");
* connect(browser, SIGNAL(serviceAdded(RemoteService::Ptr)),
* this, SLOT(addService(RemoteService::Ptr)));
* connect(browser, SIGNAL(serviceRemoved(RemoteService::Ptr)),
* this, SLOT(delService(RemoteService::Ptr)));
* browser->startBrowse();
* @endcode
*
* In above example addService() will be called for every web server
* already running and for every web service that subsequently
* appears on the network and delService() will be called when
* a server previously advertised is stopped.
*
* Because no domain was passed to constructor, the default domain
* will be searched. To find other domains to browse for services on,
* use DomainBrowser.
*
* @author Jakub Stachowski
*/
class KDNSSD_EXPORT ServiceBrowser : public QObject
{
Q_OBJECT
public:
/**
* Availability of DNS-SD services
*/
enum State {
/** the service is available */
Working,
/** not available because mDnsd or Avahi daemon is not running */
Stopped,
/** not available because KDE was compiled without DNS-SD support */
Unsupported
};
/**
* Create a ServiceBrowser for a particular service type
*
* DomainBrowser can be used to find other domains to browse on.
* If no domain is given, the default domain is used.
*
* The service type is the high-level protocol type, followed by a dot,
* followed by the transport protocol type (@c _tcp or @c _udp).
* The <a href="http://www.dns-sd.org">DNS-SD website</a> maintains
* <a href="http://www.dns-sd.org/ServiceTypes.html">a full list</a>
* of service types.
*
* The @p subtype parameter allows you to do more fine-grained filtering
* on the services you are interested in. So you might request only
* FTP servers that allow anonymous access by passing "_ftp._tcp" as the
* @p type and "_anon" as the @p subtype. Subtypes are particularly
* important for types like _soap and _upnp, which are far too generic
* for most applications. In these cases, the subtype can be used to
* specify the particular SOAP or UPnP protocol they want.
*
* @warning
* Enabling @p autoResolve will increase network usage by resolving
* all services, so this feature should be used only when necessary.
*
* @param type service types to browse for (example: "_http._tcp")
* @param autoResolve discovered services will be resolved before being
* reported with the serviceAdded() signal
* @param domain a domain to search on instead of the default one
* @param subtype only browse for a specific subtype
*
* @see startBrowse() and isAvailable()
*/
explicit ServiceBrowser(const QString& type,
bool autoResolve = false,
const QString& domain = QString(),
const QString& subtype = QString());
~ServiceBrowser();
/**
* The currently known services of the specified type
*
* @returns a list of RemoteService pointers
*
* @see serviceAdded() and serviceRemoved()
*/
QList<RemoteService::Ptr> services() const;
/**
* Starts browsing for services
*
* Only the first call to this function will have any effect.
*
* Browsing stops when the ServiceBrowser object is destroyed.
*
* @warning The serviceAdded() signal may be emitted before this
* function returns.
*
* @see serviceAdded(), serviceRemoved() and finished()
*/
virtual void startBrowse();
/**
* Checks availability of DNS-SD services
*
* Although this method is part of ServiceBrowser, none of the classes
* in this library will be able to perform their intended function
* if this method does not return Working.
*
* If this method does not return Working, it is still safe to call
* any of the methods in this library. However, no services will be
* found or published and no domains will be found.
*
* If you use this function to report an error to the user, below
* is a suggestion on how to word the errors when publishing a
* service. The first line of each error message can also be
* used for reporting errors when browsing for services.
*
* @code
* switch(DNSSD::ServiceBrowser::isAvailable()) {
* case DNSSD::ServiceBrowser::Working:
* return "";
* case DNSSD::ServiceBrowser::Stopped:
* return i18n("<p>The Zeroconf daemon is not running. See the Service"
* " Discovery Handbook for more information.<br/>"
* "Other users will not see the services provided by this
* " system when browsing the network via zeroconf, but "
* " normal access will still work.</p>");
* case DNSSD::ServiceBrowser::Unsupported:
* return i18n("<p>Zeroconf support is not available in this version of KDE."
* " See the Service Discovery Handbook for more information.<br/>"
* "Other users will not see the services provided by this
* " application when browsing the network via zeroconf, but "
* " normal access will still work.</p>");
* default:
* return i18n("<p>Unknown error with Zeroconf.<br/>"
* "Other users will not see the services provided by this
* " application when browsing the network via zeroconf, but "
* " normal access will still work.</p>");
* }
* @endcode
*
*/
static State isAvailable();
/**
* Whether discovered services are resolved before being reported
*
* @return the value of the @p autoResolve parameter passed to the constructor
*
* @since 4.1
*/
bool isAutoResolving() const;
/**
* Resolves an mDNS hostname into an IP address
*
* This function is very rarely useful, since a properly configured
* system is able to resolve an mDNS-based host name using the system
* resolver (ie: you can just pass the mDNS hostname to KIO or other
* library).
*
* @param hostname the hostname to be resolved
* @return a QHostAddress containing the IP address, or QHostAddress() if
* resolution failed
* @since 4.2
*/
static QHostAddress resolveHostName(const QString& hostname);
/**
* The mDNS hostname of the local machine
*
* Usually this will return the same as QHostInfo::localHostName(),
* but it may be changed to something different
* in the Avahi configuration file (if using the Avahi backend).
*
* @return the hostname, or an empty string on failure
* @since 4.2
*/
static QString getLocalHostName();
Q_SIGNALS:
/**
* Emitted when new service is discovered
*
* If isAutoResolving() returns @c true, this will not be emitted
* until the service has been resolved.
*
* @param service a RemoteService object describing the service
*
* @see serviceRemoved() and finished()
*/
void serviceAdded(DNSSD::RemoteService::Ptr service);
/**
* Emitted when a service is no longer published over DNS-SD
*
* The RemoteService object is removed from the services() list
* and deleted immediately after this signal returns.
*
* @warning
* Do @b not use a delayed connection with this signal
*
* @param service a RemoteService object describing the service
*
* @see serviceAdded() and finished()
*/
void serviceRemoved(DNSSD::RemoteService::Ptr service);
/**
* Emitted when the list of published services has settled
*
* This signal is emitted once after startBrowse() is called
* when all the services of the requested type that are
* currently published have been reported (even if none
* are available or the DNS-SD service is not available).
* It is emitted again when a new batch of services become
* available or disappear.
*
* For example, if a new host is connected to network and
* announces some services watched for by this ServiceBrowser,
* they will be reported by one or more serviceAdded() signals
* and the whole batch will be concluded by finished().
*
* This signal can be used by applications that just want to
* get a list of the currently available services
* (similar to a directory listing) and do not care about
* adding or removing services that appear or disappear later.
*
* @warning
* There is no guarantee any RemoteService
* pointers received by serviceAdded() will be valid
* by the time this signal is emitted, so you should either
* do all your work involving them in the slot receiving
* the serviceAdded() signal, or you should listen to
* serviceRemoved() as well.
*
* @see serviceAdded() and serviceRemoved()
*/
void finished();
private:
friend class ServiceBrowserPrivate;
ServiceBrowserPrivate* const d;
};
}
#endif

View file

@ -1,108 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2008 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "servicemodel.h"
#include "servicebrowser.h"
#include <klocale.h>
namespace DNSSD
{
struct ServiceModelPrivate
{
ServiceBrowser* m_browser;
};
ServiceModel::ServiceModel(ServiceBrowser* browser, QObject* parent)
: QAbstractItemModel(parent), d(new ServiceModelPrivate)
{
d->m_browser=browser;
browser->setParent(this);
connect(browser, SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)), this,
SIGNAL(layoutChanged()));
connect(browser, SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)), this,
SIGNAL(layoutChanged()));
browser->startBrowse();
}
ServiceModel::~ServiceModel()
{
delete d;
}
int ServiceModel::columnCount(const QModelIndex&) const
{
return d->m_browser->isAutoResolving() ? 3 : 1;
}
int ServiceModel::rowCount(const QModelIndex& parent ) const
{
return (parent.isValid()) ? 0 : d->m_browser->services().size();
}
QModelIndex ServiceModel::parent(const QModelIndex&) const
{
return QModelIndex();
}
QModelIndex ServiceModel::index(int row, int column, const QModelIndex& parent ) const
{
return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex();
}
bool ServiceModel::hasIndex(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid()) return false;
if (column<0 || column>=columnCount()) return false;
if (row<0 || row>=rowCount(parent)) return false;
return true;
}
QVariant ServiceModel::data(const QModelIndex& index, int role ) const
{
if (!index.isValid()) return QVariant();
if (!hasIndex(index.row(), index.column(), index.parent())) return QVariant();
const QList<RemoteService::Ptr> srv=d->m_browser->services();
switch (role) {
case Qt::DisplayRole:
switch (index.column()) {
case ServiceName: return srv[index.row()]->serviceName();
case Host: return srv[index.row()]->hostName();
case Port: return srv[index.row()]->port();
}
case ServicePtrRole: QVariant ret;
ret.setValue(srv[index.row()]);
return ret;
}
return QVariant();
}
QVariant ServiceModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation!=Qt::Horizontal || role!=Qt::DisplayRole) return QVariant();
switch (section) {
case ServiceName: return i18n("Name");
case Host: return i18n("Host");
case Port: return i18n("Port");
}
return QVariant();
}
}

View file

@ -1,126 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2008 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef DNSSDSERVICEMODEL_H
#define DNSSDSERVICEMODEL_H
#include <QtCore/QAbstractItemModel>
#include <dnssd/kdnssd_export.h>
#include <dnssd/remoteservice.h>
namespace DNSSD
{
struct ServiceModelPrivate;
class ServiceBrowser;
/**
* @class ServiceModel servicemodel.h DNSSD/ServiceModel
* @short Model for list of Zeroconf services
*
* This class provides a Qt Model for ServiceBrowser to allow easy
* integration of service discovery into a GUI. For example, to
* show the HTTP servers published on the local network, you can do:
* @code
* DNSSD::ServiceModel *serviceModel = new ServiceModel(
* new DNSSD::ServiceBrowser("_http._tcp")
* );
* QComboBox *serviceCombo = new QComboBox();
* serviceCombo->setModel(serviceModel);
* @endcode
*
* After the user makes a selection, the application typically needs
* to get a pointer to the selected service in order to get the host
* name and port. A RemoteService::Ptr can be obtained from
* a QModelIndex using:
* @code
* void onSelected(const QModelIndex &selection) {
* DNSSD::RemoteService::Ptr service =
* selection.data(DNSSD::ServiceModel::ServicePtrRole)
* .value<DNSSD::RemoteService::Ptr>();
* }
* @endcode
*
* @since 4.1
* @author Jakub Stachowski
*/
class KDNSSD_EXPORT ServiceModel : public QAbstractItemModel
{
Q_OBJECT
public:
/** The additional data roles provided by this model */
enum AdditionalRoles {
ServicePtrRole = Qt::UserRole + 1 ///< gets a RemoteService::Ptr for the service
};
/**
* The default columns for this model.
*
* If service browser is not set to resolve automatically,
* then the model will only ever have one column (the service name).
*/
enum ModelColumns {
ServiceName = 0,
Host = 1,
Port = 2
};
/**
* Creates a model for the given service browser and starts browsing
* for services.
*
* The model takes ownership of the browser,
* so there is no need to delete it afterwards.
*
* You should @b not call ServiceBrowser::startBrowse() on @p browser
* before passing it to ServiceModel.
*/
explicit ServiceModel(ServiceBrowser* browser, QObject* parent = 0);
virtual ~ServiceModel();
/** @reimp */
virtual int columnCount(const QModelIndex& parent = QModelIndex() ) const;
/** @reimp */
virtual int rowCount(const QModelIndex& parent = QModelIndex() ) const;
/** @reimp */
virtual QModelIndex parent(const QModelIndex& index ) const;
/** @reimp */
virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex() ) const;
/** @reimp */
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole ) const;
/** @reimp */
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
/** @reimp */
virtual bool hasIndex(int row, int column, const QModelIndex &parent) const;
private:
ServiceModelPrivate* const d;
friend struct ServiceModelPrivate;
};
}
#endif

View file

@ -1,146 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef DNSSDSERVICETYPEBROWSER_H
#define DNSSDSERVICETYPEBROWSER_H
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <dnssd/remoteservice.h>
namespace DNSSD
{
class ServiceTypeBrowserPrivate;
/**
* @class ServiceBrowser servicebrowser.h DNSSD/ServiceBrowser
* @short Browses the service types being published on a domain
*
* This class is mostly useful for generic utilities for
* browsing all the published services on a local network.
* Applications that wish to find out about available services
* of a particular type (such as web servers) should use
* ServiceBrowser.
*
* ServiceTypeBrowser provides a list of all the service types
* published by at least one service on a given domain.
*
* @author Jakub Stachowski
*/
class KDNSSD_EXPORT ServiceTypeBrowser : public QObject
{
Q_OBJECT
public:
/**
* Create a ServiceTypeBrowser for a domain
*
* The link-local domain (the LAN subnet for this computer) will
* be used if no @p domain is given. DomainBrowser can be used
* to get a list of browsing domains.
*
* Note that WAN domains may not support service type browsing.
*
* @param domain a browsing domain to search
* @param parent the parent object (see QObject documentation)
*
* @see startBrowse() and ServiceBrowser::isAvailable()
*/
explicit ServiceTypeBrowser(const QString& domain = QString(),
QObject* parent = 0);
~ServiceTypeBrowser();
/**
* All the service types currently being published
*
* @return a list of service types, in the form _type._tcp or _type._udp
*/
QStringList serviceTypes() const;
/**
* Starts browsing
*
* Only the first call to this function will have any effect.
*
* Browsing stops when the ServiceBrowser object is destroyed.
*
* @warning The serviceTypeAdded() signal may be emitted before this
* function returns.
*
* @see serviceTypeAdded(), serviceTypeRemoved() and finished()
*/
void startBrowse();
Q_SIGNALS:
/**
* Emitted when there are no more services of this type
*
* @warning
* This signal is not reliable: it is possible that it will not be
* emitted even after last service of this type disappeared
*
* @param type the service type
*
* @see serviceTypeAdded() and finished()
*/
void serviceTypeRemoved(const QString& type);
/**
* A new type of service has been found
*
* @param type the service type
*
* @see serviceTypeAdded() and finished()
*/
void serviceTypeAdded(const QString& type);
/**
* Emitted when the list of published service types has settled
*
* This signal is emitted once after startBrowse() is called
* when the types of all the services that are
* currently published have been reported (even if no services
* are available or the DNS-SD service is not available).
* It is emitted again when a new batch of service types become
* available or disappear.
*
* For example, if a new host is connected to network and
* announces services of several new types,
* they will be reported by several serviceTypeAdded() signals
* and the whole batch will be concluded by finished().
*
* This signal can be used by applications that just want to
* get a list of the currently available service types
* (similar to a directory listing) and do not care about
* adding or removing service types that appear or disappear later.
*
* @see serviceTypeAdded() and serviceTypeRemoved()
*/
void finished();
private:
friend class ServiceTypeBrowserPrivate;
ServiceTypeBrowserPrivate* const d;
};
}
#endif

View file

@ -1,12 +0,0 @@
ClassName=Configuration
File=kcm_kdnssd.kcfg
GlobalEnums=false
Inherits=KCoreConfigSkeleton
ItemAccessors=false
MemberVariables=private
Mutators=true
NameSpace=DNSSD
SetUserTexts=false
Singleton=true
Visibility=KDNSSD_EXPORT
IncludeFiles=dnssd/kdnssd_export.h

View file

@ -401,21 +401,6 @@ install(
COMPONENT Devel
)
install(
FILES
DNSSD/Configuration
DNSSD/DomainBrowser
DNSSD/DomainModel
DNSSD/PublicService
DNSSD/RemoteService
DNSSD/ServiceBase
DNSSD/ServiceBrowser
DNSSD/ServiceModel
DNSSD/ServiceTypeBrowser
DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE/DNSSD
COMPONENT Devel
)
install(
FILES
KAccelGen/Deref

View file

@ -1 +0,0 @@
#include "../../dnssd/settings.h"

View file

@ -1 +0,0 @@
#include "../../dnssd/domainbrowser.h"

View file

@ -1 +0,0 @@
#include "../../dnssd/domainmodel.h"

View file

@ -1 +0,0 @@
#include "../../dnssd/publicservice.h"

View file

@ -1 +0,0 @@
#include "../../dnssd/remoteservice.h"

View file

@ -1 +0,0 @@
#include "../../dnssd/servicebase.h"

View file

@ -1 +0,0 @@
#include "../../dnssd/servicebrowser.h"

View file

@ -1 +0,0 @@
#include "../../dnssd/servicemodel.h"

View file

@ -1 +0,0 @@
#include "../../dnssd/servicetypebrowser.h"

View file

@ -200,6 +200,9 @@
# kpowermanager
51005 kpowermanager
# kdnssd
51006 kdnssd
# kdemultimedia
67100 kmix

View file

@ -11,6 +11,7 @@ add_subdirectory(kmediaplayer)
add_subdirectory(kexiv2)
add_subdirectory(kpasswdstore)
add_subdirectory(kpowermanager)
add_subdirectory(kdnssd)
######## kidletime ####################

View file

@ -0,0 +1,43 @@
if(AVAHI_FOUND)
include_directories(${AVAHI_INCLUDE_DIR})
add_definitions(-DHAVE_AVAHI)
endif()
add_definitions(-DKDE_DEFAULT_DEBUG_AREA=51006)
set(kdnssd_LIB_SRCS
kdnssd.cpp
)
add_library(kdnssd ${LIBRARY_TYPE} ${kdnssd_LIB_SRCS})
target_link_libraries(kdnssd PUBLIC
${KDE4_KDECORE_LIBS}
${QT_QTCORE_LIBRARY}
${QT_QTNETWORK_LIBRARY}
)
if(AVAHI_FOUND)
target_link_libraries(kdnssd PRIVATE ${AVAHI_LIBRARIES})
endif()
set_target_properties(kdnssd PROPERTIES
VERSION ${GENERIC_LIB_VERSION}
SOVERSION ${GENERIC_LIB_SOVERSION}
)
generate_export_header(kdnssd)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/kdnssd_export.h
kdnssd.h
DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}
COMPONENT Devel
)
install(
TARGETS kdnssd
EXPORT kdelibsLibraryTargets
${INSTALL_TARGETS_DEFAULT_ARGS}
)

425
kutils/kdnssd/kdnssd.cpp Normal file
View file

@ -0,0 +1,425 @@
/* This file is part of the KDE libraries
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2, as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kdnssd.h"
#include "kurl.h"
#include "kdebug.h"
#include <QCoreApplication>
#include <QThread>
#if defined(HAVE_AVAHI)
# include <avahi-client/client.h>
# include <avahi-client/publish.h>
# include <avahi-client/lookup.h>
# include <avahi-common/simple-watch.h>
# include <avahi-common/error.h>
#endif
class KDNSSDPrivate : public QObject
{
Q_OBJECT
public:
KDNSSDPrivate(QObject *parent);
~KDNSSDPrivate();
bool publishService(const QByteArray &servicetype, const uint serviceport, const QString &servicename);
bool unpublishService();
void startBrowse(const QByteArray &servicetype);
QList<KDNSSDService> services();
#if defined(HAVE_AVAHI)
static void clientCallback(AvahiClient *avahiclient, AvahiClientState avahistate, void *userdata);
static void groupCallback(AvahiEntryGroup *avahigroup, AvahiEntryGroupState avahistate, void *userdata);
static void browseCallback(AvahiServiceBrowser *avahibrowser, AvahiIfIndex avahiinterface,
AvahiProtocol avahiprotocol, AvahiBrowserEvent avahievent,
const char *avahiname, const char *avahitype, const char *avahidomain,
AvahiLookupResultFlags avahiflags,
void* userdata);
static void resolveCallback(AvahiServiceResolver *avahiresolver, AvahiIfIndex avahiinterface,
AvahiProtocol avahiprotocol, AvahiResolverEvent avahievent,
const char *avahiname, const char *avahitype, const char *avahidomain, const char *avahihost_name,
const AvahiAddress *avahiaddress, uint16_t avahiport,
AvahiStringList *avahitxt,
AvahiLookupResultFlags avahiflags,
void* userdata);
static void serviceCallback(AvahiServiceTypeBrowser *avahiservice,
AvahiIfIndex avahiinterface,
AvahiProtocol avahiprotocol,
AvahiBrowserEvent avahievent,
const char *avahitype,
const char *avahidomain,
AvahiLookupResultFlags avahiflags,
void *userdata);
private:
int m_poll;
AvahiSimplePoll *m_avahipoll;
AvahiClient *m_avahiclient;
AvahiEntryGroup *m_avahigroup;
QList<KDNSSDService> m_services;
QList<QByteArray> m_servicetypes;
#endif // HAVE_AVAHI
};
KDNSSDPrivate::KDNSSDPrivate(QObject *parent)
: QObject(parent)
#if defined(HAVE_AVAHI)
, m_poll(0),
m_avahipoll(nullptr),
m_avahiclient(nullptr),
m_avahigroup(nullptr)
#endif
{
#if defined(HAVE_AVAHI)
m_avahipoll = avahi_simple_poll_new();
if (!m_avahipoll) {
kWarning() << "Could not create Avahi poll";
return;
}
int avahierror = 0;
m_avahiclient = avahi_client_new(
avahi_simple_poll_get(m_avahipoll), AVAHI_CLIENT_NO_FAIL,
KDNSSDPrivate::clientCallback, this,
&avahierror
);
if (!m_avahiclient) {
kWarning() << "Could not create Avahi client" << avahi_strerror(avahierror);
return;
}
#endif // HAVE_AVAHI
}
KDNSSDPrivate::~KDNSSDPrivate()
{
#if defined(HAVE_AVAHI)
m_poll = 0;
if (m_avahigroup) {
avahi_entry_group_reset(m_avahigroup);
}
if (m_avahiclient) {
avahi_client_free(m_avahiclient);
}
if (m_avahipoll) {
avahi_simple_poll_free(m_avahipoll);
}
#endif // HAVE_AVAHI
}
bool KDNSSDPrivate::publishService(const QByteArray &servicetype, const uint serviceport, const QString &servicename)
{
#if defined(HAVE_AVAHI)
if (m_avahigroup) {
avahi_entry_group_reset(m_avahigroup);
}
m_avahigroup = avahi_entry_group_new(m_avahiclient, KDNSSDPrivate::groupCallback, this);
if (!m_avahigroup) {
kWarning() << "Could not create Avahi group";
return false;
}
const QByteArray servicenamebytes = servicename.toUtf8();
// qDebug() << Q_FUNC_INFO << servicenamebytes << servicetype;
int avahiresult = avahi_entry_group_add_service(
m_avahigroup,
AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
AvahiPublishFlags(0),
servicenamebytes.constData(), servicetype.constData(), NULL, NULL, serviceport,
NULL
);
if (avahiresult < 0) {
kWarning() << "Could not add Avahi service to group" << avahi_strerror(avahiresult);
return false;
}
avahiresult = avahi_entry_group_commit(m_avahigroup);
return (avahiresult >= 0);
#else
return false;
#endif
}
bool KDNSSDPrivate::unpublishService()
{
#if defined(HAVE_AVAHI)
if (!m_avahigroup) {
return true;
}
const int avahiresult = avahi_entry_group_reset(m_avahigroup);
if (avahiresult < 0) {
kWarning() << "Could not reset Avahi service group" << avahi_strerror(avahiresult);
return false;
}
return true;
#else
return false;
#endif
}
void KDNSSDPrivate::startBrowse(const QByteArray &servicetype)
{
// qDebug() << Q_FUNC_INFO << servicetype;
QList<QByteArray> servicetypes;
if (servicetype.isEmpty()) {
AvahiServiceTypeBrowser* avahiservice = avahi_service_type_browser_new(
m_avahiclient,
AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL,
AvahiLookupFlags(0),
KDNSSDPrivate::serviceCallback, this
);
if (!avahiservice) {
kWarning() << "Could not create Avahi service type browser" << avahi_strerror(avahi_client_errno(m_avahiclient));
return;
}
m_poll++;
m_servicetypes.clear();
while (m_poll) {
// qDebug() << Q_FUNC_INFO << m_poll;
avahi_simple_poll_iterate(m_avahipoll, 0);
}
avahi_service_type_browser_free(avahiservice);
servicetypes = m_servicetypes;
} else {
servicetypes.append(servicetype);
}
m_services.clear();
foreach (const QByteArray &servicetypeit, servicetypes) {
AvahiServiceBrowser *avahibrowser = avahi_service_browser_new(
m_avahiclient,
AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, servicetypeit.constData(), NULL,
AvahiLookupFlags(0),
KDNSSDPrivate::browseCallback, this
);
if (!avahibrowser) {
kWarning() << "Could not create Avahi browser" << avahi_strerror(avahi_client_errno(m_avahiclient));
return;
}
m_poll++;
while (m_poll) {
// qDebug() << Q_FUNC_INFO << m_poll;
avahi_simple_poll_iterate(m_avahipoll, 0);
}
avahi_service_browser_free(avahibrowser);
}
// TODO: filter IPv6 if IPv4 addresses are available or vice-versa?
}
QList<KDNSSDService> KDNSSDPrivate::services()
{
#if defined(HAVE_AVAHI)
return m_services;
#else
static const QList<KDNSSDService> result;
return result;
#endif
}
#if defined(HAVE_AVAHI)
void KDNSSDPrivate::groupCallback(AvahiEntryGroup *avahigroup, AvahiEntryGroupState avahistate, void *userdata)
{
// qDebug() << Q_FUNC_INFO << avahigroup << avahistate << userdata;
if (avahistate == AVAHI_ENTRY_GROUP_FAILURE) {
kWarning() << avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(avahigroup)));
}
}
void KDNSSDPrivate::clientCallback(AvahiClient *avahiclient, AvahiClientState avahistate, void *userdata)
{
// qDebug() << Q_FUNC_INFO << avahistate << userdata;
if (avahistate == AVAHI_CLIENT_FAILURE) {
kWarning() << avahi_strerror(avahi_client_errno(avahiclient));
// avahi_simple_poll_quit(m_avahiclient);
}
}
void KDNSSDPrivate::browseCallback(AvahiServiceBrowser *avahibrowser, AvahiIfIndex avahiinterface,
AvahiProtocol avahiprotocol, AvahiBrowserEvent avahievent,
const char *avahiname, const char *avahitype, const char *avahidomain,
AvahiLookupResultFlags avahiflags,
void* userdata)
{
// qDebug() << Q_FUNC_INFO << avahievent << avahiname << avahitype << avahidomain << userdata;
KDNSSDPrivate *kdnssdprivate = static_cast<KDNSSDPrivate*>(userdata);
AvahiClient *avahiclient = avahi_service_browser_get_client(avahibrowser);
switch (avahievent) {
case AVAHI_BROWSER_NEW: {
kDebug() << "New service" << avahiname << avahitype << avahidomain;
kdnssdprivate->m_poll++;
AvahiServiceResolver *avahiresolver = avahi_service_resolver_new(
avahiclient,
avahiinterface, avahiprotocol,
avahiname, avahitype, avahidomain,
AVAHI_PROTO_UNSPEC, AvahiLookupFlags(0),
KDNSSDPrivate::resolveCallback,
userdata
);
if (!avahiresolver) {
kWarning() << avahi_strerror(avahi_client_errno(avahiclient));
}
break;
}
case AVAHI_BROWSER_ALL_FOR_NOW:
case AVAHI_BROWSER_CACHE_EXHAUSTED: {
kDebug() << "Done browsing";
kdnssdprivate->m_poll--;
KDNSSD *kdnssd= qobject_cast<KDNSSD*>(kdnssdprivate->parent());
emit kdnssd->finished();
break;
}
case AVAHI_BROWSER_FAILURE: {
kWarning() << avahi_strerror(avahi_client_errno(avahiclient));
kdnssdprivate->m_poll = 0;
break;
}
}
}
void KDNSSDPrivate::resolveCallback(AvahiServiceResolver *avahiresolver, AvahiIfIndex avahiinterface,
AvahiProtocol avahiprotocol, AvahiResolverEvent avahievent,
const char *avahiname, const char *avahitype, const char *avahidomain, const char *avahihost_name,
const AvahiAddress *avahiaddress, uint16_t avahiport,
AvahiStringList *avahitxt,
AvahiLookupResultFlags avahiflags,
void* userdata)
{
// qDebug() << Q_FUNC_INFO << avahievent << avahiname << avahitype << avahidomain << userdata;
KDNSSDPrivate *kdnssdprivate = static_cast<KDNSSDPrivate*>(userdata);
switch (avahievent) {
case AVAHI_RESOLVER_FOUND: {
kDebug() << "Resolved service" << avahiname << avahitype << avahidomain;
char avahiaddressbuff[AVAHI_ADDRESS_STR_MAX];
::memset(avahiaddressbuff, 0, sizeof(avahiaddressbuff) * sizeof(char));
avahi_address_snprint(avahiaddressbuff, sizeof(avahiaddressbuff), avahiaddress);
QString kdnssdserviceprotocol = QString::fromLatin1(avahitype);
kdnssdserviceprotocol = kdnssdserviceprotocol.mid(1);
const int dotindex = kdnssdserviceprotocol.indexOf(QLatin1Char('.'));
kdnssdserviceprotocol = kdnssdserviceprotocol.left(dotindex);
KUrl kdnssdserviceurl;
kdnssdserviceurl.setProtocol(kdnssdserviceprotocol);
kdnssdserviceurl.setHost(QString::fromLatin1(avahiaddressbuff));
kdnssdserviceurl.setPort(avahiport);
KDNSSDService kdnssdservice;
kdnssdservice.name = QString::fromUtf8(avahiname);
kdnssdservice.type = QByteArray(avahitype);
kdnssdservice.domain = QString::fromUtf8(avahidomain);
kdnssdservice.hostname = QString::fromUtf8(avahihost_name);
kdnssdservice.url = kdnssdserviceurl.prettyUrl();
kdnssdservice.port = avahiport;
kdnssdprivate->m_services.append(kdnssdservice);
break;
}
case AVAHI_RESOLVER_FAILURE: {
kWarning() << avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(avahiresolver)));
break;
}
}
kdnssdprivate->m_poll--;
avahi_service_resolver_free(avahiresolver);
}
void KDNSSDPrivate::serviceCallback(AvahiServiceTypeBrowser *avahiservice,
AvahiIfIndex avahiinterface,
AvahiProtocol avahiprotocol,
AvahiBrowserEvent avahievent,
const char *avahitype,
const char *avahidomain,
AvahiLookupResultFlags avahiflags,
void *userdata)
{
// qDebug() << Q_FUNC_INFO << avahievent << avahitype << avahidomain << userdata;
KDNSSDPrivate *kdnssdprivate = static_cast<KDNSSDPrivate*>(userdata);
AvahiClient *avahiclient = avahi_service_type_browser_get_client(avahiservice);
switch (avahievent) {
case AVAHI_BROWSER_NEW: {
kDebug() << "New service type" << avahitype << avahidomain;
const QByteArray kdnsservicetype(avahitype);
if (!kdnssdprivate->m_servicetypes.contains(kdnsservicetype)) {
kdnssdprivate->m_servicetypes.append(kdnsservicetype);
}
break;
}
case AVAHI_BROWSER_ALL_FOR_NOW:
case AVAHI_BROWSER_CACHE_EXHAUSTED: {
kDebug() << "Done browsing service types";
kdnssdprivate->m_poll--;
break;
}
case AVAHI_BROWSER_FAILURE: {
kWarning() << avahi_strerror(avahi_client_errno(avahiclient));
kdnssdprivate->m_poll = 0;
break;
}
}
}
#endif // HAVE_AVAHI
KDNSSD::KDNSSD(QObject *parent)
: QObject(parent),
d(new KDNSSDPrivate(this))
{
}
KDNSSD::~KDNSSD()
{
delete d;
}
bool KDNSSD::publishService(const QByteArray &servicetype, const uint serviceport, const QString &servicename)
{
#if defined(HAVE_AVAHI)
return d->publishService(servicetype, serviceport, servicename);
#else
return false;
#endif
}
bool KDNSSD::unpublishService()
{
return d->unpublishService();
}
QList<KDNSSDService> KDNSSD::services()
{
return d->services();
}
void KDNSSD::startBrowse(const QByteArray &servicetype)
{
d->startBrowse(servicetype);
}
#include "kdnssd.moc"

74
kutils/kdnssd/kdnssd.h Normal file
View file

@ -0,0 +1,74 @@
/* This file is part of the KDE libraries
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2, as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KDNSSD_H
#define KDNSSD_H
#include "kdnssd_export.h"
#include <QObject>
#include <QList>
struct KDNSSDService
{
QString name;
QByteArray type;
QString domain;
QString hostname;
QString url;
uint port;
};
class KDNSSDPrivate;
/*!
Class to register and query for discovarable services.
@since 4.21
@warning the API is subject to change
*/
class KDNSSD_EXPORT KDNSSD : public QObject
{
Q_OBJECT
public:
/*!
@brief Contructs object with @p parent
*/
KDNSSD(QObject *parent = nullptr);
~KDNSSD();
bool publishService(const QByteArray &servicetype, const uint serviceport, const QString &servicename);
bool unpublishService();
/*!
@brief Starts browse request for @p servicetype, if @p servicetype is empty the result will
include services for all service types. This will block until all services are resolved
*/
void startBrowse(const QByteArray &servicetype = QByteArray());
QList<KDNSSDService> services();
Q_SIGNALS:
void finished();
private:
friend KDNSSDPrivate;
Q_DISABLE_COPY(KDNSSD);
KDNSSDPrivate *d;
};
#endif // KDNSSD_H