00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qstringlist.h>
00022 #include "domainbrowser.h"
00023 #include "settings.h"
00024 #include "sdevent.h"
00025 #include "responder.h"
00026 #include "remoteservice.h"
00027 #include "query.h"
00028 #include "servicebrowser.h"
00029 #include <kapplication.h>
00030 #ifdef AVAHI_API_0_6
00031 #include <avahi-client/lookup.h>
00032 #endif
00033
00034 namespace DNSSD
00035 {
00036
00037 #ifdef AVAHI_API_0_6
00038 void domains_callback(AvahiDomainBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00039 AvahiLookupResultFlags, void* context);
00040 #else
00041 void domains_callback(AvahiDomainBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00042 void* context);
00043 #endif
00044
00045
00046 class DomainBrowserPrivate
00047 {
00048 public:
00049 DomainBrowserPrivate(DomainBrowser* owner) : m_browseLAN(false), m_started(false),
00050 m_browser(0), m_owner(owner) {}
00051 ~DomainBrowserPrivate() { if (m_browser) avahi_domain_browser_free(m_browser); }
00052 QStringList m_domains;
00053 virtual void customEvent(QCustomEvent* event);
00054 bool m_browseLAN;
00055 bool m_started;
00056 AvahiDomainBrowser* m_browser;
00057 DomainBrowser* m_owner;
00058 };
00059
00060 void DomainBrowserPrivate::customEvent(QCustomEvent* event)
00061 {
00062 if (event->type()==QEvent::User+SD_ADDREMOVE) {
00063 AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event);
00064 if (aev->m_op==AddRemoveEvent::Add) m_owner->gotNewDomain(aev->m_domain);
00065 else m_owner->gotRemoveDomain(aev->m_domain);
00066 }
00067 }
00068
00069
00070 DomainBrowser::DomainBrowser(QObject *parent) : QObject(parent)
00071 {
00072 d = new DomainBrowserPrivate(this);
00073 d->m_domains = Configuration::domainList();
00074 if (Configuration::browseLocal()) {
00075 d->m_domains+="local.";
00076 d->m_browseLAN=true;
00077 }
00078 connect(KApplication::kApplication(),SIGNAL(kipcMessage(int,int)),this,
00079 SLOT(domainListChanged(int,int)));
00080 }
00081
00082 DomainBrowser::DomainBrowser(const QStringList& domains, bool recursive, QObject *parent) : QObject(parent)
00083 {
00084 d = new DomainBrowserPrivate(this);
00085 d->m_browseLAN = recursive;
00086 d->m_domains=domains;
00087 }
00088
00089
00090 DomainBrowser::~DomainBrowser()
00091 {
00092 delete d;
00093 }
00094
00095
00096 void DomainBrowser::startBrowse()
00097 {
00098 if (d->m_started) return;
00099 d->m_started=true;
00100 if (ServiceBrowser::isAvailable()!=ServiceBrowser::Working) return;
00101 QStringList::const_iterator itEnd = d->m_domains.end();
00102 for (QStringList::const_iterator it=d->m_domains.begin(); it!=itEnd; ++it ) emit domainAdded(*it);
00103 if (d->m_browseLAN)
00104 #ifdef AVAHI_API_0_6
00105 d->m_browser = avahi_domain_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00106 "local.", AVAHI_DOMAIN_BROWSER_BROWSE, (AvahiLookupFlags)0, domains_callback, this);
00107 #else
00108 d->m_browser = avahi_domain_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00109 "local.", AVAHI_DOMAIN_BROWSER_BROWSE, domains_callback, this);
00110 #endif
00111 }
00112
00113 void DomainBrowser::gotNewDomain(const QString& domain)
00114 {
00115 if (d->m_domains.contains(domain)) return;
00116 d->m_domains.append(domain);
00117 emit domainAdded(domain);
00118 }
00119
00120 void DomainBrowser::gotRemoveDomain(const QString& domain)
00121 {
00122 d->m_domains.remove(domain);
00123 emit domainRemoved(domain);
00124 }
00125
00126 void DomainBrowser::domainListChanged(int message,int)
00127 {
00128 if (message!=KIPCDomainsChanged) return;
00129
00130 bool was_started = d->m_started;
00131 if (d->m_browser) {
00132 avahi_domain_browser_free(d->m_browser);
00133 d->m_browser=0;
00134 }
00135 d->m_started = false;
00136
00137
00138 if (was_started) {
00139 QStringList::const_iterator itEnd = d->m_domains.end();
00140 for (QStringList::const_iterator it=d->m_domains.begin(); it!=itEnd; ++it )
00141 emit domainRemoved(*it);
00142 }
00143 d->m_domains.clear();
00144
00145 Configuration::self()->readConfig();
00146 d->m_browseLAN = Configuration::browseLocal();
00147 d->m_domains = Configuration::domainList();
00148 if (Configuration::browseLocal()) d->m_domains+="local";
00149
00150 if (was_started) startBrowse();
00151 }
00152
00153 const QStringList& DomainBrowser::domains() const
00154 {
00155 return d->m_domains;
00156 }
00157
00158 bool DomainBrowser::isRunning() const
00159 {
00160 return d->m_started;
00161 }
00162
00163 void DomainBrowser::virtual_hook(int, void*)
00164 {}
00165
00166 #ifdef AVAHI_API_0_6
00167 void domains_callback(AvahiDomainBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00168 AvahiLookupResultFlags,void* context)
00169 #else
00170 void domains_callback(AvahiDomainBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00171 void* context)
00172 #endif
00173 {
00174 QObject *obj = reinterpret_cast<QObject*>(context);
00175 AddRemoveEvent* arev=new AddRemoveEvent((event==AVAHI_BROWSER_NEW) ? AddRemoveEvent::Add :
00176 AddRemoveEvent::Remove, QString::null, QString::null,
00177 DNSToDomain(replyDomain));
00178 QApplication::postEvent(obj, arev);
00179 }
00180
00181
00182 }
00183 #include "domainbrowser.moc"