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