Warning: That file was not part of the compilation database. It may have many parsing errors.

1/* This file is part of the KDE project
2 *
3 * Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#include <QtCore/QCoreApplication>
22#include <QtCore/QStringList>
23#include <netinet/in.h>
24#include "publicservice.h"
25#include "servicebase_p.h"
26#include "mdnsd-sdevent.h"
27#include "mdnsd-responder.h"
28#include "settings.h"
29
30#define K_D PublicServicePrivate* d=static_cast<PublicServicePrivate*>(this->d)
31
32namespace DNSSD
33{
34void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name,
35 const char*, const char*, void *context);
36class PublicServicePrivate : public Responder, public ServiceBasePrivate
37{
38public:
39 PublicServicePrivate(PublicService* parent, const QString& name, const QString& type, unsigned int port,
40 const QString& domain) : Responder(), ServiceBasePrivate(name, type, domain, QString(), port),
41 m_published(false), m_parent(parent)
42 {}
43 bool m_published;
44 PublicService* m_parent;
45 QStringList m_subtypes;
46 virtual void customEvent(QEvent* event);
47};
48
49PublicService::PublicService(const QString& name, const QString& type, unsigned int port,
50 const QString& domain, const QStringList& subtypes)
51 : QObject(), ServiceBase(new PublicServicePrivate(this, name, type, port, domain))
52{
53 K_D;
54 if (domain.isNull()) d->m_domain="local.";
55 d->m_subtypes=subtypes;
56}
57
58
59PublicService::~PublicService()
60{
61 stop();
62}
63
64void PublicService::setServiceName(const QString& serviceName)
65{
66 K_D;
67 d->m_serviceName = serviceName;
68 if (d->isRunning()) {
69 stop();
70 publishAsync();
71 }
72}
73
74void PublicService::setDomain(const QString& domain)
75{
76 K_D;
77 d->m_domain = domain;
78 if (d->isRunning()) {
79 stop();
80 publishAsync();
81 }
82}
83
84QStringList PublicService::subtypes() const
85{
86 K_D;
87 return d->m_subtypes;
88}
89
90void PublicService::setType(const QString& type)
91{
92 K_D;
93 d->m_type = type;
94 if (d->isRunning()) {
95 stop();
96 publishAsync();
97 }
98}
99
100void PublicService::setSubTypes(const QStringList& subtypes)
101{
102 K_D;
103 d->m_subtypes = subtypes;
104 if (d->isRunning()) {
105 stop();
106 publishAsync();
107 }
108}
109
110void PublicService::setPort(unsigned short port)
111{
112 K_D;
113 d->m_port = port;
114 if (d->isRunning()) {
115 stop();
116 publishAsync();
117 }
118}
119
120bool PublicService::isPublished() const
121{
122 K_D;
123 return d->m_published;
124}
125
126void PublicService::setTextData(const QMap<QString,QByteArray>& textData)
127{
128 K_D;
129 d->m_textData = textData;
130 if (d->isRunning()) {
131 stop();
132 publishAsync();
133 }
134}
135
136bool PublicService::publish()
137{
138 K_D;
139 publishAsync();
140 while (d->isRunning() && !d->m_published) d->process();
141 return d->m_published;
142}
143
144void PublicService::stop()
145{
146 K_D;
147 d->stop();
148 d->m_published = false;
149}
150
151void PublicService::publishAsync()
152{
153 K_D;
154 if (d->isRunning()) stop();
155 TXTRecordRef txt;
156 TXTRecordCreate(&txt,0,0);
157 QMap<QString,QByteArray>::ConstIterator itEnd = d->m_textData.end();
158 for (QMap<QString,QByteArray>::ConstIterator it = d->m_textData.begin(); it!=itEnd ; ++it) {
159 if (TXTRecordSetValue(&txt,it.key().toUtf8(),it.value().length(),it.value())!=kDNSServiceErr_NoError) {
160 TXTRecordDeallocate(&txt);
161 emit published(false);
162 return;
163 }
164 }
165 DNSServiceRef ref;
166 QString fullType=d->m_type;
167 Q_FOREACH(const QString &subtype, d->m_subtypes) fullType+=','+subtype;
168 if (DNSServiceRegister(&ref,0,0,d->m_serviceName.toUtf8(),fullType.toLatin1().constData(),domainToDNS(d->m_domain),NULL,
169 htons(d->m_port),TXTRecordGetLength(&txt),TXTRecordGetBytesPtr(&txt),publish_callback,
170 reinterpret_cast<void*>(d)) == kDNSServiceErr_NoError) d->setRef(ref);
171 TXTRecordDeallocate(&txt);
172 if (!d->isRunning()) emit published(false);
173}
174
175void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name,
176 const char*, const char*, void *context)
177{
178 QObject *obj = reinterpret_cast<QObject*>(context);
179 if (errorCode != kDNSServiceErr_NoError) {
180 ErrorEvent err;
181 QCoreApplication::sendEvent(obj, &err);
182 } else {
183 PublishEvent pev(QString::fromUtf8(name));
184 QCoreApplication::sendEvent(obj, &pev);
185 }
186}
187
188void PublicServicePrivate::customEvent(QEvent* event)
189{
190 if (event->type()==QEvent::User+SD_ERROR) {
191 m_parent->stop();
192 emit m_parent->published(false);
193 }
194 if (event->type()==QEvent::User+SD_PUBLISH) {
195 m_published=true;
196 emit m_parent->published(true);
197 m_serviceName = static_cast<PublishEvent*>(event)->m_name;
198 }
199}
200
201void PublicService::virtual_hook(int, void*)
202{
203}
204
205}
206
207#include "publicservice.moc"
208

Warning: That file was not part of the compilation database. It may have many parsing errors.