diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 02:37:40 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 02:37:40 +0000 |
commit | 9ad5c7b5e23b4940e7a3ea3ca3a6fb77e6a8fab0 (patch) | |
tree | d088b5210e77d9fa91d954d8550e00e372b47378 /plugins/zeroconf | |
download | ktorrent-9ad5c7b5e23b4940e7a3ea3ca3a6fb77e6a8fab0.tar.gz ktorrent-9ad5c7b5e23b4940e7a3ea3ca3a6fb77e6a8fab0.zip |
Updated to final KDE3 ktorrent release (2.2.6)
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/ktorrent@1077377 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'plugins/zeroconf')
-rw-r--r-- | plugins/zeroconf/Makefile.am | 22 | ||||
-rw-r--r-- | plugins/zeroconf/avahiservice.cpp | 341 | ||||
-rw-r--r-- | plugins/zeroconf/avahiservice.h | 113 | ||||
-rw-r--r-- | plugins/zeroconf/ktzeroconfplugin.desktop | 22 | ||||
-rw-r--r-- | plugins/zeroconf/localbrowser.cpp | 47 | ||||
-rw-r--r-- | plugins/zeroconf/localbrowser.h | 39 | ||||
-rw-r--r-- | plugins/zeroconf/zeroconfplugin.cpp | 135 | ||||
-rw-r--r-- | plugins/zeroconf/zeroconfplugin.h | 71 |
8 files changed, 790 insertions, 0 deletions
diff --git a/plugins/zeroconf/Makefile.am b/plugins/zeroconf/Makefile.am new file mode 100644 index 0000000..c6870e6 --- /dev/null +++ b/plugins/zeroconf/Makefile.am @@ -0,0 +1,22 @@ +INCLUDES = -I$(top_builddir)/libktorrent -I$(top_builddir)/ktorrent/libktorrent \ + -I$(srcdir)/../../libktorrent $(all_includes) + +METASOURCES = AUTO + +if COMPILE_ZEROCONF +kde_module_LTLIBRARIES = ktzeroconfplugin.la +endif + +ktzeroconfplugin_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) $(AVAHI_LIBS) $(AVAHI_QT3_LIBS) +ktzeroconfplugin_la_SOURCES = localbrowser.cpp avahiservice.cpp \ + zeroconfplugin.cpp + +ktzeroconfplugin_la_LIBADD = $(LIB_KDECORE) $(LIB_KFILE) $(LIB_KPARTS) $(LIB_KDEUI)\ + $(LIB_QT) ../../libktorrent/libktorrent.la + +noinst_HEADERS = zeroconfplugin.h + +kde_services_DATA = ktzeroconfplugin.desktop +KDE_CXXFLAGS = $(USE_EXCEPTIONS) $(USE_RTTI) + + diff --git a/plugins/zeroconf/avahiservice.cpp b/plugins/zeroconf/avahiservice.cpp new file mode 100644 index 0000000..a190d8e --- /dev/null +++ b/plugins/zeroconf/avahiservice.cpp @@ -0,0 +1,341 @@ +/*************************************************************************** + * Copyright (C) 2006 by Lesly Weyts and Kevin Andre * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include <util/log.h> +#include <torrent/peerid.h> +#include <avahi-common/watch.h> +#include <avahi-qt3/qt-watch.h> +#include "localbrowser.h" +#include "avahiservice.h" + +using namespace bt; + +namespace kt +{ + + void group_callback(AvahiEntryGroup* g, AvahiEntryGroupState state, void* userdata) + { + AvahiService* service = reinterpret_cast<AvahiService*>(userdata); + + if (g == service->group) + { + switch (state) + { + case AVAHI_ENTRY_GROUP_ESTABLISHED: + break; + case AVAHI_ENTRY_GROUP_COLLISION: + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Entry group collision." << endl; + break; + case AVAHI_ENTRY_GROUP_FAILURE: + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Entry group failure." << endl; + break; + case AVAHI_ENTRY_GROUP_UNCOMMITED: + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Entry group uncommited." << endl; + break; + case AVAHI_ENTRY_GROUP_REGISTERING: + ; + } + } + } + + void publish_service(AvahiService* service, AvahiClient *c) + { + assert(c); + + if (!service->group) + { + if (!(service->group = avahi_entry_group_new(c, group_callback, service))) + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: avahi_entry_group_new failed." << endl; + return; + } + } + + const char* name = avahi_strdup(QString("%1__%2%3").arg(service->id).arg((rand() % 26) + 65).arg((rand() % 26) + 65).ascii()); + const char* type = avahi_strdup("_bittorrent._tcp"); + const char* subtype = avahi_strdup(QString("_" + service->infoHash + "._sub._bittorrent._tcp").ascii()); + + if (avahi_entry_group_add_service( + service->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + (AvahiPublishFlags)0, name, type, NULL, NULL, service->port, NULL)) + { + if (avahi_client_errno(c) != -8) + Out(SYS_ZCO|LOG_DEBUG) << QString("ZC: Failed to add the service (%i).").arg(avahi_client_errno(c)) << endl; + else + publish_service(service, c); + return; + } + + if (avahi_entry_group_add_service_subtype( + service->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + (AvahiPublishFlags)0, name, type, NULL, subtype)) + { + Out(SYS_ZCO|LOG_DEBUG) << QString("ZC: Failed to add the service subtype (%i).").arg( avahi_client_errno(c)) << endl; + return; + } + + if (avahi_entry_group_commit(service->group)) + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Failed to commit the entry group." << endl; + return; + } + } + + void publisher_callback(AvahiClient* c, AvahiClientState state, void* userdata) + { + if (!c) + return; + + AvahiService* service = reinterpret_cast<AvahiService*>(userdata); + + switch (state) { + case AVAHI_CLIENT_S_RUNNING: + { + if (!service->group) + publish_service(service, c); + break; + } + case AVAHI_CLIENT_FAILURE: + { + Out(SYS_ZCO|LOG_DEBUG) << "Failure when publishing." << endl; + break; + } + case AVAHI_CLIENT_S_COLLISION: + case AVAHI_CLIENT_S_REGISTERING: + { + if (service->group) + avahi_entry_group_reset(service->group); + break; + } + case AVAHI_CLIENT_CONNECTING: + ; + } + } + + void listener_callback(AvahiClient* c, AvahiClientState state, void* userdata) + { + assert(c); + + AvahiService* service = reinterpret_cast<AvahiService*>(userdata); + + if (state == AVAHI_CLIENT_FAILURE) + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Server connection failure." << endl; + } + } + + void resolve_callback( + AvahiServiceResolver* r, + AVAHI_GCC_UNUSED AvahiIfIndex interface, + AVAHI_GCC_UNUSED AvahiProtocol protocol, + AvahiResolverEvent event, + const char* name, + AVAHI_GCC_UNUSED const char* type, + AVAHI_GCC_UNUSED const char* domain, + AVAHI_GCC_UNUSED const char* host_name, + const AvahiAddress* address, + uint16_t port, + AVAHI_GCC_UNUSED AvahiStringList* txt, + AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, + void* userdata) + { + assert(r); + + switch (event) { + case AVAHI_RESOLVER_FAILURE: + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Resolver failed." << endl; + break; + } + case AVAHI_RESOLVER_FOUND: + { + AvahiService* service = reinterpret_cast<AvahiService*>(userdata); + + QString realname = QString(name); + realname.truncate(realname.length() - 5); + + if (service->id != QString(realname)) + { + char a[AVAHI_ADDRESS_STR_MAX]; + avahi_address_snprint(a, sizeof(a), address); + const char* ip = a; + LocalBrowser::insert(bt::PeerID(realname.ascii())); + + Out(SYS_ZCO|LOG_NOTICE) << "ZC: found local peer " << ip << ":" << port << endl; + service->addPeer(ip,port,true); + service->emitPeersReady(); + } + } + } + avahi_service_resolver_free(r); + } + + void browser_callback( + AvahiServiceBrowser* b, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* name, + const char* type, + const char* domain, + AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, + void* userdata) + { + assert(b); + + AvahiService* service = reinterpret_cast<AvahiService*>(userdata); + + switch (event) { + case AVAHI_BROWSER_FAILURE: + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Browser failure." << endl; + break; + } + case AVAHI_BROWSER_NEW: + { + if (!(avahi_service_resolver_new(service->listener, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, (AvahiLookupFlags)0, resolve_callback, userdata))) + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Failed to resolve the service." << endl; + break; + } + case AVAHI_BROWSER_REMOVE: + { + QString realname = QString(name); + realname.truncate(realname.length() - 5); + + LocalBrowser::remove(bt::PeerID(realname.ascii())); + + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Browser removed." << endl; + break; + } + case AVAHI_BROWSER_ALL_FOR_NOW: + case AVAHI_BROWSER_CACHE_EXHAUSTED: + ; + } + } + + AvahiService::AvahiService(const bt::PeerID& id,bt::Uint16 port, const bt::SHA1Hash & infoHash) + : group(0), publisher_poll(0), listener_poll(0),publisher(0), listener(0), browser(0) + { + started = false; + + this->id = id.toString(); + this->port = port; + this->infoHash = infoHash.toString(); + } + + AvahiService::~AvahiService() + { + stop(0); + } + + void AvahiService::stop(bt::WaitJob*) + { + if (started) + { + started = false; + + publisher_poll = 0; + if (publisher) + { + avahi_client_free(publisher); + publisher = 0; + } + + listener_poll = 0; + if (listener) + { + avahi_client_free(listener); + listener = 0; + } + } + } + + void AvahiService::start() + { + started = startPublishing() && startBrowsing(); + } + + bool AvahiService::startPublishing() + { + group = NULL; + publisher_poll = NULL; + publisher = NULL; + + if (!(publisher_poll = avahi_qt_poll_get())) + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Failed to create a poll for publishing." << endl; + stop(); + return false; + } + + publisher = avahi_client_new(publisher_poll, AVAHI_CLIENT_NO_FAIL, publisher_callback, this, NULL); + + if (!(publisher)) + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Failed to create a client for publishing." << endl; + stop(); + return false; + } + + return true; + } + + bool AvahiService::startBrowsing() + { + listener_poll = NULL; + listener = NULL; + browser = NULL; + + if (!(listener_poll = avahi_qt_poll_get())) + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Failed to create a poll for browsing." << endl; + stop(); + return false; + } + + listener = avahi_client_new(listener_poll,AVAHI_CLIENT_NO_FAIL, listener_callback, this, NULL); + + if (!listener) + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Failed to create a client for browsing." << endl; + stop(); + return false; + } + + if (!(browser = avahi_service_browser_new(listener, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, avahi_strdup(QString("_" + infoHash + "._sub._bittorrent._tcp").ascii()), NULL, (AvahiLookupFlags)0, browser_callback, this))) + { + Out(SYS_ZCO|LOG_DEBUG) << "ZC: Failed to create a service browser." << endl; + stop(); + return false; + } + + return true; + } + + void AvahiService::emitPeersReady() + { + peersReady(this); + } + + void AvahiService::aboutToBeDestroyed() + { + serviceDestroyed(this); + } +} + +#include "avahiservice.moc" diff --git a/plugins/zeroconf/avahiservice.h b/plugins/zeroconf/avahiservice.h new file mode 100644 index 0000000..10938d8 --- /dev/null +++ b/plugins/zeroconf/avahiservice.h @@ -0,0 +1,113 @@ +/*************************************************************************** + * Copyright (C) 2006 by Lesly Weyts and Kevin Andre * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef AVAHI_SERVICE_HH +#define AVAHI_SERVICE_HH + +/** + * @author Lesly Weyts and Kevin Andre + * @brief Handles everything directly related to Avahi + * + * This set of functions provide a simple way to use Avahi inside the KTorrent source code. + */ + +#include <cstdlib> +#include <qstring.h> + + +#include <avahi-client/client.h> +#include <avahi-client/publish.h> +#include <avahi-client/lookup.h> +#include <avahi-common/thread-watch.h> +#include <avahi-common/malloc.h> + +#include <util/sha1hash.h> +#include <interfaces/peersource.h> + +namespace kt +{ + + class AvahiService : public kt::PeerSource + { + Q_OBJECT + public: + AvahiService(const bt::PeerID&, bt::Uint16, const bt::SHA1Hash&); + virtual ~AvahiService(); + + virtual void stop(bt::WaitJob* wjob = 0); + virtual void start(); + virtual void aboutToBeDestroyed(); + + void emitPeersReady(); + + signals: + void serviceDestroyed(AvahiService* av); + + private: + bool startPublishing(); + bool startBrowsing(); + + friend void group_callback(AvahiEntryGroup*, AvahiEntryGroupState, void*); + friend void publish_service(AvahiService*, AvahiClient*); + friend void publisher_callback(AvahiClient*, AvahiClientState, void*); + friend void listener_callback(AvahiClient*, AvahiClientState, void*); + + friend void resolve_callback( + AvahiServiceResolver*, + AvahiIfIndex, + AvahiProtocol, + AvahiResolverEvent, + const char*, + const char*, + const char*, + const char*, + const AvahiAddress*, + uint16_t, + AvahiStringList*, + AvahiLookupResultFlags, + void* + ); + + friend void browser_callback( + AvahiServiceBrowser*, + AvahiIfIndex, + AvahiProtocol, + AvahiBrowserEvent, + const char*, + const char*, + const char*, + AvahiLookupResultFlags, + void* + ); + + QString id; + int port; + QString infoHash; + + bool started; + + AvahiEntryGroup *group; + const AvahiPoll* publisher_poll; + const AvahiPoll* listener_poll; + AvahiClient* publisher; + AvahiClient* listener; + AvahiServiceBrowser *browser; + }; +} + +#endif diff --git a/plugins/zeroconf/ktzeroconfplugin.desktop b/plugins/zeroconf/ktzeroconfplugin.desktop new file mode 100644 index 0000000..caf68e1 --- /dev/null +++ b/plugins/zeroconf/ktzeroconfplugin.desktop @@ -0,0 +1,22 @@ +[Desktop Entry] +Name=ZeroConfPlugin +Name[bg]=Приставка ZeroConf +Name[de]=ZeroConf-Modul +Name[es]=Complemento de ZeroConf +Name[et]=ZeroConfi plugin +Name[it]=Plugin ZeroConf +Name[nb]=ZeroConf-modul +Name[nds]=ZeroConf-Moduul +Name[pl]=Wtyczka ZeroConf +Name[pt]='Plugin' do ZeroConf +Name[pt_BR]=Plugin ZeroConf +Name[sr]=ZeroConf прикључак +Name[sr@Latn]=ZeroConf priključak +Name[sv]=Zeroconf-insticksprogram +Name[tr]=ZeroConf Eklentisi +Name[uk]=Втулок ZeroConf +Name[xx]=xxZeroConfPluginxx +Name[zh_CN]=ZeroConf 插件 +ServiceTypes=KTorrent/Plugin +Type=Service +X-KDE-Library=ktzeroconfplugin diff --git a/plugins/zeroconf/localbrowser.cpp b/plugins/zeroconf/localbrowser.cpp new file mode 100644 index 0000000..6306788 --- /dev/null +++ b/plugins/zeroconf/localbrowser.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2006 by Lesly Weyts and Kevin Andre * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include <list> +#include <torrent/peerid.h> +#include "localbrowser.h" + + +namespace LocalBrowser +{ + static std::list<bt::PeerID> local_peers; + + void remove(bt::PeerID id) + { + local_peers.remove(id); + } + + void insert(bt::PeerID id) + { + if (!(check(id))) + local_peers.push_front(id); + } + + bool check(bt::PeerID id) + { + for (std::list<bt::PeerID>::iterator i = local_peers.begin(); i != local_peers.end(); ++i) { + if (*i == id) + return true; + } + return false; + } +} diff --git a/plugins/zeroconf/localbrowser.h b/plugins/zeroconf/localbrowser.h new file mode 100644 index 0000000..0e06b99 --- /dev/null +++ b/plugins/zeroconf/localbrowser.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2006 by Lesly Weyts and Kevin Andre * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef LOCAL_BROWSER_HHHH +#define LOCAL_BROWSER_HHHH + +/** + * @author Lesly Weyts and Kevin Andre + * @brief Keep track of local peers + */ + + + +namespace bt { class PeerID; } + +namespace LocalBrowser { + + void remove(bt::PeerID); + void insert(bt::PeerID); + bool check (bt::PeerID); + + +} +#endif diff --git a/plugins/zeroconf/zeroconfplugin.cpp b/plugins/zeroconf/zeroconfplugin.cpp new file mode 100644 index 0000000..b906843 --- /dev/null +++ b/plugins/zeroconf/zeroconfplugin.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** + * Copyright (C) 2005 by Joris Guisson * + * joris.guisson@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include <kgenericfactory.h> +#include <util/log.h> +#include <interfaces/coreinterface.h> +#include <interfaces/torrentinterface.h> +#include <torrent/globals.h> +#include <torrent/server.h> +#include "zeroconfplugin.h" +#include "avahiservice.h" + + +#define NAME "Zeroconf" +#define AUTHOR "Lesly Weyts and Kevin Andre" + +K_EXPORT_COMPONENT_FACTORY(ktzeroconfplugin,KGenericFactory<kt::ZeroConfPlugin>("ktzeroconfplugin")) + +using namespace bt; + +namespace kt +{ + + ZeroConfPlugin::ZeroConfPlugin(QObject* parent, const char* name, const QStringList& args) + : Plugin(parent, name,args,NAME,i18n("Zeroconf"),AUTHOR,QString::null,i18n("Finds peers running ktorrent on the local network to share torrents with"),"ktplugins") + { + services.setAutoDelete(true); + } + + + ZeroConfPlugin::~ZeroConfPlugin() + {} + + void ZeroConfPlugin::load() + { + CoreInterface* core = getCore(); + connect(core,SIGNAL(torrentAdded( kt::TorrentInterface* )), + this,SLOT(torrentAdded( kt::TorrentInterface* ))); + connect(core,SIGNAL(torrentRemoved( kt::TorrentInterface* )), + this,SLOT(torrentRemoved( kt::TorrentInterface* ))); + + // go over existing torrents and add them + bt::QueueManager* qman = core->getQueueManager(); + for (QPtrList<kt::TorrentInterface>::iterator i = qman->begin();i != qman->end();i++) + { + torrentAdded(*i); + } + } + + void ZeroConfPlugin::unload() + { + CoreInterface* core = getCore(); + disconnect(core,SIGNAL(torrentAdded( kt::TorrentInterface* )), + this,SLOT(torrentAdded( kt::TorrentInterface* ))); + disconnect(core,SIGNAL(torrentRemoved( kt::TorrentInterface* )), + this,SLOT(torrentRemoved( kt::TorrentInterface*))); + + bt::PtrMap<kt::TorrentInterface*,AvahiService>::iterator i = services.begin(); + while (i != services.end()) + { + AvahiService* av = i->second; + kt::TorrentInterface* ti = i->first; + ti->removePeerSource(av); + i++; + } + services.clear(); + } + + void ZeroConfPlugin::torrentAdded(kt::TorrentInterface* tc) + { + if (services.contains(tc)) + return; + + bt::Uint16 port = bt::Globals::instance().getServer().getPortInUse(); + AvahiService* av = new AvahiService(tc->getOwnPeerID(),port,tc->getInfoHash()); + services.insert(tc,av); + tc->addPeerSource(av); + Out(SYS_ZCO|LOG_NOTICE) << "ZeroConf service added for " + << tc->getStats().torrent_name << endl; + connect(av,SIGNAL(serviceDestroyed( AvahiService* )), + this,SLOT(avahiServiceDestroyed( AvahiService* ))); + } + + + void ZeroConfPlugin::torrentRemoved(kt::TorrentInterface* tc) + { + AvahiService* av = services.find(tc); + if (!av) + return; + Out(SYS_ZCO|LOG_NOTICE) << "ZeroConf service removed for " + << tc->getStats().torrent_name << endl; + tc->removePeerSource(av); + services.erase(tc); + } + + void ZeroConfPlugin::avahiServiceDestroyed(AvahiService* av) + { + services.setAutoDelete(false); + + Out(SYS_ZCO|LOG_NOTICE) << "ZeroConf service destroyed " << endl; + bt::PtrMap<kt::TorrentInterface*,AvahiService>::iterator i = services.begin(); + while (i != services.end()) + { + if (i->second == av) + { + services.erase(i->first); + break; + } + i++; + } + services.setAutoDelete(true); + } + + bool ZeroConfPlugin::versionCheck(const QString & version) const + { + return version == KT_VERSION_MACRO; + } +} +#include "zeroconfplugin.moc" diff --git a/plugins/zeroconf/zeroconfplugin.h b/plugins/zeroconf/zeroconfplugin.h new file mode 100644 index 0000000..b34e851 --- /dev/null +++ b/plugins/zeroconf/zeroconfplugin.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2005 by Joris Guisson * + * joris.guisson@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef KTZEROCONFPLUGIN_H +#define KTZEROCONFPLUGIN_H + +#include <util/ptrmap.h> +#include <interfaces/plugin.h> + +namespace kt +{ + class TorrentInterface; + class AvahiService; + + /** + * @author Joris Guisson <joris.guisson@gmail.com> + * + * Plugin which handles the zeroconf service. + */ + class ZeroConfPlugin : public Plugin + { + Q_OBJECT + public: + ZeroConfPlugin(QObject* parent, const char* name, const QStringList& args); + virtual ~ZeroConfPlugin(); + + virtual void load(); + virtual void unload(); + virtual bool versionCheck(const QString& version) const; + + private slots: + /** + * A TorrentInterface was added + * @param tc + */ + void torrentAdded(kt::TorrentInterface* tc); + + /** + * A TorrentInterface was removed + * @param tc + */ + void torrentRemoved(kt::TorrentInterface* tc); + + /** + * An AvahiService has been destroyed by the psman + */ + void avahiServiceDestroyed(AvahiService* av); + + private: + bt::PtrMap<kt::TorrentInterface*,AvahiService> services; + }; + +} + +#endif |