[libktorrent] backport some upstream fixes, and some .spec cleanup

Rex Dieter rdieter at fedoraproject.org
Mon Dec 24 18:22:24 UTC 2012


commit c21d7308d10824e18b7c19d9e1f6cfc7a2447851
Author: Rex Dieter <rdieter at math.unl.edu>
Date:   Mon Dec 24 12:22:44 2012 -0600

    backport some upstream fixes, and some .spec cleanup

 ...-1.3-Add-workaround-for-broken-handling-o.patch |  138 +++++
 ...-1.3-Fix-crash-when-preallocating-diskspa.patch |   55 ++
 ...-1.3-Unbreak-the-non-Linux-case-after-4ff.patch |   29 +
 ...-1.3-Make-sure-stats-get-updated-properly.patch |   44 ++
 ...ockets-to-preferred-interface-for-outboun.patch |  646 ++++++++++++++++++++
 libktorrent.spec                                   |   27 +-
 6 files changed, 927 insertions(+), 12 deletions(-)
---
diff --git a/0001-Backport-to-1.3-Add-workaround-for-broken-handling-o.patch b/0001-Backport-to-1.3-Add-workaround-for-broken-handling-o.patch
new file mode 100644
index 0000000..58c2d0e
--- /dev/null
+++ b/0001-Backport-to-1.3-Add-workaround-for-broken-handling-o.patch
@@ -0,0 +1,138 @@
+From f76e1b0b637e53af64ecd813e8541019e50bb8bb Mon Sep 17 00:00:00 2001
+From: Joris Guisson <joris.guisson at gmail.com>
+Date: Mon, 24 Sep 2012 11:07:44 +0200
+Subject: [PATCH 1/9] Backport to 1.3: Add workaround for broken handling of
+ btrfs subvolumes by solid
+
+CCBUG: 306825
+---
+ ChangeLog            |  3 +++
+ src/util/fileops.cpp | 65 ++++++++++++++++++++++++++++++++++------------------
+ 2 files changed, 46 insertions(+), 22 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index fe2cc21..c037d28 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Changes in 1.3.1:
++- Add workaround for broken handling of btrfs subvolumes by solid (306825)
++
+ Changes in 1.3:
+ - Do not pass link local IPv6 addresses to ip parameter of tracker (305187)
+ 
+diff --git a/src/util/fileops.cpp b/src/util/fileops.cpp
+index 637074d..1e5d7d5 100644
+--- a/src/util/fileops.cpp
++++ b/src/util/fileops.cpp
+@@ -30,12 +30,15 @@
+ #include <kio/copyjob.h> 
+ #include <solid/device.h>
+ #include <solid/storageaccess.h>
++#include <solid/storagedrive.h>
++#include <solid/storagevolume.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+-#include <qdir.h>
+-#include <qfile.h>
+-#include <qstringlist.h>
++#include <QDir>
++#include <QFile>
++#include <QStringList>
++#include <QSet>
+ #include "error.h"
+ #include "log.h"
+ #include "file.h"
+@@ -73,12 +76,14 @@ typedef	int64_t		__s64;
+ #endif
+ 
+ #ifndef Q_WS_WIN
++#include <mntent.h>
+ #include <sys/statvfs.h>
+ #endif
+ #ifdef CopyFile
+ #undef CopyFile
+ #endif
+ 
++
+ namespace bt
+ {
+ 	void MakeDir(const QString & dir,bool nothrow)
+@@ -619,38 +624,54 @@ namespace bt
+ 		return ret;
+ 	}
+ 	
+-	QString MountPoint(const QString& path)
++	QSet<QString> AccessibleMountPoints()
+ 	{
+-		QList<Solid::Device> devs = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
+-		QString mountpoint;
++        QSet<QString> result;
++#ifndef Q_WS_WIN
++		FILE* fptr = setmntent("/proc/mounts", "r");
++		if(!fptr)
++			return result;
++
++		struct mntent mnt;
++		char buf[PATH_MAX];
++		while(getmntent_r(fptr, &mnt, buf, PATH_MAX))
++		{
++			result.insert(QString(mnt.mnt_dir));
++		}
+ 		
++		endmntent(fptr);
++		
++#else
++		QList<Solid::Device> devs = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
+ 		foreach (Solid::Device dev,devs)
+ 		{
+ 			Solid::StorageAccess* sa = dev.as<Solid::StorageAccess>();
+-			if (path.startsWith(sa->filePath()))
++			if(!sa->filePath().isEmpty() && sa->isAccessible())
++				result.insert(sa->filePa());
++		}
++#endif
++		return result;
++	}
++	
++	QString MountPoint(const QString& path)
++	{
++        QSet<QString> mount_points = AccessibleMountPoints();
++		QString mount_point;
++		foreach (const QString & mp, mount_points)
++        {
++            if (path.startsWith(mp) && (mount_point.isEmpty() || mp.startsWith(mount_point)))
+ 			{
+-				if (mountpoint.isEmpty() || sa->filePath().startsWith(mountpoint))
+-					mountpoint = sa->filePath();
++				mount_point = mp;
+ 			}
+ 		}
+ 		
+-		return mountpoint;
++		return mount_point;
+ 	}
+ 
++
+ 	bool IsMounted(const QString& mount_point)
+ 	{
+-		QList<Solid::Device> devs = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
+-		
+-		foreach (Solid::Device dev,devs)
+-		{
+-			Solid::StorageAccess* sa = dev.as<Solid::StorageAccess>();
+-			if (sa->filePath() == mount_point)
+-			{
+-				return sa->isAccessible();
+-			}
+-		}
+-		
+-		return false;
++		return AccessibleMountPoints().contains(mount_point);
+ 	}
+ 
+ }
+-- 
+1.8.0.2
+
diff --git a/0002-Backport-to-1.3-Fix-crash-when-preallocating-diskspa.patch b/0002-Backport-to-1.3-Fix-crash-when-preallocating-diskspa.patch
new file mode 100644
index 0000000..4696182
--- /dev/null
+++ b/0002-Backport-to-1.3-Fix-crash-when-preallocating-diskspa.patch
@@ -0,0 +1,55 @@
+From 30c07792eda0ac656f5173852a059705d8b85163 Mon Sep 17 00:00:00 2001
+From: Joris Guisson <joris.guisson at gmail.com>
+Date: Mon, 24 Sep 2012 13:23:41 +0200
+Subject: [PATCH 2/9] Backport to 1.3: Fix crash when preallocating diskspace
+ when a file is enabled during the download of a torrent
+
+CCBUG: 307178
+---
+ ChangeLog                          | 1 +
+ src/diskio/multifilecache.cpp      | 3 ++-
+ src/diskio/preallocationthread.cpp | 3 ++-
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index c037d28..7ce9c53 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,5 +1,6 @@
+ Changes in 1.3.1:
+ - Add workaround for broken handling of btrfs subvolumes by solid (306825)
++- Fix crash when preallocating diskspace when a file is enabled during the download of a torrent (307178) 
+ 
+ Changes in 1.3:
+ - Do not pass link local IPv6 addresses to ip parameter of tracker (305187)
+diff --git a/src/diskio/multifilecache.cpp b/src/diskio/multifilecache.cpp
+index ce19ffd..8e3d90f 100644
+--- a/src/diskio/multifilecache.cpp
++++ b/src/diskio/multifilecache.cpp
+@@ -783,7 +783,8 @@ namespace bt
+ 		while(i != files.end())
+ 		{
+ 			CacheFile::Ptr cf = i.value();
+-			prealloc->add(cf);
++			if(cf)
++				prealloc->add(cf);
+ 			i++;
+ 		}
+ 	}
+diff --git a/src/diskio/preallocationthread.cpp b/src/diskio/preallocationthread.cpp
+index 1a8856c..914d859 100644
+--- a/src/diskio/preallocationthread.cpp
++++ b/src/diskio/preallocationthread.cpp
+@@ -51,7 +51,8 @@ namespace bt
+ 	
+ 	void PreallocationThread::add(CacheFile::Ptr cache_file)
+ 	{
+-		todo.append(cache_file);
++		if(cache_file)
++			todo.append(cache_file);
+ 	}
+ 
+ 
+-- 
+1.8.0.2
+
diff --git a/0003-Backport-to-1.3-Unbreak-the-non-Linux-case-after-4ff.patch b/0003-Backport-to-1.3-Unbreak-the-non-Linux-case-after-4ff.patch
new file mode 100644
index 0000000..7a4b9a3
--- /dev/null
+++ b/0003-Backport-to-1.3-Unbreak-the-non-Linux-case-after-4ff.patch
@@ -0,0 +1,29 @@
+From 5e4226614361095fc6e83f4abc1dca268de8005b Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <rakuco at FreeBSD.org>
+Date: Wed, 10 Oct 2012 20:59:36 +0300
+Subject: [PATCH 3/9] Backport to 1.3: Unbreak the non-Linux case after
+ 4ffaa9e.
+
+Use the right method name, filePa() does not exist.
+
+(cherry picked from commit 258ae24d6c6be31362b8877c704ddf3f8b253f62)
+---
+ src/util/fileops.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/util/fileops.cpp b/src/util/fileops.cpp
+index 1e5d7d5..329462e 100644
+--- a/src/util/fileops.cpp
++++ b/src/util/fileops.cpp
+@@ -647,7 +647,7 @@ namespace bt
+ 		{
+ 			Solid::StorageAccess* sa = dev.as<Solid::StorageAccess>();
+ 			if(!sa->filePath().isEmpty() && sa->isAccessible())
+-				result.insert(sa->filePa());
++				result.insert(sa->filePath());
+ 		}
+ #endif
+ 		return result;
+-- 
+1.8.0.2
+
diff --git a/0006-Backport-to-1.3-Make-sure-stats-get-updated-properly.patch b/0006-Backport-to-1.3-Make-sure-stats-get-updated-properly.patch
new file mode 100644
index 0000000..fb77549
--- /dev/null
+++ b/0006-Backport-to-1.3-Make-sure-stats-get-updated-properly.patch
@@ -0,0 +1,44 @@
+From 92e8fc65cf0bc35be5fa5cd1bb5e76061745a0cd Mon Sep 17 00:00:00 2001
+From: Joris Guisson <joris.guisson at gmail.com>
+Date: Fri, 2 Nov 2012 13:29:06 +0100
+Subject: [PATCH 6/9] Backport to 1.3: Make sure stats get updated properly
+ during data check
+
+CCBUG: 308707
+
+Conflicts:
+
+	src/torrent/torrentcontrol.cpp
+---
+ ChangeLog                      | 1 +
+ src/torrent/torrentcontrol.cpp | 2 --
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index 7ce9c53..b66d050 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,6 +1,7 @@
+ Changes in 1.3.1:
+ - Add workaround for broken handling of btrfs subvolumes by solid (306825)
+ - Fix crash when preallocating diskspace when a file is enabled during the download of a torrent (307178) 
++- Make sure stats get updated properly during data check (308707)
+ 
+ Changes in 1.3:
+ - Do not pass link local IPv6 addresses to ip parameter of tracker (305187)
+diff --git a/src/torrent/torrentcontrol.cpp b/src/torrent/torrentcontrol.cpp
+index 7cb4eeb..1a01bf2 100644
+--- a/src/torrent/torrentcontrol.cpp
++++ b/src/torrent/torrentcontrol.cpp
+@@ -134,8 +134,6 @@ namespace bt
+ 	void TorrentControl::update()
+ 	{
+ 		UpdateCurrentTime();
+-		if (job_queue->runningJobs())
+-			return;
+ 
+ 		if (istats.io_error)
+ 		{
+-- 
+1.8.0.2
+
diff --git a/0007-Bind-peer-sockets-to-preferred-interface-for-outboun.patch b/0007-Bind-peer-sockets-to-preferred-interface-for-outboun.patch
new file mode 100644
index 0000000..2e52172
--- /dev/null
+++ b/0007-Bind-peer-sockets-to-preferred-interface-for-outboun.patch
@@ -0,0 +1,646 @@
+From 495ce3f3cec2337b31bdd4015ed80849affca0fd Mon Sep 17 00:00:00 2001
+From: Joris Guisson <joris.guisson at gmail.com>
+Date: Mon, 17 Dec 2012 12:23:01 +0100
+Subject: [PATCH 7/9] Bind peer sockets to preferred interface for outbound
+ connections
+
+---
+ ChangeLog                       |   1 +
+ src/diskio/cache.cpp            |   3 +
+ src/net/trafficshapedsocket.cpp | 260 ++++++++++++++++++++------------------
+ src/tracker/httpannouncejob.cpp | 272 ++++++++++++++++++++--------------------
+ src/tracker/httptracker.cpp     |   8 +-
+ 5 files changed, 279 insertions(+), 265 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index b66d050..bfa8fbe 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -2,6 +2,7 @@ Changes in 1.3.1:
+ - Add workaround for broken handling of btrfs subvolumes by solid (306825)
+ - Fix crash when preallocating diskspace when a file is enabled during the download of a torrent (307178) 
+ - Make sure stats get updated properly during data check (308707)
++- Bind peer sockets to preferred interface for outbound connections
+ 
+ Changes in 1.3:
+ - Do not pass link local IPv6 addresses to ip parameter of tracker (305187)
+diff --git a/src/diskio/cache.cpp b/src/diskio/cache.cpp
+index 703a846..ed43c85 100644
+--- a/src/diskio/cache.cpp
++++ b/src/diskio/cache.cpp
+@@ -203,6 +203,9 @@ namespace bt
+ 	
+ 	bool Cache::isStorageMounted(QStringList& missing)
+ 	{
++        if(mount_points.isEmpty())
++            return true;
++        
+ 		missing.clear();
+ 		foreach(const QString & mount_point, mount_points)
+ 		{
+diff --git a/src/net/trafficshapedsocket.cpp b/src/net/trafficshapedsocket.cpp
+index d3e6c90..336acac 100644
+--- a/src/net/trafficshapedsocket.cpp
++++ b/src/net/trafficshapedsocket.cpp
+@@ -20,137 +20,147 @@
+ 
+ 
+ #include "trafficshapedsocket.h"
++
++#include <QStringList>
++#include <util/functions.h>
+ #include "speed.h"
+ #include "socket.h"
+ 
+-#define OUTPUT_BUFFER_SIZE 16393
++const bt::Uint32 OUTPUT_BUFFER_SIZE = 16393;
+ 
+ using namespace bt;
+ 
+ namespace net
+ {
+ 
+-	TrafficShapedSocket::TrafficShapedSocket(SocketDevice* sock) :
+-		rdr(0),
+-		up_gid(0),
+-		down_gid(0),
+-		sock(sock),
+-		mutex(QMutex::Recursive)
+-	{
+-		down_speed = new Speed();
+-		up_speed = new Speed();
+-	}
+-
+-	TrafficShapedSocket::TrafficShapedSocket(int fd, int ip_version) :
+-		rdr(0),
+-		up_gid(0),
+-		down_gid(0),
+-		mutex(QMutex::Recursive)
+-	{
+-		sock = new Socket(fd, ip_version);
+-		down_speed = new Speed();
+-		up_speed = new Speed();
+-	}
+-
+-	TrafficShapedSocket::TrafficShapedSocket(bool tcp, int ip_version) :
+-		rdr(0),
+-		up_gid(0),
+-		down_gid(0),
+-		mutex(QMutex::Recursive)
+-	{
+-		sock = new Socket(tcp, ip_version);
+-		down_speed = new Speed();
+-		up_speed = new Speed();
+-	}
+-	
+-	TrafficShapedSocket::~TrafficShapedSocket()
+-	{
+-		delete up_speed;
+-		delete down_speed;
+-		delete sock;
+-	}
+-	
+-	void TrafficShapedSocket::setGroupID(Uint32 gid,bool upload)
+-	{
+-		if (upload)
+-			up_gid = gid;
+-		else
+-			down_gid = gid;
+-	}
+-	
+-	int TrafficShapedSocket::getDownloadRate() const
+-	{
+-		// getRate is atomic
+-		return down_speed->getRate();
+-	}
+-	
+-	int TrafficShapedSocket::getUploadRate() const
+-	{
+-		// getRate is atomic
+-		return up_speed->getRate();
+-	}
+-	
+-	void TrafficShapedSocket::updateSpeeds(bt::TimeStamp now)
+-	{
+-		mutex.lock();
+-		up_speed->update(now);
+-		down_speed->update(now);
+-		mutex.unlock();
+-	}
+-	
+-	static bt::Uint8 input_buffer[OUTPUT_BUFFER_SIZE];
+-	
+-	Uint32 TrafficShapedSocket::read(bt::Uint32 max_bytes_to_read, bt::TimeStamp now)
+-	{
+-		Uint32 br = 0;
+-		bool no_limit = (max_bytes_to_read == 0);
+-		Uint32 ba = sock->bytesAvailable();
+-		if (ba == 0)
+-		{
+-			// For some strange reason, sometimes bytesAvailable returns 0, while there are 
+-			// bytes to read, so give ba the maximum value it can be
+-			ba = max_bytes_to_read > 0 ? max_bytes_to_read : OUTPUT_BUFFER_SIZE;
+-		}
+-		
+-		while ((br < max_bytes_to_read || no_limit)  && ba > 0)
+-		{
+-			Uint32 tr = ba;
+-			if (tr > OUTPUT_BUFFER_SIZE)
+-				tr = OUTPUT_BUFFER_SIZE;
+-			if (!no_limit && tr + br > max_bytes_to_read)
+-				tr = max_bytes_to_read - br;
+-			
+-			int ret = sock->recv(input_buffer,tr);
+-			if (ret > 0)
+-			{
+-				mutex.lock();
+-				down_speed->onData(ret,now);
+-				mutex.unlock();
+-				if (rdr)
+-				{
+-					postProcess(input_buffer, ret);
+-					rdr->onDataReady(input_buffer,ret);
+-				}
+-				br += ret;
+-				ba -= ret;
+-			}
+-			else if (ret < 0)
+-			{
+-				return br;
+-			}
+-			else
+-			{
+-				sock->close();
+-				return br;
+-			}
+-		}
+-		return br;
+-	}
+-
+-
+-	void TrafficShapedSocket::postProcess(Uint8* data, Uint32 size)
+-	{
+-		Q_UNUSED(data);
+-		Q_UNUSED(size);
+-	}
+-}
+\ No newline at end of file
++    TrafficShapedSocket::TrafficShapedSocket(SocketDevice* sock) :
++        rdr(0),
++        up_gid(0),
++        down_gid(0),
++        sock(sock),
++        mutex(QMutex::Recursive)
++    {
++        down_speed = new Speed();
++        up_speed = new Speed();
++    }
++
++    TrafficShapedSocket::TrafficShapedSocket(int fd, int ip_version) :
++        rdr(0),
++        up_gid(0),
++        down_gid(0),
++        mutex(QMutex::Recursive)
++    {
++        sock = new Socket(fd, ip_version);
++        down_speed = new Speed();
++        up_speed = new Speed();
++    }
++
++    TrafficShapedSocket::TrafficShapedSocket(bool tcp, int ip_version) :
++        rdr(0),
++        up_gid(0),
++        down_gid(0),
++        mutex(QMutex::Recursive)
++    {
++        Socket* socket = new Socket(tcp, ip_version);
++
++        QString iface = NetworkInterface();
++        QStringList ips = NetworkInterfaceIPAddresses(iface);
++        if (ips.size() > 0)
++            socket->bind(ips.front(), 0, false);
++
++        sock = socket;
++        down_speed = new Speed();
++        up_speed = new Speed();
++    }
++
++    TrafficShapedSocket::~TrafficShapedSocket()
++    {
++        delete up_speed;
++        delete down_speed;
++        delete sock;
++    }
++
++    void TrafficShapedSocket::setGroupID(Uint32 gid, bool upload)
++    {
++        if (upload)
++            up_gid = gid;
++        else
++            down_gid = gid;
++    }
++
++    int TrafficShapedSocket::getDownloadRate() const
++    {
++        // getRate is atomic
++        return down_speed->getRate();
++    }
++
++    int TrafficShapedSocket::getUploadRate() const
++    {
++        // getRate is atomic
++        return up_speed->getRate();
++    }
++
++    void TrafficShapedSocket::updateSpeeds(bt::TimeStamp now)
++    {
++        mutex.lock();
++        up_speed->update(now);
++        down_speed->update(now);
++        mutex.unlock();
++    }
++
++    static bt::Uint8 input_buffer[OUTPUT_BUFFER_SIZE];
++
++    Uint32 TrafficShapedSocket::read(bt::Uint32 max_bytes_to_read, bt::TimeStamp now)
++    {
++        Uint32 br = 0;
++        bool no_limit = (max_bytes_to_read == 0);
++        Uint32 ba = sock->bytesAvailable();
++        if (ba == 0)
++        {
++            // For some strange reason, sometimes bytesAvailable returns 0, while there are
++            // bytes to read, so give ba the maximum value it can be
++            ba = max_bytes_to_read > 0 ? max_bytes_to_read : OUTPUT_BUFFER_SIZE;
++        }
++
++        while ((br < max_bytes_to_read || no_limit)  && ba > 0)
++        {
++            Uint32 tr = ba;
++            if (tr > OUTPUT_BUFFER_SIZE)
++                tr = OUTPUT_BUFFER_SIZE;
++            if (!no_limit && tr + br > max_bytes_to_read)
++                tr = max_bytes_to_read - br;
++
++            int ret = sock->recv(input_buffer, tr);
++            if (ret > 0)
++            {
++                mutex.lock();
++                down_speed->onData(ret, now);
++                mutex.unlock();
++                if (rdr)
++                {
++                    postProcess(input_buffer, ret);
++                    rdr->onDataReady(input_buffer, ret);
++                }
++                br += ret;
++                ba -= ret;
++            }
++            else if (ret < 0)
++            {
++                return br;
++            }
++            else
++            {
++                sock->close();
++                return br;
++            }
++        }
++        return br;
++    }
++
++
++    void TrafficShapedSocket::postProcess(Uint8* data, Uint32 size)
++    {
++        Q_UNUSED(data);
++        Q_UNUSED(size);
++    }
++}
+diff --git a/src/tracker/httpannouncejob.cpp b/src/tracker/httpannouncejob.cpp
+index 0e5d29f..11f760f 100644
+--- a/src/tracker/httpannouncejob.cpp
++++ b/src/tracker/httpannouncejob.cpp
+@@ -20,147 +20,149 @@
+ #include <version.h>
+ #include <KLocalizedString>
+ #include <util/log.h>
++#include <util/functions.h>
+ #include <QTimer>
+ #include <QSslError>
++#include <QTcpSocket>
+ 
+ namespace bt
+ {
+ 
+-	HTTPAnnounceJob::HTTPAnnounceJob(const KUrl& url) : url(url),get_id(0),proxy_port(-1)
+-	{
+-		http = new QHttp(this);
+-		connect(http,SIGNAL(requestFinished(int,bool)),this,SLOT(requestFinished(int,bool)));
+-		connect(http,SIGNAL(readyRead(QHttpResponseHeader)),this,SLOT(readData(QHttpResponseHeader)));
+-		connect(http,SIGNAL(sslErrors(QList<QSslError>)),this,SLOT(sslErrors(QList<QSslError>)));
+-	}
+-	
+-	HTTPAnnounceJob::~HTTPAnnounceJob()
+-	{
+-	}
+-
+-	void HTTPAnnounceJob::start()
+-	{
+-		sendRequest();
+-	}
+-	
+-	void HTTPAnnounceJob::sendRequest()
+-	{
+-		QHttp::ConnectionMode mode = url.protocol() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
+-		quint16 port = url.port() < 0 ? 0 : url.port();
+-		quint16 default_port = mode == QHttp::ConnectionModeHttps ? 443 : 80;
+-		http->setHost(url.host(),mode,port);
+-		if (!proxy_host.isEmpty() && proxy_port > 0)
+-			http->setProxy(proxy_host,proxy_port);
+-		
+-		QHttpRequestHeader hdr("GET",url.encodedPathAndQuery(),1,1);
+-		hdr.setValue("User-Agent",bt::GetVersionString());
+-		hdr.setValue("Connection","close");
+-		hdr.setValue("Host",QString("%1:%2").arg(url.host()).arg(url.port(default_port)));
+-		get_id = http->request(hdr);
+-		Out(SYS_TRK|LOG_DEBUG) << "Request sent" << endl;
+-	}
+-	
+-	void HTTPAnnounceJob::kill(bool quietly)
+-	{
+-		http->abort();
+-		if (!quietly)
+-			emitResult();
+-	}
+-
+-	void HTTPAnnounceJob::requestFinished(int id, bool err)
+-	{
+-		if (get_id != id)
+-			return;
+-		
+-		if (err)
+-		{
+-			setErrorText(http->errorString());
+-			emitResult();
+-		}
+-		else
+-		{
+-			switch (http->lastResponse().statusCode())
+-			{
+-				case 300:
+-				case 301:
+-				case 302:
+-				case 303:
+-				case 307:
+-					handleRedirect(http->lastResponse());
+-					break;
+-				case 403:
+-					setError(KIO::ERR_ACCESS_DENIED);
+-					emitResult();
+-					break;
+-				case 404:
+-					setError(KIO::ERR_DOES_NOT_EXIST);
+-					emitResult();
+-					break;
+-				case 500:
+-					setError(KIO::ERR_INTERNAL_SERVER);
+-					emitResult();
+-					break;
+-				default:
+-					emitResult();
+-					break;
+-			}
+-		}
+-	}
+-		
+-	void HTTPAnnounceJob::readData(const QHttpResponseHeader& hdr)
+-	{
+-		const int MAX_REPLY_SIZE = 1024 * 1024;
+-		
+-		int ba = http->bytesAvailable();
+-		int current_size = reply_data.size();
+-		if (current_size + ba > MAX_REPLY_SIZE)
+-		{
+-			// If the reply is larger then a mega byte, the server
+-			// has probably gone bonkers
+-			http->abort();
+-			Out(SYS_TRK|LOG_DEBUG) << "Tracker sending back to much data in announce reply, aborting ..." << endl;
+-		}
+-		else
+-		{
+-			// enlarge reply data and read data to it
+-			reply_data.resize(current_size + ba);
+-			http->read(reply_data.data() + current_size,ba);
+-		}
+-	}
+-	
+-	void HTTPAnnounceJob::setProxy(const QString& host, int port)
+-	{
+-		proxy_host = host;
+-		proxy_port = port;
+-	}
+-
+-
+-	void HTTPAnnounceJob::handleRedirect(const QHttpResponseHeader& hdr)
+-	{
+-		if (!hdr.hasKey("Location"))
+-		{
+-			setErrorText(i18n("Redirect without a redirect location"));
+-			emitResult();
+-		}
+-		else
+-		{
+-			reply_data.clear();
+-			url = hdr.value("Location");
+-			Out(SYS_TRK|LOG_DEBUG) << "Redirected to " << hdr.value("Location") << endl;
+-			sendRequest();
+-		}
+-	}
+-	
+-	void HTTPAnnounceJob::sslErrors(const QList<QSslError>& errors)
+-	{
+-		KUrl u = url;
+-		u.setQuery(QString());
+-		Out(SYS_TRK|LOG_NOTICE) << "SSL errors detected when announcing to " << u.prettyUrl() << ":" << endl;
+-		foreach (const QSslError & err,errors)
+-			Out(SYS_TRK|LOG_NOTICE) << err.errorString() << endl;
+-		Out(SYS_TRK|LOG_NOTICE) << "Errors will be ignored " << endl;
+-		http->ignoreSslErrors();
+-	}
++    HTTPAnnounceJob::HTTPAnnounceJob(const KUrl& url) : url(url), get_id(0), proxy_port(-1)
++    {
++        http = new QHttp(this);
++        connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(requestFinished(int, bool)));
++        connect(http, SIGNAL(readyRead(QHttpResponseHeader)), this, SLOT(readData(QHttpResponseHeader)));
++        connect(http, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
++    }
++
++    HTTPAnnounceJob::~HTTPAnnounceJob()
++    {
++    }
++
++    void HTTPAnnounceJob::start()
++    {
++        sendRequest();
++    }
++
++    void HTTPAnnounceJob::sendRequest()
++    {
++        QHttp::ConnectionMode mode = url.protocol() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
++        quint16 port = url.port() < 0 ? 0 : url.port();
++        quint16 default_port = mode == QHttp::ConnectionModeHttps ? 443 : 80;
++        http->setHost(url.host(), mode, port);
++        if (!proxy_host.isEmpty() && proxy_port > 0)
++            http->setProxy(proxy_host, proxy_port);
++
++        QHttpRequestHeader hdr("GET", url.encodedPathAndQuery(), 1, 1);
++        hdr.setValue("User-Agent", bt::GetVersionString());
++        hdr.setValue("Connection", "close");
++        hdr.setValue("Host", QString("%1:%2").arg(url.host()).arg(url.port(default_port)));
++        get_id = http->request(hdr);
++        Out(SYS_TRK | LOG_DEBUG) << "Request sent" << endl;
++    }
++
++    void HTTPAnnounceJob::kill(bool quietly)
++    {
++        http->abort();
++        if (!quietly)
++            emitResult();
++    }
++
++    void HTTPAnnounceJob::requestFinished(int id, bool err)
++    {
++        if (get_id != id)
++            return;
++
++        if (err)
++        {
++            setErrorText(http->errorString());
++            emitResult();
++        }
++        else
++        {
++            switch (http->lastResponse().statusCode())
++            {
++            case 300:
++            case 301:
++            case 302:
++            case 303:
++            case 307:
++                handleRedirect(http->lastResponse());
++                break;
++            case 403:
++                setError(KIO::ERR_ACCESS_DENIED);
++                emitResult();
++                break;
++            case 404:
++                setError(KIO::ERR_DOES_NOT_EXIST);
++                emitResult();
++                break;
++            case 500:
++                setError(KIO::ERR_INTERNAL_SERVER);
++                emitResult();
++                break;
++            default:
++                emitResult();
++                break;
++            }
++        }
++    }
++
++    void HTTPAnnounceJob::readData(const QHttpResponseHeader& hdr)
++    {
++        const int MAX_REPLY_SIZE = 1024 * 1024;
++
++        int ba = http->bytesAvailable();
++        int current_size = reply_data.size();
++        if (current_size + ba > MAX_REPLY_SIZE)
++        {
++            // If the reply is larger then a mega byte, the server
++            // has probably gone bonkers
++            http->abort();
++            Out(SYS_TRK | LOG_DEBUG) << "Tracker sending back to much data in announce reply, aborting ..." << endl;
++        }
++        else
++        {
++            // enlarge reply data and read data to it
++            reply_data.resize(current_size + ba);
++            http->read(reply_data.data() + current_size, ba);
++        }
++    }
++
++    void HTTPAnnounceJob::setProxy(const QString& host, int port)
++    {
++        proxy_host = host;
++        proxy_port = port;
++    }
++
++
++    void HTTPAnnounceJob::handleRedirect(const QHttpResponseHeader& hdr)
++    {
++        if (!hdr.hasKey("Location"))
++        {
++            setErrorText(i18n("Redirect without a redirect location"));
++            emitResult();
++        }
++        else
++        {
++            reply_data.clear();
++            url = hdr.value("Location");
++            Out(SYS_TRK | LOG_DEBUG) << "Redirected to " << hdr.value("Location") << endl;
++            sendRequest();
++        }
++    }
++
++    void HTTPAnnounceJob::sslErrors(const QList<QSslError>& errors)
++    {
++        KUrl u = url;
++        u.setQuery(QString());
++        Out(SYS_TRK | LOG_NOTICE) << "SSL errors detected when announcing to " << u.prettyUrl() << ":" << endl;
++        foreach (const QSslError& err, errors)
++            Out(SYS_TRK | LOG_NOTICE) << err.errorString() << endl;
++        Out(SYS_TRK | LOG_NOTICE) << "Errors will be ignored " << endl;
++        http->ignoreSslErrors();
++    }
+ 
+ }
+ 
+diff --git a/src/tracker/httptracker.cpp b/src/tracker/httptracker.cpp
+index cef3179..a20f9b5 100644
+--- a/src/tracker/httptracker.cpp
++++ b/src/tracker/httptracker.cpp
+@@ -157,11 +157,11 @@ namespace bt
+ 
+ 		KIO::StoredTransferJob* st = (KIO::StoredTransferJob*)j;
+ 		BDecoder dec(st->data(), false, 0);
+-		BNode* n = 0;
++		QScopedPointer<BNode> n;
+ 
+ 		try
+ 		{
+-			n = dec.decode();
++			n.reset(dec.decode());
+ 		}
+ 		catch (bt::Error & err)
+ 		{
+@@ -171,7 +171,7 @@ namespace bt
+ 
+ 		if (n && n->getType() == BNode::DICT)
+ 		{
+-			BDictNode* d = (BDictNode*)n;
++			BDictNode* d = (BDictNode*)n.data();
+ 			d = d->getDict(QString("files"));
+ 			if (d)
+ 			{
+@@ -198,8 +198,6 @@ namespace bt
+ 				}
+ 			}
+ 		}
+-
+-		delete n;
+ 	}
+ 
+ 	void HTTPTracker::doRequest(WaitJob* wjob)
+-- 
+1.8.0.2
+
diff --git a/libktorrent.spec b/libktorrent.spec
index 1945d06..d124dbf 100644
--- a/libktorrent.spec
+++ b/libktorrent.spec
@@ -2,15 +2,19 @@
 
 Name:    libktorrent
 Version: 1.3.0
-Release: 1%{?pre}%{?dist}
+Release: 2%{?pre}%{?dist}
 Summary: Library providing torrent downloading code
 
-Group:   System Environment/Libraries
 License: GPLv2+
 URL:     http://ktorrent.org/
 Source0: http://ktorrent.org/downloads/4.3.0%{?pre}/libktorrent-%{version}%{?pre}.tar.bz2
 
 ## upstream patches
+Patch101: 0001-Backport-to-1.3-Add-workaround-for-broken-handling-o.patch
+Patch102: 0002-Backport-to-1.3-Fix-crash-when-preallocating-diskspa.patch
+Patch103: 0003-Backport-to-1.3-Unbreak-the-non-Linux-case-after-4ff.patch
+Patch106: 0006-Backport-to-1.3-Make-sure-stats-get-updated-properly.patch
+Patch107: 0007-Bind-peer-sockets-to-preferred-interface-for-outboun.patch
 
 BuildRequires: boost-devel
 BuildRequires: gettext
@@ -26,7 +30,6 @@ BuildRequires: pkgconfig(qca2)
 
 %package devel
 Summary: Developer files for %{name}
-Group:   Development/Libraries
 Obsoletes: ktorrent-devel <= 4.0
 Requires: %{name}%{?_isa} = %{version}-%{release}
 Requires: kdelibs4-devel%{?_isa}
@@ -36,10 +39,15 @@ Requires: gmp-devel%{?_isa}
 %{summary}.
 
 
-
 %prep
 %setup -q -n %{name}-%{version}%{?pre}
 
+%patch101 -p1 -b .0001
+%patch102 -p1 -b .0002
+%patch103 -p1 -b .0003
+%patch106 -p1 -b .0006
+%patch107 -p1 -b .0007
+
 
 %build
 mkdir -p %{_target_platform}
@@ -51,33 +59,28 @@ make %{?_smp_mflags} -C %{_target_platform}
 
 
 %install
-rm -rf %{buildroot}
-
 make install/fast DESTDIR=%{buildroot} -C %{_target_platform}
 
 %find_lang %{name} --with-kde
 
 
-%clean
-rm -rf %{buildroot} 
-
-
 %post -p /sbin/ldconfig
 %postun -p /sbin/ldconfig
 
 %files -f %{name}.lang
-%defattr(-,root,root,-)
 %doc ChangeLog COPYING
 %{_kde4_libdir}/libktorrent.so.5*
 
 %files devel
-%defattr(-,root,root,-)
 %{_kde4_appsdir}/cmake/modules/FindKTorrent.cmake
 %{_kde4_includedir}/libktorrent/
 %{_kde4_libdir}/libktorrent.so
 
 
 %changelog
+* Mon Dec 24 2012 Rex Dieter <rdieter at fedoraproject.org> 1.3.0-2
+- backport some upstream fixes, and some .spec cleanup
+
 * Sat Sep  1 2012 Alexey Kurov <nucleo at fedoraproject.org> - 1.3.0-1
 - libktorrent-1.3.0
 


More information about the scm-commits mailing list