2008-07-04 Albert Lee <[email protected]>
authortrisk
Fri, 04 Jul 2008 10:28:02 +0000
changeset 1263 74f1e78b1e06
parent 1262 35efbff3a1ac
child 1264 d4ca7223d957
2008-07-04 Albert Lee <[email protected]> * SFErtorrent.spec: Fix gcc compilation * base-specs/rlibtorrent.spec: Add patch5 * patches/rlibtorrent-01-madvise.diff: Apply madvise workaround for gcc * patches/rlibtorrent-02-event-ports.diff: Redesign to avoid problems with reusing file descriptors before close() is called * patches/rlibtorrent-04-sunpro.diff: Clean up, allow compiling with gcc * patches/rlibtorrent-05-tracker-usable.diff: Fix tracker update bug * patches/rtorrent-01-solaris.diff: Add extended FILE API handling * patches/rtorrent-03-curl-event.diff: Remove unnecessary overhead * patches/rtorrent-04-sunpro.diff: Clean up, allow compiling with gcc
ChangeLog
SFErtorrent.spec
base-specs/rlibtorrent.spec
patches/rlibtorrent-01-madvise.diff
patches/rlibtorrent-02-event-ports.diff
patches/rlibtorrent-04-sunpro.diff
patches/rlibtorrent-05-tracker-usable.diff
patches/rtorrent-01-solaris.diff
patches/rtorrent-03-curl-event.diff
patches/rtorrent-04-sunpro.diff
--- a/ChangeLog	Thu Jul 03 10:51:57 2008 +0000
+++ b/ChangeLog	Fri Jul 04 10:28:02 2008 +0000
@@ -1,3 +1,16 @@
+2008-07-04 Albert Lee <[email protected]>
+
+	* SFErtorrent.spec: Fix gcc compilation
+	* base-specs/rlibtorrent.spec: Add patch5
+	* patches/rlibtorrent-01-madvise.diff: Apply madvise workaround for gcc
+	* patches/rlibtorrent-02-event-ports.diff: Redesign to avoid problems
+	  with reusing file descriptors before close() is called
+	* patches/rlibtorrent-04-sunpro.diff: Clean up, allow compiling with gcc
+	* patches/rlibtorrent-05-tracker-usable.diff: Fix tracker update bug
+	* patches/rtorrent-01-solaris.diff: Add extended FILE API handling
+	* patches/rtorrent-03-curl-event.diff: Remove unnecessary overhead
+	* patches/rtorrent-04-sunpro.diff: Clean up, allow compiling with gcc
+
 2008-07-03 Dick Hoogendijk <[email protected]>
 	* SFEsylpheed.spec: bump to the stable 2.5 release
 
--- a/SFErtorrent.spec	Thu Jul 03 10:51:57 2008 +0000
+++ b/SFErtorrent.spec	Fri Jul 04 10:28:02 2008 +0000
@@ -5,14 +5,14 @@
 #
 %include Solaris.inc
 
+# Studio support is experimental
+#%define cc_is_gcc 1
+
 %include base.inc
 
 %use rtorrent = rtorrent.spec
 %use rlibtorrent = rlibtorrent.spec
 
-# Studio support is experimental
-%define cc_is_gcc 1
-
 Name:		SFErtorrent
 Summary:	%{rtorrent.summary}
 Version:	%{rtorrent.version}
@@ -47,8 +47,8 @@
 export CXX=/usr/sfw/bin/g++
 export CXXFLAGS="%{gcc_cxx_optflags} \
  -I%{sfw_inc} -I%{gnu_inc} -I%{gnu_inc}/ncurses -I$LIBTORRENT_ROOT/src"
-export LDFLAGS="%_ldflags %{sfw_lib_path} %{gnu_lib_path} -R%{_cxx_libdir} \
- -L$LIBTORRENT_ROOT/src/.libs"
+export LDFLAGS="%_ldflags %{sfw_lib_path} %{gnu_lib_path} \
+ -L%{_cxx_libdir} -R%{_cxx_libdir} -L$LIBTORRENT_ROOT/src/.libs"
 %else
 # __attribute__((unused)) test uses $CC
 export CC="$CXX"
@@ -59,7 +59,7 @@
  -L$LIBTORRENT_ROOT/src/.libs"
 %endif
 
-export PKG_CONFIG_PATH="%{_cxx_libdir}/pkgconfig:$LIBTORRENT_ROOT"
+export PKG_CONFIG_PATH="%{_cxx_libdir}/pkgconfig:%{_sfw_libdir}/pkgconfig:$LIBTORRENT_ROOT"
 %rlibtorrent.build -d %name-%version/%{base_arch}
 %if %cc_is_gcc
 %else
@@ -84,6 +84,8 @@
 %{_mandir}/man1/rtorrent.1
 
 %changelog
+* Fri Jul 04 2008 - [email protected]
+- Fix gcc compilation
 * Tue Jun 24 2008 - [email protected]
 - Allow building with Studio
 - Rename SFExmlrpc-c-gpp dependency, add SUNWsigcpp
--- a/base-specs/rlibtorrent.spec	Thu Jul 03 10:51:57 2008 +0000
+++ b/base-specs/rlibtorrent.spec	Fri Jul 04 10:28:02 2008 +0000
@@ -12,6 +12,7 @@
 Patch2:         rlibtorrent-02-event-ports.diff
 Patch3:         rlibtorrent-03-dh-generate.diff
 Patch4:         rlibtorrent-04-sunpro.diff
+Patch5:         rlibtorrent-05-tracker-usable.diff
 BuildRoot:	%{_tmppath}/%{name}-%{version}-build
 
 %prep
@@ -20,6 +21,7 @@
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
+%patch5 -p1
 
 %build
 CPUS=`/usr/sbin/psrinfo | grep on-line | wc -l | tr -d ' '`
@@ -52,6 +54,8 @@
 rm -rf $RPM_BUILD_ROOT
 
 %changelog
+* Fri Jul 04 2008 - [email protected]
+- Add patch5 for bug in tracker updating
 * Thu Jun 26 2008 - [email protected]
 - Add patch3 for DH key error, patch4 for Studio compatibility
 * Mon Jun 16 2008 - [email protected]
--- a/patches/rlibtorrent-01-madvise.diff	Thu Jul 03 10:51:57 2008 +0000
+++ b/patches/rlibtorrent-01-madvise.diff	Fri Jul 04 10:28:02 2008 +0000
@@ -1,3 +1,22 @@
+--- libtorrent-0.12.2.orig/src/data/memory_chunk.cc	(revision 1060)
++++ libtorrent-0.12.2/src/data/memory_chunk.cc	(working copy)
+@@ -41,6 +41,16 @@
+ #include <unistd.h>
+ #include <sys/types.h>
+ #include <sys/mman.h>
++#if defined(__sun) && defined(__SVR4)
++/* Ugly hack to make this compile on Solaris with g++. See
++ * http://www.opensolaris.org/jive/thread.jspa?threadID=21035&tstart=0
++ */
++#if (_POSIX_C_SOURCE > 2) || defined(_XPG4_2)
++extern "C" {
++extern int madvise(caddr_t, size_t, int);
++}
++#endif
++#endif
+ #include <rak/error_number.h>
+ 
+ #include "torrent/exceptions.h"
 --- libtorrent-0.12.2.orig/scripts/common.m4	2008-05-07 08:19:12.000000000 -0400
 +++ libtorrent-0.12.2/scripts/common.m4	2008-06-23 17:04:24.567475080 -0400
 @@ -170,7 +170,7 @@
--- a/patches/rlibtorrent-02-event-ports.diff	Thu Jul 03 10:51:57 2008 +0000
+++ b/patches/rlibtorrent-02-event-ports.diff	Fri Jul 04 10:28:02 2008 +0000
@@ -18,10 +18,10 @@
  
 +AC_DEFUN([TORRENT_WITH_PORTS], [
 +  AC_ARG_WITH(ports,
-+    [  --with-ports            enable Solaris ports. [[default=no]]],
++    [  --with-ports            enable Solaris event ports. [[default=no]]],
 +    [
 +        if test "$withval" = "yes"; then
-+            AC_DEFINE(USE_PORTS, 1, Enable ports.)
++            AC_DEFINE(USE_PORTS, 1, Enable event ports.)
 +        fi
 +    ])
 +])
@@ -35,8 +35,8 @@
  	poll_epoll.h \
  	poll_kqueue.h \
  	poll_kqueue.cc \
++	poll_ports.h \
 +	poll_ports.cc \
-+	poll_ports.h \
  	poll_select.h \
  	poll_select.cc \
  	rate.cc \
@@ -48,10 +48,118 @@
  	poll_kqueue.h \
  	poll_select.h \
  	rate.h \
+diff -urN libtorrent.orig/src/torrent/poll_ports.h libtorrent/src/torrent/poll_ports.h
+--- libtorrent.orig/src/torrent/poll_ports.h	1969-12-31 19:00:00.000000000 -0500
++++ libtorrent/src/torrent/poll_ports.h	2008-05-12 00:42:15.000000000 -0400
+@@ -0,0 +1,104 @@
++// libTorrent - BitTorrent library
++// Copyright (C) 2005-2007, Jari Sundell
++//
++// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++//
++// In addition, as a special exception, the copyright holders give
++// permission to link the code of portions of this program with the
++// OpenSSL library under certain conditions as described in each
++// individual source file, and distribute linked combinations
++// including the two.
++//
++// You must obey the GNU General Public License in all respects for
++// all of the code used other than OpenSSL.  If you modify file(s)
++// with this exception, you may extend this exception to your version
++// of the file(s), but you are not obligated to do so.  If you do not
++// wish to do so, delete this exception statement from your version.
++// If you delete this exception statement from all source files in the
++// program, then also delete it here.
++//
++// Contact:  Jari Sundell <[email protected]>
++//
++//           Skomakerveien 33
++//           3185 Skoppum, NORWAY
++
++#ifndef LIBTORRENT_TORRENT_POLL_PORTS_H
++#define LIBTORRENT_TORRENT_POLL_PORTS_H
++
++#include <vector>
++#include <map>
++#include <torrent/poll.h>
++
++struct port_event;
++
++namespace torrent {
++
++class LIBTORRENT_EXPORT PollPorts : public torrent::Poll {
++public:
++  typedef std::pair<Event*,int> ObjectMask;
++  typedef std::vector<ObjectMask> Table;
++
++  static PollPorts*   create(int maxOpenSockets);
++  virtual ~PollPorts();
++
++  int                 poll(int msec);
++  void                perform();
++
++  int                 file_descriptor() { return m_fd; }
++
++  virtual uint32_t    open_max() const { return m_table.size(); }
++
++  // torrent::Event::get_fd() is guaranteed to be valid and remain constant
++  // from open(...) is called to close(...) returns.
++  virtual void        open(torrent::Event* event);
++  virtual void        close(torrent::Event* event);
++
++  // Functions for checking whetever the torrent::Event is listening to r/w/e?
++  virtual bool        in_read(torrent::Event* event);
++  virtual bool        in_write(torrent::Event* event);
++  virtual bool        in_error(torrent::Event* event);
++
++  // These functions may be called on 'event's that might, or might
++  // not, already be in the set.
++  virtual void        insert_read(torrent::Event* event);
++  virtual void        insert_write(torrent::Event* event);
++  virtual void        insert_error(torrent::Event* event);
++
++  virtual void        remove_read(torrent::Event* event);
++  virtual void        remove_write(torrent::Event* event);
++  virtual void        remove_error(torrent::Event* event);
++
++private:
++  PollPorts(int fd, int maxEvents, int maxOpenSockets);
++
++  inline Event*       event_object(Event* e);
++  inline int          event_mask(Event* e);
++  inline void         set_event_object(Event* e);
++  inline void         set_event_mask(Event* e, int m);
++
++  inline void         modify(torrent::Event* event, int mask);
++
++  int                 m_fd;
++
++  int                 m_maxEvents;
++  int                 m_waitingEvents;
++
++  Table               m_table;
++  port_event*         m_events;
++};
++
++}
++
++#endif
 diff -urN libtorrent.orig/src/torrent/poll_ports.cc libtorrent/src/torrent/poll_ports.cc
 --- libtorrent.orig/src/torrent/poll_ports.cc	1969-12-31 19:00:00.000000000 -0500
 +++ libtorrent/src/torrent/poll_ports.cc	2008-06-10 14:48:05.000000000 -0400
-@@ -0,0 +1,331 @@
+@@ -0,0 +1,338 @@
 +// libTorrent - BitTorrent library
 +// Copyright (C) 2005-2007, Jari Sundell
 +//
@@ -91,6 +199,7 @@
 +#include "config.h"
 +
 +#include <cerrno>
++#include <cstring>
 +#include <iostream>
 +
 +#include <unistd.h>
@@ -113,19 +222,33 @@
 +namespace torrent {
 +
 +#ifdef USE_PORTS
++inline Event*
++PollPorts::event_object(Event* e) {
++  return m_table[e->file_descriptor()].first;
++}
 +
-+inline uint32_t
++inline int
 +PollPorts::event_mask(Event* e) {
-+  return m_table[e->file_descriptor()];
++  if (event_object(e) != e)
++    return 0;
++  return m_table[e->file_descriptor()].second;
 +}
 +
 +inline void
-+PollPorts::set_event_mask(Event* e, uint32_t m) {
-+  m_table[e->file_descriptor()] = m;
++PollPorts::set_event_object(Event* e) {
++  m_table[e->file_descriptor()] = std::pair<Event*,int>(e, 0);
 +}
 +
 +inline void
-+PollPorts::modify(Event* event, uint32_t mask) {
++PollPorts::set_event_mask(Event* e, int m) {
++  m_table[e->file_descriptor()].second = m;
++}
++
++inline void
++PollPorts::modify(Event* event, int mask) {
++  if (event_object(event) != event)
++    return;
++
 +  if (event_mask(event) == mask)
 +    return;
 +
@@ -156,12 +279,12 @@
 +  m_maxEvents(maxEvents),
 +  m_waitingEvents(0),
 +  m_events(new port_event_t[maxEvents]) {
-+
-+  m_table.resize(maxOpenSockets); 
++  m_table.resize(maxOpenSockets);
 +}
 +
 +PollPorts::~PollPorts() {
 +  m_table.clear();
++  delete [] m_events;
 +
 +  ::close(m_fd);
 +}
@@ -199,49 +322,46 @@
 +    // TODO: Make it so that it checks that read/write is wanted, that
 +    // it wasn't removed from one of them but not closed.
 +
-+    if (itr->portev_user == NULL)
++    Event *e = static_cast<Event*>(itr->portev_user);
++    if (e == NULL)
 +      continue;
 +
 +    if (itr->portev_events & POLLERR 
-+        && event_mask((Event*)itr->portev_user) & POLLERR)
-+      ((Event*)itr->portev_user)->event_error();
++        && event_mask(e) & POLLERR)
++      e->event_error();
 +
-+    if (itr->portev_user == NULL)
++    if (itr->portev_user != e)
 +      continue;
 +
 +    if (itr->portev_events & POLLIN
-+        && event_mask((Event*)itr->portev_user) & POLLIN)
-+      ((Event*)itr->portev_user)->event_read();
++        && event_mask(e) & POLLIN)
++      e->event_read();
 +
-+    if (itr->portev_user == NULL)
++    if (itr->portev_user != e)
 +      continue;
 +
 +    if (itr->portev_events & POLLOUT
-+        && event_mask((Event*)itr->portev_user) & POLLOUT)
-+      ((Event*)itr->portev_user)->event_write();
++        && event_mask(e) & POLLOUT)
++      e->event_write();
 +
-+    if (itr->portev_user == NULL)
++    if (itr->portev_user != e)
 +      continue;
 +
 +    // Since port events are one-shot, re-add the fd after we process
 +    // its events.
 +
 +    port_associate(m_fd, PORT_SOURCE_FD, itr->portev_object,
-+        event_mask((Event *)itr->portev_user), itr->portev_user);
++        event_mask(e), e);
 +  }
 +
 +  m_waitingEvents = 0;
 +}
 +
-+uint32_t
-+PollPorts::open_max() const {
-+  return m_table.size();
-+}
-+
 +void
 +PollPorts::open(Event* event) {
-+  if (event_mask(event) != 0)
++  if (event_object(event) == event && event_mask(event) != 0)
 +    throw internal_error("PollPorts::open(...) called but the file descriptor is active");
++  set_event_object(event);
 +}
 +
 +void
@@ -286,22 +406,17 @@
 +
 +void
 +PollPorts::remove_read(Event* event) {
-+  uint32_t mask = event_mask(event) & ~POLLIN;
-+  modify(event, mask);
++  modify(event, event_mask(event) & ~POLLIN);
 +}
 +
 +void
 +PollPorts::remove_write(Event* event) {
-+  uint32_t mask = event_mask(event) & ~POLLOUT;
-+
-+  modify(event, mask);
++  modify(event, event_mask(event) & ~POLLOUT);
 +}
 +
 +void
 +PollPorts::remove_error(Event* event) {
-+  uint32_t mask = event_mask(event) & ~POLLERR;
-+
-+  modify(event, mask);
++  modify(event, event_mask(event) & ~POLLERR);
 +}
 +
 +#else // USE_PORTS
@@ -383,107 +498,3 @@
 +#endif // USE_PORTS
 +
 +}
-diff -urN libtorrent.orig/src/torrent/poll_ports.h libtorrent/src/torrent/poll_ports.h
---- libtorrent.orig/src/torrent/poll_ports.h	1969-12-31 19:00:00.000000000 -0500
-+++ libtorrent/src/torrent/poll_ports.h	2008-05-12 00:42:15.000000000 -0400
-@@ -0,0 +1,100 @@
-+// libTorrent - BitTorrent library
-+// Copyright (C) 2005-2007, Jari Sundell
-+//
-+// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+//
-+// In addition, as a special exception, the copyright holders give
-+// permission to link the code of portions of this program with the
-+// OpenSSL library under certain conditions as described in each
-+// individual source file, and distribute linked combinations
-+// including the two.
-+//
-+// You must obey the GNU General Public License in all respects for
-+// all of the code used other than OpenSSL.  If you modify file(s)
-+// with this exception, you may extend this exception to your version
-+// of the file(s), but you are not obligated to do so.  If you do not
-+// wish to do so, delete this exception statement from your version.
-+// If you delete this exception statement from all source files in the
-+// program, then also delete it here.
-+//
-+// Contact:  Jari Sundell <[email protected]>
-+//
-+//           Skomakerveien 33
-+//           3185 Skoppum, NORWAY
-+
-+#ifndef LIBTORRENT_TORRENT_POLL_PORTS_H
-+#define LIBTORRENT_TORRENT_POLL_PORTS_H
-+
-+#include <vector>
-+#include <torrent/poll.h>
-+
-+struct port_event;
-+
-+namespace torrent {
-+
-+class LIBTORRENT_EXPORT PollPorts : public torrent::Poll {
-+public:
-+  typedef std::vector<uint32_t> Table;
-+
-+  static PollPorts*   create(int maxOpenSockets);
-+  virtual ~PollPorts();
-+
-+  int                 poll(int msec);
-+  void                perform();
-+
-+  int                 file_descriptor() { return m_fd; }
-+
-+  virtual uint32_t    open_max() const;
-+
-+  // torrent::Event::get_fd() is guaranteed to be valid and remain constant
-+  // from open(...) is called to close(...) returns.
-+  virtual void        open(torrent::Event* event);
-+  virtual void        close(torrent::Event* event);
-+
-+  // Functions for checking whetever the torrent::Event is listening to r/w/e?
-+  virtual bool        in_read(torrent::Event* event);
-+  virtual bool        in_write(torrent::Event* event);
-+  virtual bool        in_error(torrent::Event* event);
-+
-+  // These functions may be called on 'event's that might, or might
-+  // not, already be in the set.
-+  virtual void        insert_read(torrent::Event* event);
-+  virtual void        insert_write(torrent::Event* event);
-+  virtual void        insert_error(torrent::Event* event);
-+
-+  virtual void        remove_read(torrent::Event* event);
-+  virtual void        remove_write(torrent::Event* event);
-+  virtual void        remove_error(torrent::Event* event);
-+
-+private:
-+  PollPorts(int fd, int maxEvents, int maxOpenSockets);
-+
-+  inline uint32_t     event_mask(Event* e);
-+  inline void         set_event_mask(Event* e, uint32_t m);
-+
-+  inline void         modify(torrent::Event* event, uint32_t mask);
-+
-+  int                 m_fd;
-+
-+  int                 m_maxEvents;
-+  int                 m_waitingEvents;
-+
-+  Table               m_table;
-+  port_event*        m_events;
-+};
-+
-+}
-+
-+#endif
--- a/patches/rlibtorrent-04-sunpro.diff	Thu Jul 03 10:51:57 2008 +0000
+++ b/patches/rlibtorrent-04-sunpro.diff	Fri Jul 04 10:28:02 2008 +0000
@@ -80,7 +80,7 @@
  
 --- rtorrent-0.8.2.orig/rak/algorithm.h	2008-05-07 08:19:12.000000000 -0400
 +++ rtorrent-0.8.2/rak/algorithm.h	2008-06-25 17:27:39.728352000 -0400
-@@ -40,6 +40,45 @@
+@@ -40,6 +40,63 @@
  #include <algorithm>
  #include <functional>
  
@@ -120,6 +120,24 @@
 +               iterator_traits<ForwardIterator>::iterator_category());
 +    return n;
 +  }
++
++  template <class InputIterator, class T>
++  inline typename iterator_traits<InputIterator>::difference_type
++  count (InputIterator first, InputIterator last, const T& value)
++  {
++    typename iterator_traits<InputIterator>::difference_type n = 0;
++    count(first, last, value, n);
++    return n;
++  }
++
++  template <class InputIterator, class Predicate>
++  inline typename iterator_traits<InputIterator>::difference_type
++  count_if (InputIterator first, InputIterator last, Predicate pred)
++  {
++    typename iterator_traits<InputIterator>::difference_type n = 0;
++    count_if(first, last, pred, n);
++    return n;
++  }
 +}
 +#endif
 +
@@ -128,15 +146,18 @@
  template <typename _InputIter, typename _Function>
 --- libtorrent-0.12.2.orig/src/download/choke_manager.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/download/choke_manager.cc	2008-06-24 13:40:32.322166472 -0400
-@@ -43,6 +43,7 @@
+@@ -41,8 +41,10 @@
+ #include <numeric>
+ #include <cstdlib>
  
++#include "rak/algorithm.h"
  #include "protocol/peer_connection_base.h"
  #include "torrent/peer/connection_list.h"
 +#include "resource_manager.h"
  
  #include "choke_manager.h"
  #include "choke_manager_node.h"
-@@ -261,7 +262,7 @@
+@@ -261,7 +263,7 @@
                                          rak::less(i * ChokeManager::order_base + (ChokeManager::order_base - 1),
                                                    rak::mem_ref(&ChokeManager::value_type::second)));
  
@@ -145,58 +166,6 @@
        weightTotal += weights[i];
    }
  
-@@ -271,7 +272,8 @@
-     uint32_t base = unchoke / weightTotal;
- 
-     for (uint32_t itr = 0; itr < ChokeManager::order_max_size; itr++) {
--      uint32_t s = std::distance(target[itr].second, target[itr + 1].second);
-+      uint32_t s = 0;
-+      std::distance(target[itr].second, target[itr + 1].second, s);
- 
-       if (weights[itr] == 0 || target[itr].first >= s)
-         continue;
-@@ -294,7 +296,8 @@
-     unsigned int itr = 0;
- 
-     for ( ; ; itr++) {
--      uint32_t s = std::distance(target[itr].second, target[itr + 1].second);
-+      uint32_t s = 0;
-+      std::distance(target[itr].second, target[itr + 1].second, s);
- 
-       if (weights[itr] == 0 || target[itr].first >= s)
-         continue;
-@@ -306,7 +309,8 @@
-     }
- 
-     for ( ; weightTotal != 0 && unchoke != 0; itr = (itr + 1) % ChokeManager::order_max_size) {
--      uint32_t s = std::distance(target[itr].second, target[itr + 1].second);
-+      uint32_t s = 0;
-+      std::distance(target[itr].second, target[itr + 1].second, s);
- 
-       if (weights[itr] == 0 || target[itr].first >= s)
-         continue;
-@@ -336,7 +340,9 @@
-   // Iterate in reverse so that the iterators in 'target' remain vaild
-   // even though we remove random ranges.
-   for (target_type* itr = target + order_max_size; itr != target; itr--) {
--    if ((itr - 1)->first > (uint32_t)std::distance((itr - 1)->second, itr->second))
-+    uint32_t s = 0;
-+    std::distance((itr - 1)->second, itr->second, s);
-+    if ((itr - 1)->first > s)
-       throw internal_error("ChokeManager::choke_range(...) itr->first > std::distance((itr - 1)->second, itr->second).");
- 
-     if (itr->second - (itr - 1)->first > itr->second ||
-@@ -379,7 +385,9 @@
-   uint32_t count = 0;
- 
-   for (target_type* itr = target + order_max_size; itr != target; itr--) {
--    if ((itr - 1)->first > (uint32_t)std::distance((itr - 1)->second, itr->second))
-+    uint32_t s = 0;
-+    std::distance((itr - 1)->second, itr->second, s);
-+    if ((itr - 1)->first > s)
-       throw internal_error("ChokeManager::unchoke_range(...) itr->first > std::distance((itr - 1)->second, itr->second).");
- 
-     if (itr->second - (itr - 1)->first > itr->second ||
 --- libtorrent-0.12.2.orig/src/download/delegator.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/download/delegator.cc	2008-06-24 13:42:52.016431294 -0400
 @@ -46,7 +46,9 @@
@@ -366,17 +335,14 @@
    m_data = new char[m_length];
 --- libtorrent-0.12.2.orig/src/dht/dht_bucket.cc	2008-05-07 08:19:12.000000000 -0400
 +++ libtorrent-0.12.2/src/dht/dht_bucket.cc	2008-06-24 02:41:04.089051646 -0400
-@@ -85,8 +85,8 @@
+@@ -36,6 +36,7 @@
+ 
+ #include "config.h"
  
- void
- DhtBucket::count() {
--  m_good = std::count_if(begin(), end(), std::mem_fun(&DhtNode::is_good));
--  m_bad = std::count_if(begin(), end(), std::mem_fun(&DhtNode::is_bad));
-+  std::count_if(begin(), end(), std::mem_fun(&DhtNode::is_good), m_good);
-+  std::count_if(begin(), end(), std::mem_fun(&DhtNode::is_bad), m_bad);
- }
++#include "rak/algorithm.h"
+ #include "torrent/exceptions.h"
  
- // Called every 15 minutes for housekeeping.
+ #include "dht_bucket.h"
 --- libtorrent-0.12.2.orig/src/dht/dht_node.cc	2008-05-07 08:19:12.000000000 -0400
 +++ libtorrent-0.12.2/src/dht/dht_node.cc	2008-06-28 15:57:24.639449987 -0400
 @@ -77,7 +77,10 @@
@@ -448,33 +414,32 @@
    // For initial seeding, check if chunk is well seeded now, and if so
 --- libtorrent-0.12.2.orig/src/protocol/handshake_manager.cc	2008-05-07 08:19:12.000000000 -0400
 +++ libtorrent-0.12.2/src/protocol/handshake_manager.cc	2008-06-24 15:11:50.179786185 -0400
-@@ -67,7 +67,9 @@
+@@ -37,6 +37,7 @@
+ #include "config.h"
  
- HandshakeManager::size_type
- HandshakeManager::size_info(DownloadMain* info) const {
--  return std::count_if(base_type::begin(), base_type::end(), rak::equal(info, std::mem_fun(&Handshake::download)));
-+  uint32_t size = 0;
-+  std::count_if(base_type::begin(), base_type::end(), rak::equal(info, std::mem_fun(&Handshake::download)), size);
-+  return size;
- }
+ #include <rak/socket_address.h>
++#include <rak/algorithm.h>
  
- void
+ #include "torrent/exceptions.h"
+ #include "torrent/error.h"
 --- libtorrent-0.12.2.orig/src/protocol/handshake.cc	2008-05-07 08:19:12.000000000 -0400
 +++ libtorrent-0.12.2/src/protocol/handshake.cc	2008-06-24 15:05:32.683533289 -0400
-@@ -38,6 +38,7 @@
+@@ -36,8 +36,10 @@
  
+ #include "config.h"
+ 
++#include "rak/algorithm.h"
  #include "download/download_info.h"
  #include "download/download_main.h"
 +#include "download/download_manager.h"
  #include "net/throttle_list.h"
  #include "torrent/dht_manager.h"
  #include "torrent/exceptions.h"
-@@ -324,14 +325,17 @@
+@@ -324,14 +326,16 @@
        return false;
    }
  
-+  uint32_t len = 0;
-+  std::distance(m_readBuffer.position(), itr, len);
++  uint32_t len = std::distance(m_readBuffer.position(), itr);
 +
    if (m_incoming) {
      // We've found HASH('req1' + S), skip that and go on reading the
@@ -634,7 +599,15 @@
  #include "hash_chunk.h"
 --- libtorrent-0.12.2.orig/src/data/chunk_part.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/data/chunk_part.cc	2008-06-23 19:16:19.997055043 -0400
-@@ -70,11 +70,14 @@
+@@ -39,6 +39,7 @@
+ #include <algorithm>
+ #include <unistd.h>
+ 
++#include "rak/algorithm.h"
+ #include "torrent/exceptions.h"
+ #include "chunk_part.h"
+ 
+@@ -70,11 +71,13 @@
  
    int length = size() - pos;
    int touched = m_chunk.pages_touched(pos, length);
@@ -643,9 +616,7 @@
  
    m_chunk.incore(buf, pos, length);
  
--  int dist = std::distance(buf, std::find(buf, buf + touched, 0));
-+  unsigned int dist = 0;
-+  std::distance(buf, std::find(buf, buf + touched, 0), dist);
+   int dist = std::distance(buf, std::find(buf, buf + touched, 0));
 +
 +  delete buf;
  
@@ -662,18 +633,17 @@
  
  #include "chunk_list.h"
  #include "chunk.h"
-@@ -349,16 +351,19 @@
+@@ -349,16 +351,18 @@
      bool required = std::find_if(itr, range, std::bind1st(std::mem_fun(&ChunkList::check_node), this)) != range;
      dontSkip = dontSkip || required;
  
 -    if (!required && std::distance(itr, range) < maxDistance) {
-+    uint32_t l = 0;
-+    std::distance(itr, range, l);
++    unsigned int l = range - itr;
 +
 +    if (!required && l < maxDistance) {
        // Don't sync this range.
 -      unsigned int l = std::min(range - itr, itr - first);
-+      l = std::min(range - itr, itr - first);
++      l = std::min(l, (unsigned int)(itr - first));
        std::swap_ranges(first, first + l, range - l);
  
        first += l;
@@ -712,34 +682,16 @@
  
 --- libtorrent-0.12.2.orig/src/tracker/tracker_manager.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/tracker/tracker_manager.cc	2008-06-24 15:23:58.547482693 -0400
-@@ -37,6 +37,7 @@
+@@ -36,7 +36,9 @@
+ 
  #include "config.h"
  
++#include "rak/algorithm.h"
  #include "download/download_info.h"
 +#include "download/download_wrapper.h"
  #include "torrent/exceptions.h"
  #include "torrent/tracker.h"
  #include "torrent/tracker_list.h"
-@@ -202,7 +203,9 @@
- 
- TrackerManager::size_type
- TrackerManager::focus_index() const {
--  return std::distance(m_control->begin(), m_control->focus());
-+  uint32_t index = 0;
-+  std::distance(m_control->begin(), m_control->focus(), index);
-+  return index;
- }
- 
- void
-@@ -263,7 +266,7 @@
-     return m_slotSuccess(l);
- 
-   if (m_control->state() == DownloadInfo::STARTED)
--    m_initialTracker = std::distance(m_control->begin(), m_control->focus());
-+    std::distance(m_control->begin(), m_control->focus(), m_initialTracker);
- 
-   // Don't reset the focus when we're requesting more peers. If we
-   // want to query the next tracker in the list we need to remember
 --- libtorrent-0.12.2.orig/src/tracker/tracker_udp.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/tracker/tracker_udp.cc	2008-06-24 15:35:31.207275209 -0400
 @@ -45,6 +45,7 @@
@@ -783,18 +735,15 @@
  }
 --- libtorrent-0.12.2.orig/src/torrent/object_stream.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/torrent/object_stream.cc	2008-06-23 22:07:52.705714634 -0400
-@@ -185,7 +185,9 @@
- void
- object_write_bencode_c_string(object_write_data_t* output, const char* srcData, uint32_t srcLength) {
-   do {
--    uint32_t len = std::min<uint32_t>(srcLength, std::distance(output->pos, output->buffer.second));
-+    uint32_t len = 0;
-+    std::distance(output->pos, output->buffer.second, len);
-+    len = std::min<uint32_t>(srcLength, len);
+@@ -39,6 +39,7 @@
+ #include <iterator>
+ #include <iostream>
+ #include <rak/functional.h>
++#include <rak/algorithm.h>
  
-     std::memcpy(output->pos, srcData, len);
+ #include "utils/sha1.h"
  
-@@ -233,7 +235,7 @@
+@@ -233,7 +234,7 @@
      src /= 10;
    }
  
@@ -803,55 +752,26 @@
  }
  
  void
-@@ -306,14 +308,18 @@
- 
- object_buffer_t
- object_write_to_sha1(void* data, object_buffer_t buffer) {
--  reinterpret_cast<Sha1*>(data)->update(buffer.first, std::distance(buffer.first, buffer.second));
-+  uint32_t len = 0;
-+  std::distance(buffer.first, buffer.second, len);
-+  reinterpret_cast<Sha1*>(data)->update(buffer.first, len);
- 
-   return buffer;
- }
- 
- object_buffer_t
- object_write_to_stream(void* data, object_buffer_t buffer) {
--  reinterpret_cast<std::ostream*>(data)->write(buffer.first, std::distance(buffer.first, buffer.second));
-+  uint32_t len = 0;
-+  std::distance(buffer.first, buffer.second, len);
-+  reinterpret_cast<std::ostream*>(data)->write(buffer.first, len);
- 
-   if (reinterpret_cast<std::ostream*>(data)->bad())
-     return object_buffer_t(buffer.first, buffer.first);
 --- libtorrent-0.12.2.orig/src/torrent/download.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/torrent/download.cc	2008-06-23 18:56:21.847160292 -0400
-@@ -395,7 +395,9 @@
-   if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking())
-     throw input_error("Download::set_bitfield(...) Download in invalid state.");
+@@ -36,6 +36,7 @@
+ 
+ #include "config.h"
  
--  if (std::distance(first, last) != (ptrdiff_t)m_ptr->main()->file_list()->bitfield()->size_bytes())
-+  uint32_t len = 0;
-+  std::distance(first, last, len);
-+  if (len != (ptrdiff_t)m_ptr->main()->file_list()->bitfield()->size_bytes())
-     throw input_error("Download::set_bitfield(...) Invalid length.");
- 
-   Bitfield* bitfield = m_ptr->main()->file_list()->mutable_bitfield();
++#include <rak/algorithm.h>
+ #include <rak/functional.h>
+ #include <sigc++/adaptors/bind.h>
+ #include <sigc++/adaptors/hide.h>
 --- libtorrent-0.12.2.orig/src/torrent/data/file_list.cc	2008-06-23 18:17:42.415878000 -0400
 +++ libtorrent-0.12.2/src/torrent/data/file_list.cc	2008-06-23 18:21:51.029221269 -0400
-@@ -211,8 +211,10 @@
-   File* oldFile = *position;
- 
-   uint64_t offset = oldFile->offset();
--  size_type index = std::distance(begin(), position);
--  size_type length = std::distance(first, last);
-+  size_type index = 0;
-+  size_type length = 0;
-+  std::distance(begin(), position, index);
-+  std::distance(first, last, length);
- 
-   base_type::insert(position, length - 1, NULL);
-   position = begin() + index;
+@@ -42,6 +42,7 @@
+ #include <limits>
+ #include <memory>
+ #include <set>
++#include <rak/algorithm.h>
+ #include <rak/error_number.h>
+ #include <rak/file_stat.h>
+ #include <rak/fs_stat.h>
 --- libtorrent-0.12.2.orig/src/torrent/data/file_utils.cc	2008-06-23 18:25:06.488832000 -0400
 +++ libtorrent-0.12.2/src/torrent/data/file_utils.cc	2008-06-23 18:25:31.066012126 -0400
 @@ -60,7 +60,7 @@
@@ -874,20 +794,21 @@
  
 --- libtorrent-0.12.2.orig/src/torrent/data/block.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/torrent/data/block.cc	2008-06-23 17:24:05.346918013 -0400
-@@ -202,7 +202,9 @@
- 
-   m_parent->inc_finished();
+@@ -38,6 +38,7 @@
  
--  if ((Block::size_type)std::count_if(m_parent->begin(), m_parent->end(), std::mem_fun_ref(&Block::is_finished)) < m_parent->finished())
-+  uint32_t finished = 0;
-+  std::count_if(m_parent->begin(), m_parent->end(), std::mem_fun_ref(&Block::is_finished), finished);
-+  if ((Block::size_type)finished < m_parent->finished())
-     throw internal_error("Block::completed(...) Finished blocks too large.");
+ #include <algorithm>
+ #include <functional>
++#include <rak/algorithm.h>
+ #include <rak/functional.h>
  
-   m_notStalled -= transfer->stall() == 0;
+ #include "peer/peer_info.h"
 --- libtorrent-0.12.2.orig/src/torrent/data/transfer_list.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/torrent/data/transfer_list.cc	2008-06-24 15:09:29.809436919 -0400
-@@ -42,6 +42,8 @@
+@@ -39,9 +39,12 @@
+ #include <algorithm>
+ #include <functional>
+ #include <set>
++#include <rak/algorithm.h>
  #include <rak/functional.h>
  
  #include "data/chunk.h"
@@ -896,28 +817,6 @@
  #include "peer/peer_info.h"
  
  #include "block_failed.h"
-@@ -116,7 +118,9 @@
- TransferList::hash_succeded(uint32_t index) {
-   iterator blockListItr = find(index);
- 
--  if ((Block::size_type)std::count_if((*blockListItr)->begin(), (*blockListItr)->end(), std::mem_fun_ref(&Block::is_finished)) != (*blockListItr)->size())
-+  uint32_t finished = 0;
-+  std::count_if((*blockListItr)->begin(), (*blockListItr)->end(), std::mem_fun_ref(&Block::is_finished), finished);
-+  if ((Block::size_type)finished != (*blockListItr)->size())
-     throw internal_error("TransferList::hash_succeded(...) Finished blocks does not match size.");
- 
-   if ((*blockListItr)->failed() != 0)
-@@ -143,7 +147,9 @@
-   if (blockListItr == end())
-     throw internal_error("TransferList::hash_failed(...) Could not find index.");
- 
--  if ((Block::size_type)std::count_if((*blockListItr)->begin(), (*blockListItr)->end(), std::mem_fun_ref(&Block::is_finished)) != (*blockListItr)->size())
-+  uint32_t finished = 0;
-+  std::count_if((*blockListItr)->begin(), (*blockListItr)->end(), std::mem_fun_ref(&Block::is_finished), finished);
-+  if ((Block::size_type)finished != (*blockListItr)->size())
-     throw internal_error("TransferList::hash_failed(...) Finished blocks does not match size.");
- 
-   // Could propably also check promoted against size of the block
 --- libtorrent-0.12.2.orig/src/torrent/poll_select.cc	2008-05-07 08:19:13.000000000 -0400
 +++ libtorrent-0.12.2/src/torrent/poll_select.cc	2008-06-23 19:06:09.911597997 -0400
 @@ -37,6 +37,7 @@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/rlibtorrent-05-tracker-usable.diff	Fri Jul 04 10:28:02 2008 +0000
@@ -0,0 +1,48 @@
+--- libtorrent-0.12.2.orig/src/torrent/tracker_list.cc	2008-07-01 22:21:49.641937000 -0400
++++ libtorrent-0.12.2/src/torrent/tracker_list.cc	2008-07-01 22:22:08.525804085 -0400
+@@ -66,14 +66,9 @@
+   return m_itr != end() && (*m_itr)->is_busy();
+ }
+ 
+-// Need a custom predicate because the is_usable function is virtual.
+-struct tracker_usable_t : public std::unary_function<TrackerList::value_type, bool> {
+-  bool operator () (const TrackerList::value_type& value) const { return value->is_usable(); }
+-};
+-
+ bool
+ TrackerList::has_usable() const {
+-  return std::find_if(begin(), end(), tracker_usable_t()) != end();
++  return find_usable(begin()) != end();
+ }
+ 
+ void
+@@ -90,6 +85,8 @@
+ 
+   set_state(s);
+   m_itr = find_usable(m_itr);
++  if (m_itr == end())
++    m_itr = find_usable(begin());
+ 
+   if (m_itr != end())
+     (*m_itr)->send_state(state());
+@@ -134,18 +131,12 @@
+ 
+ TrackerList::iterator
+ TrackerList::find_usable(iterator itr) {
+-  while (itr != end() && !tracker_usable_t()(*itr))
+-    ++itr;
+-
+-  return itr;
++  return std::find_if(itr, end(), std::mem_fun(&Tracker::is_usable));
+ }
+ 
+ TrackerList::const_iterator
+ TrackerList::find_usable(const_iterator itr) const {
+-  while (itr != end() && !tracker_usable_t()(*itr))
+-    ++itr;
+-
+-  return itr;
++  return std::find_if(itr, end(), std::mem_fun(&Tracker::is_usable));
+ }
+ 
+ TrackerList::iterator
--- a/patches/rtorrent-01-solaris.diff	Thu Jul 03 10:51:57 2008 +0000
+++ b/patches/rtorrent-01-solaris.diff	Fri Jul 04 10:28:02 2008 +0000
@@ -101,3 +101,31 @@
    curl_easy_setopt(m_handle, CURLOPT_ENCODING,       "");
  
    m_stack->add_get(this);
+--- rtorrent-0.8.2.orig/src/main.cc	2008-07-01 16:49:14.445080000 -0400
++++ rtorrent-0.8.2/src/main.cc	2008-07-02 10:37:19.052279890 -0400
+@@ -44,7 +44,13 @@
+ #include <torrent/torrent.h>
+ #include <torrent/exceptions.h>
+ #include <rak/functional.h>
++#include <locale.h>
+ 
++#if defined(__sun) && defined(__SVR4)
++#include <stdio.h>
++#include <stdio_ext.h>
++#endif
++
+ #ifdef USE_EXECINFO
+ #include <execinfo.h>
+ #endif
+@@ -165,6 +170,11 @@
+     SignalHandler::set_handler(SIGSEGV,  sigc::bind(sigc::ptr_fun(&do_panic), SIGSEGV));
+     SignalHandler::set_handler(SIGBUS,   sigc::bind(sigc::ptr_fun(&do_panic), SIGBUS));
+     SignalHandler::set_handler(SIGFPE,   sigc::bind(sigc::ptr_fun(&do_panic), SIGFPE));
++    SignalHandler::set_handler(SIGABRT,   sigc::bind(sigc::ptr_fun(&do_panic), SIGABRT));
++
++#if defined(__sun) && defined(__SVR4)
++    enable_extended_FILE_stdio(-1, SIGABRT);
++#endif
+ 
+     control->core()->initialize_first();
+ 
--- a/patches/rtorrent-03-curl-event.diff	Thu Jul 03 10:51:57 2008 +0000
+++ b/patches/rtorrent-03-curl-event.diff	Fri Jul 04 10:28:02 2008 +0000
@@ -254,7 +254,7 @@
        // Done with some handles.
 -      int t;
 -      CURLMsg* msg;
-+      this->process();
++      process();
 +    }
  
 -      while ((msg = curl_multi_info_read((CURLM*)m_handle, &t)) != NULL) {
@@ -285,7 +285,7 @@
 +
 +    if ((unsigned int)count != size()) {
 +      // Done with some handles.
-+      this->process();
++      process();
      }
  
    } while (code == CURLM_CALL_MULTI_PERFORM);
@@ -379,16 +379,6 @@
  
    // Yes, below is how much code really *should* have been in this
    // function. ;)
-@@ -108,6 +110,9 @@
-   if (static_cast<torrent::PollEPoll*>(m_poll)->poll((timeout.usec() + 999) / 1000) == -1)
-     return check_error();
- 
-+  if (!m_httpStack->empty())
-+    m_httpStack->perform();
-+ 
-   torrent::perform();
-   static_cast<torrent::PollEPoll*>(m_poll)->perform();
- }
 diff -urN rtorrent-0.8.2.orig/src/core/poll_manager_kqueue.cc rtorrent-0.8.2/src/core/poll_manager_kqueue.cc
 --- rtorrent-0.8.2.orig/src/core/poll_manager_kqueue.cc	2008-05-07 08:19:11.000000000 -0400
 +++ rtorrent-0.8.2/src/core/poll_manager_kqueue.cc	2008-06-10 14:17:31.672907000 -0400
@@ -408,16 +398,6 @@
  
    // Yes, below is how much code really *should* have been in this
    // function. ;)
-@@ -109,6 +111,9 @@
-   if (static_cast<torrent::PollKQueue*>(m_poll)->poll((timeout.usec() + 999) / 1000) == -1)
-     return check_error();
- 
-+  if (!m_httpStack->empty())
-+    m_httpStack->perform();
-+ 
-   torrent::perform();
-   static_cast<torrent::PollKQueue*>(m_poll)->perform();
- }
 diff -urN rtorrent-0.8.2.orig/src/core/poll_manager_ports.cc rtorrent-0.8.2/src/core/poll_manager_ports.cc
 --- rtorrent-0.8.2.orig/src/core/poll_manager_ports.cc	2008-06-10 15:13:49.790288665 -0400
 +++ rtorrent-0.8.2/src/core/poll_manager_ports.cc	2008-06-10 14:31:09.552278000 -0400
@@ -437,16 +417,6 @@
  
    // Yes, below is how much code really *should* have been in this
    // function. ;)
-@@ -111,6 +113,9 @@
- 	  std::cerr << "error from ports poll\n";
-     return check_error();
-   }
-+  if (!m_httpStack->empty())
-+    m_httpStack->perform();
-+ 
-   torrent::perform();
-   static_cast<torrent::PollPorts*>(m_poll)->perform();
- }
 diff -urN rtorrent-0.8.2.orig/src/core/poll_manager_select.cc rtorrent-0.8.2/src/core/poll_manager_select.cc
 --- rtorrent-0.8.2.orig/src/core/poll_manager_select.cc	2008-05-07 08:19:11.000000000 -0400
 +++ rtorrent-0.8.2/src/core/poll_manager_select.cc	2008-06-10 02:37:17.419878000 -0400
--- a/patches/rtorrent-04-sunpro.diff	Thu Jul 03 10:51:57 2008 +0000
+++ b/patches/rtorrent-04-sunpro.diff	Fri Jul 04 10:28:02 2008 +0000
@@ -80,7 +80,7 @@
  
 --- rtorrent-0.8.2.orig/rak/algorithm.h	2008-05-07 08:19:12.000000000 -0400
 +++ rtorrent-0.8.2/rak/algorithm.h	2008-06-25 17:27:39.728352000 -0400
-@@ -40,6 +40,45 @@
+@@ -40,6 +40,63 @@
  #include <algorithm>
  #include <functional>
  
@@ -120,22 +120,30 @@
 +               iterator_traits<ForwardIterator>::iterator_category());
 +    return n;
 +  }
++
++  template <class InputIterator, class T>
++  inline typename iterator_traits<InputIterator>::difference_type
++  count (InputIterator first, InputIterator last, const T& value)
++  {
++    typename iterator_traits<InputIterator>::difference_type n = 0;
++    count(first, last, value, n);
++    return n;
++  }
++
++  template <class InputIterator, class Predicate>
++  inline typename iterator_traits<InputIterator>::difference_type
++  count_if (InputIterator first, InputIterator last, Predicate pred)
++  {
++    typename iterator_traits<InputIterator>::difference_type n = 0;
++    count_if(first, last, pred, n);
++    return n;
++  }
 +}
 +#endif
 +
  namespace rak {
  
  template <typename _InputIter, typename _Function>
---- rtorrent-0.8.2.orig/src/main.cc	2008-05-07 08:19:11.000000000 -0400
-+++ rtorrent-0.8.2/src/main.cc	2008-06-25 18:08:56.717232910 -0400
-@@ -44,6 +44,7 @@
- #include <torrent/torrent.h>
- #include <torrent/exceptions.h>
- #include <rak/functional.h>
-+#include <locale.h>
- 
- #ifdef USE_EXECINFO
- #include <execinfo.h>
 --- rtorrent-0.8.2.orig/src/command_file.cc	2008-05-07 08:19:11.000000000 -0400
 +++ rtorrent-0.8.2/src/command_file.cc	2008-06-25 18:06:51.985365949 -0400
 @@ -64,7 +64,7 @@
@@ -246,6 +254,14 @@
  
 --- rtorrent-0.8.2.orig/src/display/text_element_string.cc	2008-05-07 08:19:11.000000000 -0400
 +++ rtorrent-0.8.2/src/display/text_element_string.cc	2008-06-25 02:57:08.521853302 -0400
+@@ -36,6 +36,7 @@
+ 
+ #include "config.h"
+ 
++#include <rak/algorithm.h>
+ #include <rak/string_manip.h>
+ 
+ #include "rpc/parse_commands.h"
 @@ -52,17 +52,21 @@
      return first;
  
@@ -270,17 +286,6 @@
    } else {
      first = copy_string(first, last, target);
    }  
-@@ -112,7 +116,9 @@
-       first = rak::copy_escape_html(str.c_str(), str.c_str() + str.size(), first, last);
- 
-     } else {
--      size_t length = std::min<size_t>(str.size(), std::distance(first, last));
-+      size_t length = 0;
-+      std::distance(first, last, length);
-+      length = std::min<size_t>(str.size(), length);
- 
-       std::memcpy(first, str.c_str(), length);
-       first += std::min<size_t>(str.size(), length);
 --- rtorrent-0.8.2.orig/src/display/window.h	2008-05-07 08:19:11.000000000 -0400
 +++ rtorrent-0.8.2/src/display/window.h	2008-06-26 00:42:49.975992333 -0400
 @@ -41,6 +41,7 @@
@@ -351,17 +356,14 @@
  int
 --- rtorrent-0.8.2.orig/src/display/window_log.cc	2008-05-07 08:19:11.000000000 -0400
 +++ rtorrent-0.8.2/src/display/window_log.cc	2008-06-25 03:13:37.195603865 -0400
-@@ -86,7 +86,9 @@
-     return;
+@@ -37,6 +37,7 @@
+ #include "config.h"
  
-   iterator itr = find_older();
--  extent_type height = std::min(std::distance(m_log->begin(), itr), (std::iterator_traits<iterator>::difference_type)10);
-+  extent_type height = 0;
-+  std::distance(m_log->begin(), itr, height);
-+  height = std::min(height, (extent_type)10);
+ #include <ctime>
++#include <rak/algorithm.h>
  
-   if (height != m_maxHeight) {
-     m_minHeight = height != 0 ? 1 : 0;
+ #include "canvas.h"
+ #include "utils.h"
 --- rtorrent-0.8.2.orig/src/display/frame.cc	2008-05-07 08:19:11.000000000 -0400
 +++ rtorrent-0.8.2/src/display/frame.cc	2008-06-25 02:51:41.636803977 -0400
 @@ -41,6 +41,8 @@
@@ -515,18 +517,7 @@
      bounds_type bounds = (*itr)->preferred_size();
      
      if ((*itr)->is_height_dynamic()) {
-@@ -372,7 +374,9 @@
-     retry = false;
- 
-     for (dynamic_type *itr = dynamicFrames, *last = dynamicFrames + dynamicSize; itr != last; ++itr) {
--      uint32_t adjust = (std::max(remaining, 0) + std::distance(itr, last) - 1) / std::distance(itr, last);
-+      uint32_t n = 0;
-+      std::distance(itr, last, n);
-+      uint32_t adjust = (std::max(remaining, 0) + n - 1) / n;
-     
-       adjust += itr->first->m_height;
-       adjust = std::max(adjust, itr->second.minHeight);
-@@ -391,7 +395,7 @@
+@@ -391,7 +393,7 @@
    // the frame is too small, it will set the remaining windows to zero
    // extent which will flag them as offscreen.
  
@@ -535,7 +526,7 @@
      // If there is any remaining space, check if we want to shift
      // the subsequent frames to the other side of this frame.
      if (remaining > 0 && (*itr)->has_bottom_frame()) {
-@@ -417,7 +421,7 @@
+@@ -417,7 +419,7 @@
  
    int remaining = width;
    
@@ -544,18 +535,7 @@
      bounds_type bounds = (*itr)->preferred_size();
      
      if ((*itr)->is_width_dynamic()) {
-@@ -446,7 +450,9 @@
-     retry = false;
- 
-     for (dynamic_type *itr = dynamicFrames, *last = dynamicFrames + dynamicSize; itr != last; ++itr) {
--      uint32_t adjust = (std::max(remaining, 0) + std::distance(itr, last) - 1) / std::distance(itr, last);
-+      uint32_t n = 0;
-+      std::distance(itr, last, n);
-+      uint32_t adjust = (std::max(remaining, 0) + n - 1) / n;
-     
-       adjust += itr->first->m_width;
-       adjust = std::max(adjust, itr->second.minWidth);
-@@ -465,7 +471,7 @@
+@@ -465,7 +469,7 @@
    // the frame is too small, it will set the remaining windows to zero
    // extent which will flag them as offscreen.
  
@@ -586,33 +566,24 @@
  }
 --- rtorrent-0.8.2.orig/src/core/scheduler.cc	2008-05-07 08:19:11.000000000 -0400
 +++ rtorrent-0.8.2/src/core/scheduler.cc	2008-06-25 02:19:20.043037414 -0400
-@@ -66,7 +66,9 @@
+@@ -37,6 +37,7 @@
+ #include "config.h"
  
- Scheduler::size_type
- Scheduler::active() const {
--  return std::count_if(m_view->begin_visible(), m_view->end_visible(), std::mem_fun(&Download::is_active));
-+  uint32_t n = 0;
-+  std::count_if(m_view->begin_visible(), m_view->end_visible(), std::mem_fun(&Download::is_active), n);
-+  return n;
- }
+ #include <algorithm>
++#include <rak/algorithm.h>
+ #include <rak/functional.h>
+ #include <torrent/exceptions.h>
  
- void
 --- rtorrent-0.8.2.orig/src/core/view.cc	2008-05-07 08:19:11.000000000 -0400
 +++ rtorrent-0.8.2/src/core/view.cc	2008-06-25 02:28:36.651635274 -0400
-@@ -230,9 +230,11 @@
-   iterator splitFiltered = std::stable_partition(begin_filtered(), end_filtered(), view_downloads_filter(m_filter));
+@@ -38,6 +38,7 @@
  
-   base_type changed(splitVisible, splitFiltered);
--  iterator splitChanged = changed.begin() + std::distance(splitVisible, end_visible());
-+  uint32_t visible = 0;
-+  std::distance(splitVisible, end_visible(), visible);
-+  iterator splitChanged = changed.begin() + visible;
-   
--  m_size = std::distance(begin(), std::copy(splitChanged, changed.end(), splitVisible));
-+  std::distance(begin(), std::copy(splitChanged, changed.end(), splitVisible), m_size);
-   std::copy(changed.begin(), splitChanged, begin_filtered());
- 
-   // Fix this...
+ #include <algorithm>
+ #include <functional>
++#include <rak/algorithm.h>
+ #include <rak/functional.h>
+ #include <rak/functional_fun.h>
+ #include <rpc/parse_commands.h>
 --- rtorrent-0.8.2.orig/src/core/manager.cc	2008-06-25 01:44:38.134154000 -0400
 +++ rtorrent-0.8.2/src/core/manager.cc	2008-06-25 02:08:43.144712661 -0400
 @@ -352,19 +352,25 @@
@@ -647,31 +618,14 @@
      ai->address()->set_port(port);
 --- rtorrent-0.8.2.orig/src/rpc/parse.cc	2008-05-07 08:19:10.000000000 -0400
 +++ rtorrent-0.8.2/src/rpc/parse.cc	2008-06-25 17:30:55.775246860 -0400
-@@ -363,7 +363,9 @@
-       if (first == last)
-         return first;
- 
--      size_t n = std::min<size_t>(str.size(), std::distance(first, last) - 1);
-+      size_t n = 0;
-+      std::distance(first, last, n);
-+      n = std::min<size_t>(str.size(), n - 1);
+@@ -37,6 +37,7 @@
+ #include "config.h"
  
-       std::memcpy(first, str.c_str(), n);
-       *(first += n) = '\0';
-@@ -373,8 +375,11 @@
-   }
+ #include <locale>
++#include <rak/algorithm.h>
+ #include <rak/path.h>
+ #include <torrent/exceptions.h>
  
-   case torrent::Object::TYPE_VALUE:
--    return std::min(first + snprintf(first, std::distance(first, last), "%lli", src->as_value()), last);
--
-+  {
-+    size_t n = 0;
-+    std::distance(first, last, n);
-+    return std::min(first + snprintf(first, n, "%lli", src->as_value()), last);
-+  }
-   case torrent::Object::TYPE_LIST:
-     for (torrent::Object::list_const_iterator itr = src->as_list().begin(), itrEnd = src->as_list().end(); itr != itrEnd; itr++) {
-       first = print_object(first, last, &*itr, flags);
 --- rtorrent-0.8.2.orig/src/rpc/xmlrpc.cc	2008-05-07 08:19:10.000000000 -0400
 +++ rtorrent-0.8.2/src/rpc/xmlrpc.cc	2008-06-25 17:54:04.404987582 -0400
 @@ -477,7 +477,8 @@