summaryrefslogtreecommitdiffstats
path: root/dnssd/query.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dnssd/query.cpp')
-rw-r--r--dnssd/query.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/dnssd/query.cpp b/dnssd/query.cpp
new file mode 100644
index 000000000..bcb9c69f5
--- /dev/null
+++ b/dnssd/query.cpp
@@ -0,0 +1,140 @@
+/* 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 "query.h"
+#include "responder.h"
+#include "remoteservice.h"
+#include "sdevent.h"
+#include <kdebug.h>
+#include <qapplication.h>
+#include <qtimer.h>
+
+#define TIMEOUT_WAN 2000
+#define TIMEOUT_LAN 200
+
+namespace DNSSD
+{
+#ifdef HAVE_DNSSD
+void query_callback (DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode,
+ const char *serviceName, const char *regtype, const char *replyDomain, void *context);
+#endif
+class QueryPrivate : public Responder
+{
+public:
+ QueryPrivate(const QString& type, const QString& domain) : Responder(), m_finished(false),
+ m_domain(domain), m_type(type)
+ {};
+ bool m_finished;
+ QString m_domain;
+ QTimer timeout;
+ QString m_type;
+};
+
+Query::Query(const QString& type, const QString& domain)
+{
+ d = new QueryPrivate(type,domain);
+ connect(&d->timeout,SIGNAL(timeout()),this,SLOT(timeout()));
+}
+
+
+Query::~Query()
+{
+ delete d;
+}
+
+bool Query::isRunning() const
+{
+ return d->isRunning();
+}
+
+bool Query::isFinished() const
+{
+ return d->m_finished;
+}
+
+const QString& Query::domain() const
+{
+ return d->m_domain;
+}
+
+void Query::startQuery()
+{
+ if (d->isRunning()) return;
+ d->m_finished = false;
+#ifdef HAVE_DNSSD
+ DNSServiceRef ref;
+ if (DNSServiceBrowse(&ref,0,0, d->m_type.ascii(),
+ domainToDNS(d->m_domain),query_callback,reinterpret_cast<void*>(this))
+ == kDNSServiceErr_NoError) d->setRef(ref);
+#endif
+ if (!d->isRunning()) emit finished();
+ else d->timeout.start(domainIsLocal(d->m_domain) ? TIMEOUT_LAN : TIMEOUT_WAN,true);
+}
+void Query::virtual_hook(int, void*)
+{
+}
+
+void Query::customEvent(QCustomEvent* event)
+{
+ if (event->type()==QEvent::User+SD_ERROR) {
+ d->stop();
+ d->m_finished=false;
+ emit finished();
+ }
+ if (event->type()==QEvent::User+SD_ADDREMOVE) {
+ RemoteService* svr;
+ AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event);
+ // m_type has useless trailing dot
+ QString type=aev->m_type.left(aev->m_type.length()-1);
+ // label is badly splitted here - _http _tcp.local. . - rely on decode()
+ if (d->m_type=="_services._dns-sd._udp") svr = new RemoteService(aev->m_name+"."+
+ type+"."+aev->m_domain);
+ else svr = new RemoteService(aev->m_name, type, aev->m_domain);
+ if (aev->m_op==AddRemoveEvent::Add) emit serviceAdded(svr);
+ else emit serviceRemoved(svr);
+ d->m_finished = aev->m_last;
+ if (d->m_finished) emit finished();
+ }
+}
+
+void Query::timeout()
+{
+ d->m_finished=true;
+ emit finished();
+}
+#ifdef HAVE_DNSSD
+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;
+ QApplication::sendEvent(obj, &err);
+ } else {
+ AddRemoveEvent arev((flags & kDNSServiceFlagsAdd) ? AddRemoveEvent::Add :
+ AddRemoveEvent::Remove, QString::fromUtf8(serviceName), regtype,
+ DNSToDomain(replyDomain), !(flags & kDNSServiceFlagsMoreComing));
+ QApplication::sendEvent(obj, &arev);
+ }
+}
+#endif
+}
+#include "query.moc"