]> git.pld-linux.org Git - packages/ctorrent.git/commitdiff
- 'Enhanced CTorrent' patchset for ctorrent
authorJacek Konieczny <jajcus@pld-linux.org>
Fri, 10 Mar 2006 16:41:50 +0000 (16:41 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    ctorrent.spec -> 1.12
    patchset-ctorrent-1.3.4-dnh2.diff -> 1.1

ctorrent.spec
patchset-ctorrent-1.3.4-dnh2.diff [new file with mode: 0644]

index 75cd8816ff25b5e893612b130242679796bf4719..1e03f9853b9f7946ea16bb64c0026a75cf402ea1 100644 (file)
@@ -1,13 +1,17 @@
 Summary:       BitTorrent client written in the C++
 Summary(pl):   Klient BitTorrenta napisany w C++
 Name:          ctorrent
-Version:       1.3.4
-Release:       1
+%define        _base_version 1.3.4
+%define        _dnh_version dnh2
+Version:       %{_base_version}_%{_dnh_version}
+Release:       0.1
 License:       GPL
 Group:         Applications/Networking
-Source0:       http://dl.sourceforge.net/ctorrent/%{name}-%{version}.tar.bz2
+Source0:       http://dl.sourceforge.net/ctorrent/%{name}-%{_base_version}.tar.bz2
 # Source0-md5: 823010ec78215d476537c9eba9381cdd
-URL:           http://ctorrent.sourceforge.net/
+Patch0:                http://www.rahul.net/dholmes/ctorrent/patchset-ctorrent-%{_base_version}-%{_dnh_version}.diff
+#URL:          http://ctorrent.sourceforge.net/
+URL:           http://www.rahul.net/dholmes/ctorrent/
 BuildRequires: libstdc++-devel
 BuildRequires: openssl-devel >= 0.9.7d
 BuildRoot:     %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
@@ -31,7 +35,8 @@ CTorrent pomaga dok
 u¿ywa siê sieci BitTorrent.
 
 %prep
-%setup -q
+%setup -q -n %{name}-%{_base_version}
+%patch0 -p0
 
 %build
 %configure
diff --git a/patchset-ctorrent-1.3.4-dnh2.diff b/patchset-ctorrent-1.3.4-dnh2.diff
new file mode 100644 (file)
index 0000000..ffcd7f7
--- /dev/null
@@ -0,0 +1,11985 @@
+--- README-DNH.TXT.orig        Sat Jan 14 23:37:29 2006
++++ README-DNH.TXT     Sun Jan 15 00:11:23 2006
+@@ -0,0 +1,239 @@
++
++                             Enhanced CTorrent
++
++       [ [1]Overview | [2]News | [3]Changes | [4]CTCS | [5]Download |
++                        [6]Resources | [7]Contact ] 
++     _________________________________________________________________
++
++   Overview
++
++   [8]CTorrent is a [9]BitTorrent client implemented in C++ to be
++   lightweight and quick. It has fallen a little behind in updates and
++   bug fixes though.
++
++   The files here contain the good work of those who wrote the original
++   CTorrent base code and a number of patches that provide fixes and
++   enhancements, as well as additional fixes and enhancements that I am
++   contributing. I am not the original author, current maintainer, or any
++   other official representative of CTorrent. The files on this page are
++   not the original or official CTorrent distribution. I encourage you to
++   visit the [10]CTorrent project page on SourceForge for further
++   information.
++
++  Features
++
++   The purpose of the Enhanced CTorrent effort is to fix problems that
++   remain in the code, modernize existing features and algorithms, and
++   implement new features while maintaining low overhead requirements and
++   a high standard of performance (both part of the original CTorrent
++   design philosophy). Highlights of the enhanced client include:
++     * Support for large files (>2GB) and large torrents (>255 files)
++     * Strategic selection of pieces to request for download
++     * Continuous queueing of download requests, tuned based on latency
++       and throughput for each peer
++     * Improved download performance, including parallel requests in
++       initial and endgame modes
++     * Improved bandwidth regulation
++     * Improved compatibility with other peers
++     * Performance optimization and bug fixes
++     * An interface for monitoring and managing multiple clients
++
++  Status Line
++
++   The status line that is output by the client has changed since the
++   original and deserves some explanation.
++
++       / 0/33/110 [672/672/672] 0MB,1130MB | 0,20K/s | 0,0K E:0,31
++       - - -- ---  --- --- ---  --- ------   - --      - -    - --
++       A B  C  D    E   F   G    H     I     J  K      L M    N  O
++
++   A: Ticker; this character changes to indicate that the client is
++   running.
++   B: Number of seeders (complete peers) to which you are connected.
++   C: Number of leechers (incomplete peers) to which you are connected.
++   D: Total number of peers in the swarm, as last reported by the
++   tracker.
++   E: Number of pieces of the torrent that you have completed.
++   F: Number of pieces currently available from you and your connected
++   peers.
++   G: Total number of pieces in the torrent.
++   H: Total amount of data you have downloaded.
++   I: Total amount of data you have uploaded.
++   J: Your current total download rate.
++   K: Your current total upload rate.
++   L: Amount of data downloaded since the last status line update.
++   M: Amount of data uploaded since the last status line update.
++   N: Number of tracker connection errors.
++   O: Number of successful tracker connections.
++
++  Peer ID
++
++   Beginning with dnh1.1 the default peer ID has been changed for
++   convenience, as some other clients and trackers assume that Ctorrent
++   is "buggy" and won't cooperate with it. [Guess what, there are plenty
++   of others with bugs too.] The -P option is still available if you wish
++   to use a different peer ID, but it is no longer necessary to do so in
++   order to avoid this "ban".
++
++   The new default peer ID prefix is "-CDversion-", where version is an
++   indication of the version number (0101 for dnh1.1).
++
++  CTCS
++
++   [11]CTorrent Control Server (CTCS) is an interface for monitoring and
++   managing Enhanced CTorrent clients. It can manage allocation of
++   bandwidth, provide status information, and allow changes to the
++   running configuration of each client. Support for this interface was
++   added in the dnh2 release.
++     _________________________________________________________________
++
++   News
++
++   2006-01-15
++          Version dnh2 is released! This version includes a number of
++          significant [12]changes, including large file support, piece
++          selection, tuned request queue depth, and support for
++          [13]CTorrent Control Server.
++     _________________________________________________________________
++
++   Changes
++
++   For a list of changes in the current and previous versions, see the
++   [14]ChangeLog file.
++     _________________________________________________________________
++
++   Download
++
++   Release dnh2
++   The patch files for this version are significantly larger
++   than in previous releases. It will be faster and easier to just
++   download the patched source distribution below.
++
++   [15]dnh1.2 to dnh2 patch file
++   A patch file of changes to release dnh1.2 to bring it up to dnh2.
++
++   [16]Patch file
++   A patch file of changes to the CTorrent 1.3.4 base.
++
++   [17]Patched source
++   A complete source distribution for all platforms.
++                    ___________________________________
++
++   Release dnh1.2
++   Note: If you get a message about needing to install OpenSSL, you might
++   want to try the FreeBSD patch/version even if you are not using
++   FreeBSD.
++
++   [18]dnh1.1 to dnh1.2 patch file
++   A patch file of changes to release dnh1.1 to bring it up to dnh1.2.
++
++   [19]FreeBSD patch file
++   A patch file of changes to the CTorrent 1.3.4 base, including the
++   patches from the FreeBSD ports tree.
++
++   [20]Patch file
++   A patch file of changes to the CTorrent 1.3.4 base.
++
++   [21]FreeBSD patched source
++   This includes the patches from the FreeBSD ports tree.
++
++   [22]Linux/Windows/Other patched source
++   Please [23]let me know if you encounter any portability issues, as I
++   don't have a test environment set up for these platforms.
++                    ___________________________________
++
++   Bitfield::Invert patch
++
++   [24]Bitfield::Invert patch
++   See notes in the change log; this is needed if you are using dnh1.1,
++   dnh1, or ctorrent-1.3.4.
++                    ___________________________________
++
++   Release dnh1.1
++
++   [25]dnh1 to dnh1.1 patch file
++   A patch file of changes to release dnh1 to bring it up to dnh1.1.
++                    ___________________________________
++
++   Release dnh1
++
++   [26]FreeBSD patch file
++   A patch file of changes to the CTorrent 1.3.4 base, including the
++   patches from the FreeBSD ports tree.
++   Note: Thanks to Florent Thoumie, as of 29 Jul 2005 this patchset is
++   included in the FreeBSD port. If you update your ports tree (or at
++   least net/ctorrent) and install from there, you will have these
++   updates without downloading the file and patching manually.
++
++   [27]Patch file
++   A patch file of changes to the CTorrent 1.3.4 base.
++
++   [28]FreeBSD patched source
++   This includes the patches from the FreeBSD ports tree.
++
++   [29]Linux/Windows/Other patched source
++   Please [30]let me know if you encounter any portability issues, as I
++   don't have a test environment set up for these platforms.
++     _________________________________________________________________
++
++   Resources
++
++   [31]CTorrent Home Page 
++   Outdated, but you may find some useful info (particularly the FAQ).
++
++   [32]CTorrent SourceForge Project 
++   Hosts the CTorrent codebase, bug reports, patches, and forum.
++
++   [33]Custom CTorrent 
++   A page by the author of the "get1file" patch and other fixes. It
++   contains a custom version and a GUI for CTorrent.
++
++   [34]BitTorrent 
++   The official BitTorrent home page.
++
++   [35]BitTorrent wiki 
++   Various documentation.
++
++   [36]BitTorrent protocol specification (official version)
++
++   [37]BitTorrent protocol specification (wiki version)
++
++References
++
++   1. http://www.rahul.net/dholmes/ctorrent/index.html#info
++   2. http://www.rahul.net/dholmes/ctorrent/index.html#news
++   3. http://www.rahul.net/dholmes/ctorrent/changelog.html
++   4. http://www.rahul.net/dholmes/ctorrent/ctcs.html
++   5. http://www.rahul.net/dholmes/ctorrent/index.html#download
++   6. http://www.rahul.net/dholmes/ctorrent/index.html#resources
++   7. mailto:dholmes@ct.boxmail.com
++   8. http://ctorrent.sourceforge.net/
++   9. http://www.bittorrent.com/
++  10. http://sourceforge.net/projects/ctorrent/
++  11. http://www.rahul.net/dholmes/ctorrent/ctcs.html
++  12. http://www.rahul.net/dholmes/ctorrent/changelog.html
++  13. http://www.rahul.net/dholmes/ctorrent/ctcs.html
++  14. http://www.rahul.net/dholmes/ctorrent/changelog.html
++  15. http://www.rahul.net/dholmes/ctorrent/patchset-ctorrent-dnh1.2-dnh2.diff
++  16. http://www.rahul.net/dholmes/ctorrent/patchset-ctorrent-1.3.4-dnh2.diff
++  17. http://www.rahul.net/dholmes/ctorrent/ctorrent-1.3.4-dnh2.tar.gz
++  18. http://www.rahul.net/dholmes/ctorrent/patchset-ctorrent-dnh1.1-dnh1.2.diff
++  19. http://www.rahul.net/dholmes/ctorrent/patchset-ctorrent-1.3.4-dnh1.2-fbsd.diff
++  20. http://www.rahul.net/dholmes/ctorrent/patchset-ctorrent-1.3.4-dnh1.2.diff
++  21. http://www.rahul.net/dholmes/ctorrent/ctorrent-1.3.4-dnh1.2-fbsd.tar.gz
++  22. http://www.rahul.net/dholmes/ctorrent/ctorrent-1.3.4-dnh1.2.tar.gz
++  23. mailto:dholmes@ct.boxmail.com
++  24. http://www.rahul.net/dholmes/ctorrent/patch-invert.diff
++  25. http://www.rahul.net/dholmes/ctorrent/patchset-ctorrent-dnh1-dnh1.1.diff
++  26. http://www.rahul.net/dholmes/ctorrent/patchset-ctorrent-1.3.4-dnh1-fbsd.diff
++  27. http://www.rahul.net/dholmes/ctorrent/patchset-ctorrent-1.3.4-dnh1.diff
++  28. http://www.rahul.net/dholmes/ctorrent/ctorrent-1.3.4-dnh1-fbsd.tar.gz
++  29. http://www.rahul.net/dholmes/ctorrent/ctorrent-1.3.4-dnh1.tar.gz
++  30. mailto:dholmes@ct.boxmail.com
++  31. http://ctorrent.sourceforge.net/
++  32. http://sourceforge.net/projects/ctorrent/
++  33. http://customctorrent.ifreepages.com/
++  34. http://bittorrent.com/
++  35. http://wiki.theory.org/CategoryBitTorrent
++  36. http://www.bittorrent.com/protocol.html
++  37. http://wiki.theory.org/BitTorrentSpecification
+--- ChangeLog.orig     Wed Sep  8 16:10:51 2004
++++ ChangeLog  Sat Jan 14 23:22:57 2006
+@@ -1 +1,379 @@
+-*EMPTY*
++
++                        Enhanced CTorrent Change Log
++     _________________________________________________________________
++
++   Changes for "dnh2" Release
++
++   Patches
++     * The following patches or their functionality are incorporated:
++       1380164 [dnh1.2]
++       1357832 [invert] (included in dnh1.2)
++       1352866 [dnh1.1]
++       1266767 [passkey2]
++       1239547 [dnh1]
++       1170457 [standalone-sha1] Added as a fallback case in configure if
++       OpenSSL is not found. To force it to be used, define
++       USE_STANDALONE_SHA1 in config.h (after running configure).
++       1164454 [ip]
++       1119610 [vfat] This bug appears to be linux-specific; I've tried
++       to handle it in a more general way that may apply to similar
++       situations on other platforms and filesystems, but I have limited
++       capability to test this.
++       1067196 [lfs] This is the large-file support that many have asked
++       for.
++
++   Optimization
++     * Use fewer call to random() by shifting the previously unused bits.
++     * Time() calls have been greatly reduced; a global timestamp
++       variable "now" is set once per main loop interation and referenced
++       in functions that need a timestamp (except the caching I/O
++       routines which were left alone).
++     * Overall current bandwidth rates are now computed only once per
++       main loop and referenced in any routines that evaluate or control
++       bandwidth.
++     * Avoid flushing peer output buffers except in SendModule. This
++       allows for some consolidation of messages to reduce network
++       overhead.
++
++   Code Fixes
++     * Fixed use of cfg_req_queue_length to be the actual queue size
++       (queue was half of this value).
++     * Fixed: "peer is" verbose output could fubar the terminal.
++     * Formatting: Replaced indentation tabs with spaces for consistency.
++
++   Operational Enhancements
++     * Improved piece selection methods to include rarity as a factor.
++       This is not strictly "rarest-first", as we do not make a
++       comprehensive effort to find the "rarest" piece or rank pieces by
++       rarity. Rather, we use a more efficient compromise and try to find
++       the set of pieces that have "trade value" (another peer needs
++       them) and make a random choice from that set. Here is the current
++       preference order used in each mode:
++       Trade Value is defined as:
++         1. Piece that only this peer has (not considering other
++            seeders), that a peer in which we're interested needs.
++         2. Piece that not every peer in which we're interested has.
++         3. Piece that only this peer has (not considering other
++            seeders).
++         4. Piece that not every peer has.
++       Normal Mode
++         1. Piece we tried to get from another peer but stopped due to
++            choking or lost connection. (We have part of the piece
++            already.)
++         2. Piece most recently acquired by the peer (possibly/probably
++            rare).
++         3. Piece with trade value.
++         4. Any piece not yet requested.
++       Initial-piece Mode
++         1. Piece with trade value which is already in progress.
++         2. Piece with trade value that more than one peer has.
++         3. Piece with trade value.
++         4. Any piece not yet requested.
++       Endgame Mode
++         1. Piece with trade value which is already in progress, of which
++            we have the least amount.
++         2. Piece already in progress of which we have the least amount.
++     * Advanced request queueing system.
++          + Instead of requesting all of the slices for a piece at one
++            time, we now measure latency to the peer and send requests
++            based on how long it takes the data to arrive. This avoids
++            wasting upload banwidth by having too many outstanding
++            requests: If we get choked or lose the connection, the extra
++            requests were wasted; in initial or endgame modes, more
++            requests would have to be cancelled when we completed the
++            piece.
++          + A new piece will be queued for download when there is space
++            in the queue and we've requested the slices that have been
++            queued already. We also don't wait for the current piece to
++            complete before sending requests for a new piece. This helps
++            to maintain a continuous flow of data in the download
++            pipeline.
++          + When duplicating a request in initial or endgame mode, slices
++            that have already been requested are queued last.
++     * Don't send HAVE messages to seeders (to save UL bandwidth).
++          + Since we maintain interested state, and know the peer is a
++            seeder, we'll do the right thing when we become a seeder.
++          + Not sending HAVE to all peers (leechers) that already have
++            the piece is a bad idea IMO. If everyone takes the same
++            attitude, none of us will know when another becomes a seeder
++            and connections will remain open/occupied.
++          + We do send a HAVE to seeders upon completing our first piece
++            so that we don't continue to appear empty.
++     * Endgame strategy is used in get1file mode to complete the file.
++     * Queue management:
++          + Don't accept requests from choked peers.
++          + Discard peer's reponse_q when we choke them.
++          + Don't send cancels when we get choked (according to spec &
++            discussions).
++          + Don't put full piece queues in pending.
++          + Move closing peer's request queue to pending instead of
++            discarding it.
++     * Prefer uploading to or downloading from a peer after we skip them
++       due to bandwidth limiting. This is done via the g_next_up and
++       g_defer_up global variables in peer.cpp (for UL; s/up/dn for the
++       DL versions). The peerlist Sort() function and peer "click"
++       variables have been removed since they are not needed with this
++       feature.
++
++   Options & Features
++     * The -c option now reports file completion status.
++          + As a side effect the metainfo details are printed twice. This
++            allows you to view the torrent contents while pieces are
++            being verified.
++          + Total percentage completion is also added to the output.
++     * "-E" option to seed to a specified UL:DL ratio. Seeding will stop
++       when this ratio or the timeout (-e) is reached. If CTorrent starts
++       as a seeder, the ratio is interpreted as UL:[torrent size].
++     * If "-e 0" is specified (explicitly) and -E is used, there will be
++       no timeout; seeding will continue until the ratio is reached.
++     * The "-m" option previously didn't do anything, and it isn't clear
++       what it was originally going to do. Now the default value is 1,
++       and CTorrent will try to maintain at least this many peers by
++       contacting the tracker early if the peer count falls below this
++       value. This feature was present in release dnh1 but the value was
++       not changeable.
++       Actually it seems likely that this was to be number of peers that
++       the client would try to obtain (by initiating connections), as the
++       "official" client does; this is mentioned as a note in the online
++       specification. I don't really see the value in that though. That
++       said, the option as implemented here should rarely be used. It
++       might be useful only with torrents that have significantly more
++       than max_peers total peers and use a long tracker update interval
++       (such that you tend to drop a lot of peers betwen updates).
++     * "-z" option to set the slice size (the unit of a request, i.e. the
++       discrete amount of data that will be requested from a peer at one
++       time). The slice size now defaults to 16K regardless of the piece
++       length. Request queue size is computed and set based on the slice
++       size, as it now affects only system resources (though not a lot)
++       and not the way that requests are sent.
++     * Add support for "key" and "trackerid" tracker interaction
++       parameters.
++     * Support/display tracker warning message
++     * Now able to handle torrents with more than 255 files.
++     * Support for [1]CTorrent Control Server, an application and
++       protocol for monitoring and managing multiple Enhanced CTorrent
++       clients. The "-S" option is used to connect to CTCS, as in "-S
++       localhost:2780" if CTCS is listening at port 2780 on the local
++       system. Appending a colon ("-S localhost:2780:") will prompt for a
++       password to authenticate with CTCS.
++
++   Peer Handling
++     * Count immediate choke-unchoke (either order) as an error (two
++       errors actually, since it's so wasteful).
++       It may be that some clients do this to stimulate the peer when
++       they think it hasn't responded to their last unchoke (due to high
++       latency). It would be better for them to just repeat the unchoke
++       rather than choke-unchoke, as by choking they will cause the peer
++       to send the requests again.
++     * Detect unresponsive peer connections and try to fix them or
++       disconnect them. Basically, if a peer doesn't respond to our
++       request in a reasonable time then we first assume that our request
++       was lost in transmission; if it happens again then we assume the
++       connection is unreliable.
++     * Handle peers that suppress HAVE messages so we don't always think
++       that they're empty (and thus give them preferential treatment for
++       uploading). If we've sent the peer an amount of data equivalent to
++       two pieces, assume that they now have at least one complete piece.
++     _________________________________________________________________
++
++   Changes for "dnh1.2" Release
++
++   These are just corrections to the previous release that I felt were
++   necessary. Much more improvement is coming in the dnh2 release.
++
++   Bug/code fixes
++     * Bitfield::Invert patch [1357832 on sourceforge] described below.
++     * Fixed "piece length too long" check to reflect the actual queue
++       length used.
++     * Accept 128K slice size for peer requests.
++     * "Return" keyword in Random_init() removed due to potential compile
++       error.
++     * Modified longer-wait test in the optimistic unchoke routine to
++       consider whether the peer is currently choked.
++     _________________________________________________________________
++
++   Bitfield::Invert bug
++
++   There is a bug in the Bitfield::Invert() function that affects the
++   ctorrent-1.3.4 base code as well as releases dnh1 and dnh1.1. This can
++   cause the application to fail (segmentation fault) or may affect
++   downloading of all pieces of the torrent. A patch is available in the
++   Download secion.
++     _________________________________________________________________
++
++   Changes for "dnh1.1" Release
++
++   These are just corrections to the previous release that I felt were
++   necessary. Much more improvement is coming in the next release.
++
++   Bug/code fixes
++     * Peer count would increase on each tracker update if there were no
++       seeders.
++     * RequestQueue::CopyShuffle() changed to use a pointer argument.
++     * Fixed some incorrectness in PendingQueue::Delete() and
++       PendingQueue::DeleteSlice() which could cause a memory leak.
++     * Fixed random-chance inversion bug in PeerList::UnChokeCheck()
++       affecting choice for optimistic unchoking.
++
++   Improvements
++     * Move StopDLTimer() call from RequestPiece() to RequestCheck(),
++       which could occasionally affect peer download rate measurement.
++     * Most clients do not like a slice size of 128K even though it is
++       the max allowed by the BT specification. Changed max slice size to
++       64K. Note that the maximum piece length is 2MB (2097152); if you
++       need to download a torrent with a larger piece size you can change
++       the value of cfg_req_queue_length in btconfig.h from 64 to 128.
++     * Contact tracker immediately upon becoming (or starting as) a
++       seeder.
++     * Changed SendModule() to send only one slice at a time. This will
++       help with fairly distributing upload bandwidth among the unchoked
++       peers.
++     * Changed default peer ID prefix to '-CD0101-', indicating
++       CTorrent-dnh1.1 release.
++     _________________________________________________________________
++
++   Changes for "dnh1" Release
++
++   This is the first release. "dnh" identifies this patchset, and "1"
++   indicates release version 1 of the patchset.
++
++   Patches
++     * Incorporates the following patches. The number is the Request ID
++       from the [2]SourceForge patches page, which you can reference for
++       the details of each patch. The name in brackets is the name of the
++       patch file or a name I chose to refer to the patch. Some of these
++       names are used below (in brackets) to describe a fix or change to
++       a particular patch.
++       1042808 [getcwd] (incorporated in get1file patch)
++       1084776 [passkey] (incorporated in udlimit patch)
++       1109266 [align]
++       1109287 [tracker/tracker2]
++       1114197 [fmt] (incorporated in get1file patch)
++       1114364 [resetdl]
++       1116448 [get1file]
++       1118597 [crash]
++       1119467 [stall]
++       1119492 [rate]
++       1119497 [flush]
++       1119519 [opt]
++       1119689 [status]
++       1124342 [udlimit]
++
++   Download performance
++     * If a peer socket is ready for reading and writing, perform both.
++       Previously the cases were exclusive, with preference given to
++       reading.
++     * Download requests are now made to peers when they are ready for
++       writing (in addition to the existing event-driven cases). This
++       fixes peer stalls when a request couldn't be sent in an
++       event-triggered case due to bandwidth limiting or other
++       circumstances.
++     * Additional tests added so that the above request checking doesn't
++       create hard loops.
++
++   Bandwidth measurement/management
++     * [rate] Bandwidth reporting is now not capped. Also, only the time
++       used for the samples taken is used in the calculation rather than
++       the maximum interval (this affects rate calculation for individual
++       peers).
++     * Additional upload and download bandwidth limit checks added so
++       that bw management is more accurate.
++     * Corrected condition inversion bug in Rate::StopTimer(), which
++       affects peer rate calculations.
++
++   Peer count
++     * Request our max number of peers from the tracker each time rather
++       than just taking the tracker's default, so we can try to fill up.
++     * The tracker will be contacted early if all peers disconnect so
++       that we can actively try to establish some more peer connections.
++       To avoid hammering the tracker, we must have at least one peer for
++       15 seconds in order for this to be invoked.
++     * Some clients use nonzero bytes in the "reserved" part of the
++       handshake. Added code to ignore the reserved bytes if the rest of
++       the handshake is as expected. This includes Azureus 2300 thru 2304
++       (latest) which gives 0x80 as the first reserved byte and BitComet
++       which gives 0x6578 ("ex") as the first two bytes.
++     * Update peer's timestamp on any message, not just keepalives. Any
++       receipt of data from a peer now resets its timeout, preventing
++       early disconnect.
++
++   Parallel requests
++     * Initial-piece and endgame cases have been improved so that pieces
++       will be requested from multiple peers. Cancels are sent as slices
++       (subpieces) are received. This endgame strategy is described in
++       the BitTorrent online spec. The startup strategy is also described
++       in posts and facilitates obtaining a single piece more rapidly in
++       order to obtain some trade value. In initial mode, the piece of
++       which we need the least parts is targeted. In endgame mode, the
++       piece of which we need the most parts is targeted. Slices that are
++       cancelled are also removed from the "pending" queue, as are pieces
++       that are completed.
++     * When duplicating a piece request, the slice request order is also
++       shuffled in order to minimize duplication of effort.
++
++   Tracker info
++     * [status] Seems to be missing tracker.cpp diff. Added code to get
++       tracker's total peers, but not all trackers report these fields in
++       the normal response. Also added code to count successful updates
++       from the tracker.
++     * Added tracker connection state to status line (when
++       connecting/connected).
++
++   Tracker contact
++     * When interrupting (ctrl-C), connect to the tracker immediately
++       rather than waiting 15 seconds.
++     * Contact tracker "soon" after transitioning to seeder state.
++
++   Peer interaction
++     * Manage our interested state for each peer dynamically as content
++       changes.
++     * Unchoking
++          + Use the peer's interested state (confirming via the bitfield
++            that it needs our data) to consider unchoking. Using only the
++            bitfield could cause us to waste an upload slot on a peer
++            that doesn't have all content but isn't interested (like a
++            single-file downloader).
++          + Choke peers that become uninterested or don't need our data.
++          + Try unchoking new peers only as slots open or the optimistic
++            unchoke rotates. Unchoking too many peers can temporarily
++            reduce per-peer upload rates, which would make uploading to
++            us unappealing for good peers.
++          + In a tie for download speed, prefer to unchoke the peer to
++            whom we've uploaded the least data relative to what we've
++            downloaded from him.
++     * Optimistic unchoking
++          + Fixed condition inversion bug causing opt unchoking to occur
++            too often.
++          + A peer who has no pieces is now preferred 75% vs. a peer who
++            already has at least one piece, in order to help the new peer
++            become productive. This is documented in the online spec.
++          + Set peer's last-unchoke-time when choking the peer to get
++            better rotation of the optimistic unchoke. The value is now
++            the last time that a peer was in the unchoked state rather
++            than the time of the last unchoke event.
++
++   Miscellaneous items
++     * [tracker] Fixed normal program end (stop) process, which was
++       crashing.
++     * [get1file] Restore compact tracker response support.
++     * [get1file] Made display of the status line info dependent on
++       whether the option is in use.
++     * [get1file] Apply the filter when checking for what we need from a
++       peer instead of when recording what the peer has; this prevents
++       stalls when we move on to the next file. Update interested state
++       for each peer when we begin a new file. Also move the file-done
++       check into the piece completion code and check whether the next
++       file(s) has also been completed.
++     * Reduced the slice size from 32K to 16K (same as BT & Azureus).
++       This provides more precise DL rate measurement, and helps insure
++       that we receive a productive amount of data (i.e. a complete
++       slice) even if we are unchoked by a peer for only one cycle. See
++       [3]http://groups.yahoo.com/group/BitTorrent/message/1260 for more
++       discussion/analysis on this.
++     * Added -v (verbose) option for additional debugging output.
++
++References
++
++   1. http://www.rahul.net/dholmes/ctorrent/ctcs.html
++   2. http://sourceforge.net/tracker/?atid=598034&group_id=91688&func=browse
++   3. http://groups.yahoo.com/group/BitTorrent/message/1260
+--- Makefile.am.orig   Wed Sep  8 16:10:51 2004
++++ Makefile.am        Wed Oct 12 20:08:00 2005
+@@ -1,2 +1,2 @@
+ bin_PROGRAMS = ctorrent
+-ctorrent_SOURCES = bencode.cpp bitfield.cpp btconfig.cpp btcontent.cpp btfiles.cpp btrequest.cpp btstream.cpp bufio.cpp connect_nonb.cpp ctorrent.cpp downloader.cpp httpencode.cpp iplist.cpp peer.cpp peerlist.cpp rate.cpp setnonblock.cpp sigint.cpp tracker.cpp bencode.h bitfield.h btconfig.h btcontent.h btfiles.h btrequest.h btstream.h bufio.h connect_nonb.h def.h downloader.h httpencode.h iplist.h msgencode.h peer.h peerlist.h rate.h setnonblock.h sigint.h tracker.h
++ctorrent_SOURCES = bencode.cpp bitfield.cpp btconfig.cpp btcontent.cpp btfiles.cpp btrequest.cpp btstream.cpp bufio.cpp connect_nonb.cpp ctcs.cpp ctorrent.cpp downloader.cpp httpencode.cpp iplist.cpp peer.cpp peerlist.cpp rate.cpp setnonblock.cpp sigint.cpp tracker.cpp sha1.c bencode.h bitfield.h btconfig.h btcontent.h btfiles.h btrequest.h btstream.h bufio.h connect_nonb.h ctcs.h def.h downloader.h httpencode.h iplist.h msgencode.h peer.h peerlist.h rate.h setnonblock.h sigint.h tracker.h sha1.h
+--- aclocal.m4.orig    Wed Sep  8 16:10:51 2004
++++ aclocal.m4 Thu Nov 10 20:56:00 2005
+@@ -1,6 +1,6 @@
+-# generated automatically by aclocal 1.7.6 -*- Autoconf -*-
++# generated automatically by aclocal 1.9.1 -*- Autoconf -*-
+-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ # Free Software Foundation, Inc.
+ # This file is free software; the Free Software Foundation
+ # gives unlimited permission to copy and/or distribute it,
+@@ -11,132 +11,9 @@
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ # PARTICULAR PURPOSE.
+-# Do all the work for Automake.                            -*- Autoconf -*-
+-
+-# This macro actually does too much some checks are only needed if
+-# your package does certain things.  But this isn't really a big deal.
+-
+-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+-# Free Software Foundation, Inc.
+-
+-# 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, 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.
+-
+-# serial 10
+-
+-AC_PREREQ([2.54])
+-
+-# Autoconf 2.50 wants to disallow AM_ names.  We explicitly allow
+-# the ones we care about.
+-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+-
+-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+-# AM_INIT_AUTOMAKE([OPTIONS])
+-# -----------------------------------------------
+-# The call with PACKAGE and VERSION arguments is the old style
+-# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+-# and VERSION should now be passed to AC_INIT and removed from
+-# the call to AM_INIT_AUTOMAKE.
+-# We support both call styles for the transition.  After
+-# the next Automake release, Autoconf can make the AC_INIT
+-# arguments mandatory, and then we can depend on a new Autoconf
+-# release and drop the old call support.
+-AC_DEFUN([AM_INIT_AUTOMAKE],
+-[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+- AC_REQUIRE([AC_PROG_INSTALL])dnl
+-# test to see if srcdir already configured
+-if test "`cd $srcdir && pwd`" != "`pwd`" &&
+-   test -f $srcdir/config.status; then
+-  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+-fi
+-
+-# test whether we have cygpath
+-if test -z "$CYGPATH_W"; then
+-  if (cygpath --version) >/dev/null 2>/dev/null; then
+-    CYGPATH_W='cygpath -w'
+-  else
+-    CYGPATH_W=echo
+-  fi
+-fi
+-AC_SUBST([CYGPATH_W])
+-
+-# Define the identity of the package.
+-dnl Distinguish between old-style and new-style calls.
+-m4_ifval([$2],
+-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+- AC_SUBST([PACKAGE], [$1])dnl
+- AC_SUBST([VERSION], [$2])],
+-[_AM_SET_OPTIONS([$1])dnl
+- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+-
+-_AM_IF_OPTION([no-define],,
+-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+-
+-# Some tools Automake needs.
+-AC_REQUIRE([AM_SANITY_CHECK])dnl
+-AC_REQUIRE([AC_ARG_PROGRAM])dnl
+-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+-AM_MISSING_PROG(AUTOCONF, autoconf)
+-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+-AM_MISSING_PROG(AUTOHEADER, autoheader)
+-AM_MISSING_PROG(MAKEINFO, makeinfo)
+-AM_MISSING_PROG(AMTAR, tar)
+-AM_PROG_INSTALL_SH
+-AM_PROG_INSTALL_STRIP
+-# We need awk for the "check" target.  The system "awk" is bad on
+-# some platforms.
+-AC_REQUIRE([AC_PROG_AWK])dnl
+-AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+-AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+-
+-_AM_IF_OPTION([no-dependencies],,
+-[AC_PROVIDE_IFELSE([AC_PROG_CC],
+-                  [_AM_DEPENDENCIES(CC)],
+-                  [define([AC_PROG_CC],
+-                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+-AC_PROVIDE_IFELSE([AC_PROG_CXX],
+-                  [_AM_DEPENDENCIES(CXX)],
+-                  [define([AC_PROG_CXX],
+-                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+-])
+-])
+-
+-
+-# When config.status generates a header, we must update the stamp-h file.
+-# This file resides in the same directory as the config header
+-# that is generated.  The stamp files are numbered to have different names.
+-
+-# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+-# loop where config.status creates the headers, so we can generate
+-# our stamp files there.
+-AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+-[# Compute $1's index in $config_headers.
+-_am_stamp_count=1
+-for _am_header in $config_headers :; do
+-  case $_am_header in
+-    $1 | $1:* )
+-      break ;;
+-    * )
+-      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+-  esac
+-done
+-echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+-
+-# Copyright 2002  Free Software Foundation, Inc.
++#                                                        -*- Autoconf -*-
++# Copyright (C) 2002, 2003  Free Software Foundation, Inc.
++# Generated from amversion.in; do not edit by hand.
+ # 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
+@@ -156,18 +33,18 @@
+ # ----------------------------
+ # Automake X.Y traces this macro to ensure aclocal.m4 has been
+ # generated from the m4 files accompanying Automake X.Y.
+-AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"])
++AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
+ # AM_SET_CURRENT_AUTOMAKE_VERSION
+ # -------------------------------
+ # Call AM_AUTOMAKE_VERSION so it can be traced.
+ # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+ AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+-       [AM_AUTOMAKE_VERSION([1.7.6])])
++       [AM_AUTOMAKE_VERSION([1.9.1])])
+-# Helper functions for option handling.                    -*- Autoconf -*-
++# AM_AUX_DIR_EXPAND
+-# Copyright 2001, 2002  Free Software Foundation, Inc.
++# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ # 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
+@@ -184,36 +61,54 @@
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ # 02111-1307, USA.
+-# serial 2
+-
+-# _AM_MANGLE_OPTION(NAME)
+-# -----------------------
+-AC_DEFUN([_AM_MANGLE_OPTION],
+-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+-
+-# _AM_SET_OPTION(NAME)
+-# ------------------------------
+-# Set option NAME.  Presently that only means defining a flag for this option.
+-AC_DEFUN([_AM_SET_OPTION],
+-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+-
+-# _AM_SET_OPTIONS(OPTIONS)
+-# ----------------------------------
+-# OPTIONS is a space-separated list of Automake options.
+-AC_DEFUN([_AM_SET_OPTIONS],
+-[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+-
+-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+-# -------------------------------------------
+-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+-AC_DEFUN([_AM_IF_OPTION],
+-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+-
++# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
++# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
++# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+ #
+-# Check to make sure that the build environment is sane.
++# Of course, Automake must honor this variable whenever it calls a
++# tool from the auxiliary directory.  The problem is that $srcdir (and
++# therefore $ac_aux_dir as well) can be either absolute or relative,
++# depending on how configure is run.  This is pretty annoying, since
++# it makes $ac_aux_dir quite unusable in subdirectories: in the top
++# source directory, any form will work fine, but in subdirectories a
++# relative path needs to be adjusted first.
++#
++# $ac_aux_dir/missing
++#    fails when called from a subdirectory if $ac_aux_dir is relative
++# $top_srcdir/$ac_aux_dir/missing
++#    fails if $ac_aux_dir is absolute,
++#    fails when called from a subdirectory in a VPATH build with
++#          a relative $ac_aux_dir
++#
++# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
++# are both prefixed by $srcdir.  In an in-source build this is usually
++# harmless because $srcdir is `.', but things will broke when you
++# start a VPATH build or use an absolute $srcdir.
++#
++# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
++# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
++#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
++# and then we would define $MISSING as
++#   MISSING="\${SHELL} $am_aux_dir/missing"
++# This will work as long as MISSING is not called from configure, because
++# unfortunately $(top_srcdir) has no meaning in configure.
++# However there are other variables, like CC, which are often used in
++# configure, and could therefore not use this "fixed" $ac_aux_dir.
+ #
++# Another solution, used here, is to always expand $ac_aux_dir to an
++# absolute PATH.  The drawback is that using absolute paths prevent a
++# configured tree to be moved without reconfiguration.
++
++AC_DEFUN([AM_AUX_DIR_EXPAND],
++[dnl Rely on autoconf to set up CDPATH properly.
++AC_PREREQ([2.50])dnl
++# expand $ac_aux_dir to an absolute path
++am_aux_dir=`cd $ac_aux_dir && pwd`
++])
+-# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
++# AM_CONDITIONAL                                              -*- Autoconf -*-
++
++# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ # 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
+@@ -230,53 +125,34 @@
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ # 02111-1307, USA.
+-# serial 3
+-
+-# AM_SANITY_CHECK
+-# ---------------
+-AC_DEFUN([AM_SANITY_CHECK],
+-[AC_MSG_CHECKING([whether build environment is sane])
+-# Just in case
+-sleep 1
+-echo timestamp > conftest.file
+-# Do `set' in a subshell so we don't clobber the current shell's
+-# arguments.  Must try -L first in case configure is actually a
+-# symlink; some systems play weird games with the mod time of symlinks
+-# (eg FreeBSD returns the mod time of the symlink's containing
+-# directory).
+-if (
+-   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+-   if test "$[*]" = "X"; then
+-      # -L didn't work.
+-      set X `ls -t $srcdir/configure conftest.file`
+-   fi
+-   rm -f conftest.file
+-   if test "$[*]" != "X $srcdir/configure conftest.file" \
+-      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+-
+-      # If neither matched, then we have a broken ls.  This can happen
+-      # if, for instance, CONFIG_SHELL is bash and it inherits a
+-      # broken ls alias from the environment.  This has actually
+-      # happened.  Such a system could not be considered "sane".
+-      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+-alias in your environment])
+-   fi
++# serial 6
+-   test "$[2]" = conftest.file
+-   )
+-then
+-   # Ok.
+-   :
++# AM_CONDITIONAL(NAME, SHELL-CONDITION)
++# -------------------------------------
++# Define a conditional.
++AC_DEFUN([AM_CONDITIONAL],
++[AC_PREREQ(2.52)dnl
++ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
++      [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
++AC_SUBST([$1_TRUE])
++AC_SUBST([$1_FALSE])
++if $2; then
++  $1_TRUE=
++  $1_FALSE='#'
+ else
+-   AC_MSG_ERROR([newly created file is older than distributed files!
+-Check your system clock])
++  $1_TRUE='#'
++  $1_FALSE=
+ fi
+-AC_MSG_RESULT(yes)])
+-
+-#  -*- Autoconf -*-
++AC_CONFIG_COMMANDS_PRE(
++[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
++  AC_MSG_ERROR([[conditional "$1" was never defined.
++Usually this means the macro was only invoked conditionally.]])
++fi])])
++# serial 7                                            -*- Autoconf -*-
+-# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
++# Free Software Foundation, Inc.
+ # 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
+@@ -293,220 +169,12 @@
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ # 02111-1307, USA.
+-# serial 3
+-# AM_MISSING_PROG(NAME, PROGRAM)
+-# ------------------------------
+-AC_DEFUN([AM_MISSING_PROG],
+-[AC_REQUIRE([AM_MISSING_HAS_RUN])
+-$1=${$1-"${am_missing_run}$2"}
+-AC_SUBST($1)])
+-
+-
+-# AM_MISSING_HAS_RUN
+-# ------------------
+-# Define MISSING if not defined so far and test if it supports --run.
+-# If it does, set am_missing_run to use it, otherwise, to nothing.
+-AC_DEFUN([AM_MISSING_HAS_RUN],
+-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+-test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+-# Use eval to expand $SHELL
+-if eval "$MISSING --run true"; then
+-  am_missing_run="$MISSING --run "
+-else
+-  am_missing_run=
+-  AC_MSG_WARN([`missing' script is too old or missing])
+-fi
+-])
+-
+-# AM_AUX_DIR_EXPAND
+-
+-# Copyright 2001 Free Software Foundation, Inc.
+-
+-# 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, 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.
+-
+-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+-# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+-#
+-# Of course, Automake must honor this variable whenever it calls a
+-# tool from the auxiliary directory.  The problem is that $srcdir (and
+-# therefore $ac_aux_dir as well) can be either absolute or relative,
+-# depending on how configure is run.  This is pretty annoying, since
+-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+-# source directory, any form will work fine, but in subdirectories a
+-# relative path needs to be adjusted first.
+-#
+-# $ac_aux_dir/missing
+-#    fails when called from a subdirectory if $ac_aux_dir is relative
+-# $top_srcdir/$ac_aux_dir/missing
+-#    fails if $ac_aux_dir is absolute,
+-#    fails when called from a subdirectory in a VPATH build with
+-#          a relative $ac_aux_dir
+-#
+-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+-# are both prefixed by $srcdir.  In an in-source build this is usually
+-# harmless because $srcdir is `.', but things will broke when you
+-# start a VPATH build or use an absolute $srcdir.
+-#
+-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+-# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+-#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+-# and then we would define $MISSING as
+-#   MISSING="\${SHELL} $am_aux_dir/missing"
+-# This will work as long as MISSING is not called from configure, because
+-# unfortunately $(top_srcdir) has no meaning in configure.
+-# However there are other variables, like CC, which are often used in
+-# configure, and could therefore not use this "fixed" $ac_aux_dir.
+-#
+-# Another solution, used here, is to always expand $ac_aux_dir to an
+-# absolute PATH.  The drawback is that using absolute paths prevent a
+-# configured tree to be moved without reconfiguration.
+-
+-# Rely on autoconf to set up CDPATH properly.
+-AC_PREREQ([2.50])
+-
+-AC_DEFUN([AM_AUX_DIR_EXPAND], [
+-# expand $ac_aux_dir to an absolute path
+-am_aux_dir=`cd $ac_aux_dir && pwd`
+-])
+-
+-# AM_PROG_INSTALL_SH
+-# ------------------
+-# Define $install_sh.
+-
+-# Copyright 2001 Free Software Foundation, Inc.
+-
+-# 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, 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.
+-
+-AC_DEFUN([AM_PROG_INSTALL_SH],
+-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+-install_sh=${install_sh-"$am_aux_dir/install-sh"}
+-AC_SUBST(install_sh)])
+-
+-# AM_PROG_INSTALL_STRIP
+-
+-# Copyright 2001 Free Software Foundation, Inc.
+-
+-# 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, 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.
+-
+-# One issue with vendor `install' (even GNU) is that you can't
+-# specify the program used to strip binaries.  This is especially
+-# annoying in cross-compiling environments, where the build's strip
+-# is unlikely to handle the host's binaries.
+-# Fortunately install-sh will honor a STRIPPROG variable, so we
+-# always use install-sh in `make install-strip', and initialize
+-# STRIPPROG with the value of the STRIP variable (set by the user).
+-AC_DEFUN([AM_PROG_INSTALL_STRIP],
+-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+-# Installed binaries are usually stripped using `strip' when the user
+-# run `make install-strip'.  However `strip' might not be the right
+-# tool to use in cross-compilation environments, therefore Automake
+-# will honor the `STRIP' environment variable to overrule this program.
+-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+-if test "$cross_compiling" != no; then
+-  AC_CHECK_TOOL([STRIP], [strip], :)
+-fi
+-INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+-AC_SUBST([INSTALL_STRIP_PROGRAM])])
+-
+-#                                                          -*- Autoconf -*-
+-# Copyright (C) 2003  Free Software Foundation, Inc.
+-
+-# 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, 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.
+-
+-# serial 1
+-
+-# Check whether the underlying file-system supports filenames
+-# with a leading dot.  For instance MS-DOS doesn't.
+-AC_DEFUN([AM_SET_LEADING_DOT],
+-[rm -rf .tst 2>/dev/null
+-mkdir .tst 2>/dev/null
+-if test -d .tst; then
+-  am__leading_dot=.
+-else
+-  am__leading_dot=_
+-fi
+-rmdir .tst 2>/dev/null
+-AC_SUBST([am__leading_dot])])
+-
+-# serial 5                                            -*- Autoconf -*-
+-
+-# Copyright (C) 1999, 2000, 2001, 2002, 2003  Free Software Foundation, Inc.
+-
+-# 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, 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.
+-
+-
+-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+-# written in clear, in which case automake, when reading aclocal.m4,
+-# will think it sees a *use*, and therefore will trigger all it's
+-# C support machinery.  Also note that it means that autoscan, seeing
+-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
++# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
++# written in clear, in which case automake, when reading aclocal.m4,
++# will think it sees a *use*, and therefore will trigger all it's
++# C support machinery.  Also note that it means that autoscan, seeing
++# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+@@ -568,7 +236,9 @@
+     : > sub/conftest.c
+     for i in 1 2 3 4 5 6; do
+       echo '#include "conftst'$i'.h"' >> sub/conftest.c
+-      : > sub/conftst$i.h
++      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
++      # Solaris 8's {/usr,}/bin/sh.
++      touch sub/conftst$i.h
+     done
+     echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+@@ -596,9 +266,14 @@
+        grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+        ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+       # icc doesn't choke on unknown options, it will just issue warnings
+-      # (even with -Werror).  So we grep stderr for any message
+-      # that says an option was ignored.
+-      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
++      # or remarks (even with -Werror).  So we grep stderr for any message
++      # that says an option was ignored or not supported.
++      # When given -MP, icc 7.0 and 7.1 complain thusly:
++      #   icc: Command line warning: ignoring option '-M'; no argument required
++      # The diagnosis changed in icc 8.0:
++      #   icc: Command line remark: option '-MP' not supported
++      if (grep 'ignoring option' conftest.err ||
++          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+         am_cv_$1_dependencies_compiler_type=$depmode
+         break
+       fi
+@@ -632,8 +307,8 @@
+ # ------------
+ AC_DEFUN([AM_DEP_TRACK],
+ [AC_ARG_ENABLE(dependency-tracking,
+-[  --disable-dependency-tracking Speeds up one-time builds
+-  --enable-dependency-tracking  Do not reject slow dependency extractors])
++[  --disable-dependency-tracking  speeds up one-time build
++  --enable-dependency-tracking   do not reject slow dependency extractors])
+ if test "x$enable_dependency_tracking" != xno; then
+   am_depcomp="$ac_aux_dir/depcomp"
+   AMDEPBACKSLASH='\'
+@@ -644,7 +319,8 @@
+ # Generate code to set up dependency tracking.   -*- Autoconf -*-
+-# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
++#   Free Software Foundation, Inc.
+ # 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
+@@ -680,27 +356,21 @@
+   else
+     continue
+   fi
+-  grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+-  # Extract the definition of DEP_FILES from the Makefile without
+-  # running `make'.
+-  DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
++  # Extract the definition of DEPDIR, am__include, and am__quote
++  # from the Makefile without running `make'.
++  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+   test -z "$DEPDIR" && continue
++  am__include=`sed -n 's/^am__include = //p' < "$mf"`
++  test -z "am__include" && continue
++  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+   # When using ansi2knr, U may be empty or an underscore; expand it
+-  U=`sed -n -e '/^U = / s///p' < "$mf"`
+-  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+-  # We invoke sed twice because it is the simplest approach to
+-  # changing $(DEPDIR) to its actual value in the expansion.
+-  for file in `sed -n -e '
+-    /^DEP_FILES = .*\\\\$/ {
+-      s/^DEP_FILES = //
+-      :loop
+-      s/\\\\$//
+-      p
+-      n
+-      /\\\\$/ b loop
+-      p
+-    }
+-    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
++  U=`sed -n 's/^U = //p' < "$mf"`
++  # Find all dependency output files, they are included files with
++  # $(DEPDIR) in their names.  We invoke sed twice because it is the
++  # simplest approach to changing $(DEPDIR) to its actual value in the
++  # expansion.
++  for file in `sed -n "
++    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+     # Make sure the directory exists.
+     test -f "$dirpart/$file" && continue
+@@ -726,9 +396,13 @@
+      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+ ])
+-# Check to see how 'make' treats includes.    -*- Autoconf -*-
++# Do all the work for Automake.                            -*- Autoconf -*-
+-# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
++# This macro actually does too much some checks are only needed if
++# your package does certain things.  But this isn't really a big deal.
++
++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
++# Free Software Foundation, Inc.
+ # 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
+@@ -745,43 +419,223 @@
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ # 02111-1307, USA.
+-# serial 2
++# serial 11
+-# AM_MAKE_INCLUDE()
+-# -----------------
+-# Check to see how make treats includes.
+-AC_DEFUN([AM_MAKE_INCLUDE],
+-[am_make=${MAKE-make}
+-cat > confinc << 'END'
+-am__doit:
+-      @echo done
+-.PHONY: am__doit
+-END
+-# If we don't find an include directive, just comment out the code.
+-AC_MSG_CHECKING([for style of include used by $am_make])
+-am__include="#"
+-am__quote=
+-_am_result=none
+-# First try GNU make style include.
+-echo "include confinc" > confmf
+-# We grep out `Entering directory' and `Leaving directory'
+-# messages which can occur if `w' ends up in MAKEFLAGS.
+-# In particular we don't look at `^make:' because GNU make might
+-# be invoked under some other name (usually "gmake"), in which
+-# case it prints its new name instead of `make'.
+-if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+-   am__include=include
+-   am__quote=
+-   _am_result=GNU
+-fi
+-# Now try BSD make style include.
+-if test "$am__include" = "#"; then
+-   echo '.include "confinc"' > confmf
+-   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+-      am__include=.include
+-      am__quote="\""
+-      _am_result=BSD
+-   fi
++# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
++# AM_INIT_AUTOMAKE([OPTIONS])
++# -----------------------------------------------
++# The call with PACKAGE and VERSION arguments is the old style
++# call (pre autoconf-2.50), which is being phased out.  PACKAGE
++# and VERSION should now be passed to AC_INIT and removed from
++# the call to AM_INIT_AUTOMAKE.
++# We support both call styles for the transition.  After
++# the next Automake release, Autoconf can make the AC_INIT
++# arguments mandatory, and then we can depend on a new Autoconf
++# release and drop the old call support.
++AC_DEFUN([AM_INIT_AUTOMAKE],
++[AC_PREREQ([2.58])dnl
++dnl Autoconf wants to disallow AM_ names.  We explicitly allow
++dnl the ones we care about.
++m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
++AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
++AC_REQUIRE([AC_PROG_INSTALL])dnl
++# test to see if srcdir already configured
++if test "`cd $srcdir && pwd`" != "`pwd`" &&
++   test -f $srcdir/config.status; then
++  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
++fi
++
++# test whether we have cygpath
++if test -z "$CYGPATH_W"; then
++  if (cygpath --version) >/dev/null 2>/dev/null; then
++    CYGPATH_W='cygpath -w'
++  else
++    CYGPATH_W=echo
++  fi
++fi
++AC_SUBST([CYGPATH_W])
++
++# Define the identity of the package.
++dnl Distinguish between old-style and new-style calls.
++m4_ifval([$2],
++[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
++ AC_SUBST([PACKAGE], [$1])dnl
++ AC_SUBST([VERSION], [$2])],
++[_AM_SET_OPTIONS([$1])dnl
++ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
++ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
++
++_AM_IF_OPTION([no-define],,
++[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
++ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
++
++# Some tools Automake needs.
++AC_REQUIRE([AM_SANITY_CHECK])dnl
++AC_REQUIRE([AC_ARG_PROGRAM])dnl
++AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
++AM_MISSING_PROG(AUTOCONF, autoconf)
++AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
++AM_MISSING_PROG(AUTOHEADER, autoheader)
++AM_MISSING_PROG(MAKEINFO, makeinfo)
++AM_PROG_INSTALL_SH
++AM_PROG_INSTALL_STRIP
++AC_REQUIRE([AM_PROG_MKDIR_P])dnl
++# We need awk for the "check" target.  The system "awk" is bad on
++# some platforms.
++AC_REQUIRE([AC_PROG_AWK])dnl
++AC_REQUIRE([AC_PROG_MAKE_SET])dnl
++AC_REQUIRE([AM_SET_LEADING_DOT])dnl
++_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
++              [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
++                           [_AM_PROG_TAR([v7])])])
++_AM_IF_OPTION([no-dependencies],,
++[AC_PROVIDE_IFELSE([AC_PROG_CC],
++                  [_AM_DEPENDENCIES(CC)],
++                  [define([AC_PROG_CC],
++                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
++AC_PROVIDE_IFELSE([AC_PROG_CXX],
++                  [_AM_DEPENDENCIES(CXX)],
++                  [define([AC_PROG_CXX],
++                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
++])
++])
++
++
++# When config.status generates a header, we must update the stamp-h file.
++# This file resides in the same directory as the config header
++# that is generated.  The stamp files are numbered to have different names.
++
++# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
++# loop where config.status creates the headers, so we can generate
++# our stamp files there.
++AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
++[# Compute $1's index in $config_headers.
++_am_stamp_count=1
++for _am_header in $config_headers :; do
++  case $_am_header in
++    $1 | $1:* )
++      break ;;
++    * )
++      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
++  esac
++done
++echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
++
++# AM_PROG_INSTALL_SH
++# ------------------
++# Define $install_sh.
++
++# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
++
++# 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, 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.
++
++AC_DEFUN([AM_PROG_INSTALL_SH],
++[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
++install_sh=${install_sh-"$am_aux_dir/install-sh"}
++AC_SUBST(install_sh)])
++
++#                                                          -*- Autoconf -*-
++# Copyright (C) 2003  Free Software Foundation, Inc.
++
++# 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, 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.
++
++# serial 1
++
++# Check whether the underlying file-system supports filenames
++# with a leading dot.  For instance MS-DOS doesn't.
++AC_DEFUN([AM_SET_LEADING_DOT],
++[rm -rf .tst 2>/dev/null
++mkdir .tst 2>/dev/null
++if test -d .tst; then
++  am__leading_dot=.
++else
++  am__leading_dot=_
++fi
++rmdir .tst 2>/dev/null
++AC_SUBST([am__leading_dot])])
++
++# Check to see how 'make' treats includes.    -*- Autoconf -*-
++
++# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
++
++# 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, 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.
++
++# serial 2
++
++# AM_MAKE_INCLUDE()
++# -----------------
++# Check to see how make treats includes.
++AC_DEFUN([AM_MAKE_INCLUDE],
++[am_make=${MAKE-make}
++cat > confinc << 'END'
++am__doit:
++      @echo done
++.PHONY: am__doit
++END
++# If we don't find an include directive, just comment out the code.
++AC_MSG_CHECKING([for style of include used by $am_make])
++am__include="#"
++am__quote=
++_am_result=none
++# First try GNU make style include.
++echo "include confinc" > confmf
++# We grep out `Entering directory' and `Leaving directory'
++# messages which can occur if `w' ends up in MAKEFLAGS.
++# In particular we don't look at `^make:' because GNU make might
++# be invoked under some other name (usually "gmake"), in which
++# case it prints its new name instead of `make'.
++if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
++   am__include=include
++   am__quote=
++   _am_result=GNU
++fi
++# Now try BSD make style include.
++if test "$am__include" = "#"; then
++   echo '.include "confinc"' > confmf
++   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
++      am__include=.include
++      am__quote="\""
++      _am_result=BSD
++   fi
+ fi
+ AC_SUBST([am__include])
+ AC_SUBST([am__quote])
+@@ -789,9 +643,10 @@
+ rm -f confinc confmf
+ ])
+-# AM_CONDITIONAL                                              -*- Autoconf -*-
++#  -*- Autoconf -*-
++
+-# Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
++# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ # 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
+@@ -808,28 +663,358 @@
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ # 02111-1307, USA.
+-# serial 5
++# serial 3
+-AC_PREREQ(2.52)
++# AM_MISSING_PROG(NAME, PROGRAM)
++# ------------------------------
++AC_DEFUN([AM_MISSING_PROG],
++[AC_REQUIRE([AM_MISSING_HAS_RUN])
++$1=${$1-"${am_missing_run}$2"}
++AC_SUBST($1)])
+-# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+-# -------------------------------------
+-# Define a conditional.
+-AC_DEFUN([AM_CONDITIONAL],
+-[ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+-        [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+-AC_SUBST([$1_TRUE])
+-AC_SUBST([$1_FALSE])
+-if $2; then
+-  $1_TRUE=
+-  $1_FALSE='#'
++
++# AM_MISSING_HAS_RUN
++# ------------------
++# Define MISSING if not defined so far and test if it supports --run.
++# If it does, set am_missing_run to use it, otherwise, to nothing.
++AC_DEFUN([AM_MISSING_HAS_RUN],
++[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
++test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
++# Use eval to expand $SHELL
++if eval "$MISSING --run true"; then
++  am_missing_run="$MISSING --run "
+ else
+-  $1_TRUE='#'
+-  $1_FALSE=
++  am_missing_run=
++  AC_MSG_WARN([`missing' script is too old or missing])
+ fi
+-AC_CONFIG_COMMANDS_PRE(
+-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+-  AC_MSG_ERROR([conditional "$1" was never defined.
+-Usually this means the macro was only invoked conditionally.])
+-fi])])
++])
++
++# AM_PROG_MKDIR_P
++# ---------------
++# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
++
++# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
++
++# 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, 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.
++
++# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
++# created by `make install' are always world readable, even if the
++# installer happens to have an overly restrictive umask (e.g. 077).
++# This was a mistake.  There are at least two reasons why we must not
++# use `-m 0755':
++#   - it causes special bits like SGID to be ignored,
++#   - it may be too restrictive (some setups expect 775 directories).
++#
++# Do not use -m 0755 and let people choose whatever they expect by
++# setting umask.
++#
++# We cannot accept any implementation of `mkdir' that recognizes `-p'.
++# Some implementations (such as Solaris 8's) are not thread-safe: if a
++# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
++# concurrently, both version can detect that a/ is missing, but only
++# one can create it and the other will error out.  Consequently we
++# restrict ourselves to GNU make (using the --version option ensures
++# this.)
++AC_DEFUN([AM_PROG_MKDIR_P],
++[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
++  # We used to keeping the `.' as first argument, in order to
++  # allow $(mkdir_p) to be used without argument.  As in
++  #   $(mkdir_p) $(somedir)
++  # where $(somedir) is conditionally defined.  However this is wrong
++  # for two reasons:
++  #  1. if the package is installed by a user who cannot write `.'
++  #     make install will fail,
++  #  2. the above comment should most certainly read
++  #     $(mkdir_p) $(DESTDIR)$(somedir)
++  #     so it does not work when $(somedir) is undefined and
++  #     $(DESTDIR) is not.
++  #  To support the latter case, we have to write
++  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
++  #  so the `.' trick is pointless.
++  mkdir_p='mkdir -p --'
++else
++  # On NextStep and OpenStep, the `mkdir' command does not
++  # recognize any option.  It will interpret all options as
++  # directories to create, and then abort because `.' already
++  # exists.
++  for d in ./-p ./--version;
++  do
++    test -d $d && rmdir $d
++  done
++  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
++  if test -f "$ac_aux_dir/mkinstalldirs"; then
++    mkdir_p='$(mkinstalldirs)'
++  else
++    mkdir_p='$(install_sh) -d'
++  fi
++fi
++AC_SUBST([mkdir_p])])
++
++# Helper functions for option handling.                    -*- Autoconf -*-
++
++# Copyright (C) 2001, 2002, 2003  Free Software Foundation, Inc.
++
++# 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, 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.
++
++# serial 2
++
++# _AM_MANGLE_OPTION(NAME)
++# -----------------------
++AC_DEFUN([_AM_MANGLE_OPTION],
++[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
++
++# _AM_SET_OPTION(NAME)
++# ------------------------------
++# Set option NAME.  Presently that only means defining a flag for this option.
++AC_DEFUN([_AM_SET_OPTION],
++[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
++
++# _AM_SET_OPTIONS(OPTIONS)
++# ----------------------------------
++# OPTIONS is a space-separated list of Automake options.
++AC_DEFUN([_AM_SET_OPTIONS],
++[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
++
++# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
++# -------------------------------------------
++# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
++AC_DEFUN([_AM_IF_OPTION],
++[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
++
++#
++# Check to make sure that the build environment is sane.
++#
++
++# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
++
++# 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, 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.
++
++# serial 3
++
++# AM_SANITY_CHECK
++# ---------------
++AC_DEFUN([AM_SANITY_CHECK],
++[AC_MSG_CHECKING([whether build environment is sane])
++# Just in case
++sleep 1
++echo timestamp > conftest.file
++# Do `set' in a subshell so we don't clobber the current shell's
++# arguments.  Must try -L first in case configure is actually a
++# symlink; some systems play weird games with the mod time of symlinks
++# (eg FreeBSD returns the mod time of the symlink's containing
++# directory).
++if (
++   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
++   if test "$[*]" = "X"; then
++      # -L didn't work.
++      set X `ls -t $srcdir/configure conftest.file`
++   fi
++   rm -f conftest.file
++   if test "$[*]" != "X $srcdir/configure conftest.file" \
++      && test "$[*]" != "X conftest.file $srcdir/configure"; then
++
++      # If neither matched, then we have a broken ls.  This can happen
++      # if, for instance, CONFIG_SHELL is bash and it inherits a
++      # broken ls alias from the environment.  This has actually
++      # happened.  Such a system could not be considered "sane".
++      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
++alias in your environment])
++   fi
++
++   test "$[2]" = conftest.file
++   )
++then
++   # Ok.
++   :
++else
++   AC_MSG_ERROR([newly created file is older than distributed files!
++Check your system clock])
++fi
++AC_MSG_RESULT(yes)])
++
++# AM_PROG_INSTALL_STRIP
++
++# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
++
++# 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, 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.
++
++# One issue with vendor `install' (even GNU) is that you can't
++# specify the program used to strip binaries.  This is especially
++# annoying in cross-compiling environments, where the build's strip
++# is unlikely to handle the host's binaries.
++# Fortunately install-sh will honor a STRIPPROG variable, so we
++# always use install-sh in `make install-strip', and initialize
++# STRIPPROG with the value of the STRIP variable (set by the user).
++AC_DEFUN([AM_PROG_INSTALL_STRIP],
++[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
++# Installed binaries are usually stripped using `strip' when the user
++# run `make install-strip'.  However `strip' might not be the right
++# tool to use in cross-compilation environments, therefore Automake
++# will honor the `STRIP' environment variable to overrule this program.
++dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
++if test "$cross_compiling" != no; then
++  AC_CHECK_TOOL([STRIP], [strip], :)
++fi
++INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
++AC_SUBST([INSTALL_STRIP_PROGRAM])])
++
++# Check how to create a tarball.                            -*- Autoconf -*-
++
++# Copyright (C) 2004  Free Software Foundation, Inc.
++
++# 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, 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.
++
++# serial 1
++
++
++# _AM_PROG_TAR(FORMAT)
++# --------------------
++# Check how to create a tarball in format FORMAT.
++# FORMAT should be one of `v7', `ustar', or `pax'.
++#
++# Substitute a variable $(am__tar) that is a command
++# writing to stdout a FORMAT-tarball containing the directory
++# $tardir.
++#     tardir=directory && $(am__tar) > result.tar
++#
++# Substitute a variable $(am__untar) that extract such
++# a tarball read from stdin.
++#     $(am__untar) < result.tar
++AC_DEFUN([_AM_PROG_TAR],
++[# Always define AMTAR for backward compatibility.
++AM_MISSING_PROG([AMTAR], [tar])
++m4_if([$1], [v7],
++     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
++     [m4_case([$1], [ustar],, [pax],,
++              [m4_fatal([Unknown tar format])])
++AC_MSG_CHECKING([how to create a $1 tar archive])
++# Loop over all known methods to create a tar archive until one works.
++_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
++_am_tools=${am_cv_prog_tar_$1-$_am_tools}
++# Do not fold the above two line into one, because Tru64 sh and
++# Solaris sh will not grok spaces in the rhs of `-'.
++for _am_tool in $_am_tools
++do
++  case $_am_tool in
++  gnutar)
++    for _am_tar in tar gnutar gtar;
++    do
++      AM_RUN_LOG([$_am_tar --version]) && break
++    done
++    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
++    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
++    am__untar="$_am_tar -xf -"
++    ;;
++  plaintar)
++    # Must skip GNU tar: if it does not support --format= it doesn't create
++    # ustar tarball either.
++    (tar --version) >/dev/null 2>&1 && continue
++    am__tar='tar chf - "$$tardir"'
++    am__tar_='tar chf - "$tardir"'
++    am__untar='tar xf -'
++    ;;
++  pax)
++    am__tar='pax -L -x $1 -w "$$tardir"'
++    am__tar_='pax -L -x $1 -w "$tardir"'
++    am__untar='pax -r'
++    ;;
++  cpio)
++    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
++    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
++    am__untar='cpio -i -H $1 -d'
++    ;;
++  none)
++    am__tar=false
++    am__tar_=false
++    am__untar=false
++    ;;
++  esac
++
++  # If the value was cached, stop now.  We just wanted to have am__tar
++  # and am__untar set.
++  test -n "${am_cv_prog_tar_$1}" && break
++
++  # tar/untar a dummy directory, and stop if the command works
++  rm -rf conftest.dir
++  mkdir conftest.dir
++  echo GrepMe > conftest.dir/file
++  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
++  rm -rf conftest.dir
++  if test -s conftest.tar; then
++    AM_RUN_LOG([$am__untar <conftest.tar])
++    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
++  fi
++done
++rm -rf conftest.dir
++
++AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
++AC_MSG_RESULT([$am_cv_prog_tar_$1])])
++AC_SUBST([am__tar])
++AC_SUBST([am__untar])
++]) # _AM_PROG_TAR
+--- configure.ac.orig  Wed Sep  8 16:10:51 2004
++++ configure.ac       Thu Nov 10 20:56:00 2005
+@@ -1,6 +1,6 @@
+ # Process this file with autoconf to produce a configure script.
+-AC_INIT([CTorrent], [devel], [bsdi@sina.com])
+-AM_INIT_AUTOMAKE(ctorrent,devel)
++AC_INIT([CTorrent], [dnh2], [dholmes@ct.boxmail.com])
++AM_INIT_AUTOMAKE(ctorrent,dnh2)
+ AC_CONFIG_HEADER([config.h])
+ AC_CONFIG_SRCDIR([ctorrent.cpp])
+@@ -14,7 +14,7 @@
+       [AC_CHECK_LIB([crypt],[SHA1_Init],,
+       [AC_CHECK_LIB([crypto],[SHA1_Init],,
+       [AC_CHECK_LIB([md],[SHA1_Init],,
+-      [AC_MSG_ERROR([error, Please install OpenSSL first!])])])])])
++      [AC_DEFINE([USE_STANDALONE_SHA1],,[Define to 1 to use the Steve Reid's public-domain SHA-1 code.])])])])])
+ # Checks for header files.
+ AC_HEADER_DIRENT
+@@ -32,6 +32,10 @@
+ AC_FUNC_MEMCMP
+ AC_TYPE_SIGNAL
+ AC_FUNC_STAT
+-AC_CHECK_FUNCS([ftruncate gethostbyname gettimeofday getwd inet_ntoa memchr memmove memset mkdir select socket strchr strerror strncasecmp strstr strtol strnstr])
++AC_CHECK_FUNCS([ftruncate gethostbyname gettimeofday getwd inet_ntoa memchr memmove memset mkdir select socket strchr strerror strncasecmp strstr strtol strtoll strnstr])
++
++# Enable/check large file support
++AC_SYS_LARGEFILE
++AC_FUNC_FSEEKO
+ AC_OUTPUT(Makefile)
+--- Makefile.in.orig   Wed Sep  8 16:10:51 2004
++++ Makefile.in        Thu Nov 10 20:57:00 2005
+@@ -1,8 +1,8 @@
+-# Makefile.in generated by automake 1.7.6 from Makefile.am.
++# Makefile.in generated by automake 1.9.1 from Makefile.am.
+ # @configure_input@
+-# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+-# Free Software Foundation, Inc.
++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
++# 2003, 2004  Free Software Foundation, Inc.
+ # This Makefile.in is free software; the Free Software Foundation
+ # gives unlimited permission to copy and/or distribute it,
+ # with or without modifications, as long as this notice is preserved.
+@@ -14,6 +14,8 @@
+ @SET_MAKE@
++SOURCES = $(ctorrent_SOURCES)
++
+ srcdir = @srcdir@
+ top_srcdir = @top_srcdir@
+ VPATH = @srcdir@
+@@ -21,7 +23,6 @@
+ pkglibdir = $(libdir)/@PACKAGE@
+ pkgincludedir = $(includedir)/@PACKAGE@
+ top_builddir = .
+-
+ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+ INSTALL = @INSTALL@
+ install_sh_DATA = $(install_sh) -c -m 644
+@@ -35,6 +36,61 @@
+ NORMAL_UNINSTALL = :
+ PRE_UNINSTALL = :
+ POST_UNINSTALL = :
++bin_PROGRAMS = ctorrent$(EXEEXT)
++subdir = .
++DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
++      $(srcdir)/Makefile.in $(srcdir)/config.h.in \
++      $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
++      depcomp install-sh missing mkinstalldirs
++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
++am__aclocal_m4_deps = $(top_srcdir)/configure.ac
++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
++      $(ACLOCAL_M4)
++am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
++ configure.lineno configure.status.lineno
++mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++CONFIG_HEADER = config.h
++CONFIG_CLEAN_FILES =
++am__installdirs = "$(DESTDIR)$(bindir)"
++binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
++PROGRAMS = $(bin_PROGRAMS)
++am_ctorrent_OBJECTS = bencode.$(OBJEXT) bitfield.$(OBJEXT) \
++      btconfig.$(OBJEXT) btcontent.$(OBJEXT) btfiles.$(OBJEXT) \
++      btrequest.$(OBJEXT) btstream.$(OBJEXT) bufio.$(OBJEXT) \
++      connect_nonb.$(OBJEXT) ctcs.$(OBJEXT) ctorrent.$(OBJEXT) \
++      downloader.$(OBJEXT) httpencode.$(OBJEXT) iplist.$(OBJEXT) \
++      peer.$(OBJEXT) peerlist.$(OBJEXT) rate.$(OBJEXT) \
++      setnonblock.$(OBJEXT) sigint.$(OBJEXT) tracker.$(OBJEXT) \
++      sha1.$(OBJEXT)
++ctorrent_OBJECTS = $(am_ctorrent_OBJECTS)
++ctorrent_LDADD = $(LDADD)
++DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
++depcomp = $(SHELL) $(top_srcdir)/depcomp
++am__depfiles_maybe = depfiles
++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
++      $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
++CCLD = $(CC)
++LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
++CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
++      $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
++CXXLD = $(CXX)
++CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
++      -o $@
++SOURCES = $(ctorrent_SOURCES)
++DIST_SOURCES = $(ctorrent_SOURCES)
++ETAGS = etags
++CTAGS = ctags
++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
++distdir = $(PACKAGE)-$(VERSION)
++top_distdir = $(distdir)
++am__remove_distdir = \
++  { test ! -d $(distdir) \
++    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
++         && rm -fr $(distdir); }; }
++DIST_ARCHIVES = $(distdir).tar.gz
++GZIP_ENV = --best
++distuninstallcheck_listfiles = find . -type f -print
++distcleancheck_listfiles = find . -type f -print
+ ACLOCAL = @ACLOCAL@
+ AMDEP_FALSE = @AMDEP_FALSE@
+ AMDEP_TRUE = @AMDEP_TRUE@
+@@ -90,6 +146,8 @@
+ am__include = @am__include@
+ am__leading_dot = @am__leading_dot@
+ am__quote = @am__quote@
++am__tar = @am__tar@
++am__untar = @am__untar@
+ bindir = @bindir@
+ build_alias = @build_alias@
+ datadir = @datadir@
+@@ -102,6 +160,7 @@
+ libexecdir = @libexecdir@
+ localstatedir = @localstatedir@
+ mandir = @mandir@
++mkdir_p = @mkdir_p@
+ oldincludedir = @oldincludedir@
+ prefix = @prefix@
+ program_transform_name = @program_transform_name@
+@@ -109,76 +168,44 @@
+ sharedstatedir = @sharedstatedir@
+ sysconfdir = @sysconfdir@
+ target_alias = @target_alias@
+-bin_PROGRAMS = ctorrent
+-ctorrent_SOURCES = bencode.cpp bitfield.cpp btconfig.cpp btcontent.cpp btfiles.cpp btrequest.cpp btstream.cpp bufio.cpp connect_nonb.cpp ctorrent.cpp downloader.cpp httpencode.cpp iplist.cpp peer.cpp peerlist.cpp rate.cpp setnonblock.cpp sigint.cpp tracker.cpp bencode.h bitfield.h btconfig.h btcontent.h btfiles.h btrequest.h btstream.h bufio.h connect_nonb.h def.h downloader.h httpencode.h iplist.h msgencode.h peer.h peerlist.h rate.h setnonblock.h sigint.h tracker.h
+-subdir = .
+-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+-CONFIG_HEADER = config.h
+-CONFIG_CLEAN_FILES =
+-bin_PROGRAMS = ctorrent$(EXEEXT)
+-PROGRAMS = $(bin_PROGRAMS)
+-
+-am_ctorrent_OBJECTS = bencode.$(OBJEXT) bitfield.$(OBJEXT) \
+-      btconfig.$(OBJEXT) btcontent.$(OBJEXT) btfiles.$(OBJEXT) \
+-      btrequest.$(OBJEXT) btstream.$(OBJEXT) bufio.$(OBJEXT) \
+-      connect_nonb.$(OBJEXT) ctorrent.$(OBJEXT) downloader.$(OBJEXT) \
+-      httpencode.$(OBJEXT) iplist.$(OBJEXT) peer.$(OBJEXT) \
+-      peerlist.$(OBJEXT) rate.$(OBJEXT) setnonblock.$(OBJEXT) \
+-      sigint.$(OBJEXT) tracker.$(OBJEXT)
+-ctorrent_OBJECTS = $(am_ctorrent_OBJECTS)
+-ctorrent_LDADD = $(LDADD)
+-ctorrent_DEPENDENCIES =
+-ctorrent_LDFLAGS =
+-
+-DEFAULT_INCLUDES =  -I. -I$(srcdir) -I.
+-depcomp = $(SHELL) $(top_srcdir)/depcomp
+-am__depfiles_maybe = depfiles
+-@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/bencode.Po ./$(DEPDIR)/bitfield.Po \
+-@AMDEP_TRUE@  ./$(DEPDIR)/btconfig.Po ./$(DEPDIR)/btcontent.Po \
+-@AMDEP_TRUE@  ./$(DEPDIR)/btfiles.Po ./$(DEPDIR)/btrequest.Po \
+-@AMDEP_TRUE@  ./$(DEPDIR)/btstream.Po ./$(DEPDIR)/bufio.Po \
+-@AMDEP_TRUE@  ./$(DEPDIR)/connect_nonb.Po ./$(DEPDIR)/ctorrent.Po \
+-@AMDEP_TRUE@  ./$(DEPDIR)/downloader.Po ./$(DEPDIR)/httpencode.Po \
+-@AMDEP_TRUE@  ./$(DEPDIR)/iplist.Po ./$(DEPDIR)/peer.Po \
+-@AMDEP_TRUE@  ./$(DEPDIR)/peerlist.Po ./$(DEPDIR)/rate.Po \
+-@AMDEP_TRUE@  ./$(DEPDIR)/setnonblock.Po ./$(DEPDIR)/sigint.Po \
+-@AMDEP_TRUE@  ./$(DEPDIR)/tracker.Po
+-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+-      $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+-CXXLD = $(CXX)
+-CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+-      -o $@
+-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+-      $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+-CCLD = $(CC)
+-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+-DIST_SOURCES = $(ctorrent_SOURCES)
+-DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
+-      Makefile.in NEWS aclocal.m4 config.h.in configure configure.ac \
+-      depcomp install-sh missing mkinstalldirs
+-SOURCES = $(ctorrent_SOURCES)
+-
++ctorrent_SOURCES = bencode.cpp bitfield.cpp btconfig.cpp btcontent.cpp btfiles.cpp btrequest.cpp btstream.cpp bufio.cpp connect_nonb.cpp ctcs.cpp ctorrent.cpp downloader.cpp httpencode.cpp iplist.cpp peer.cpp peerlist.cpp rate.cpp setnonblock.cpp sigint.cpp tracker.cpp sha1.c bencode.h bitfield.h btconfig.h btcontent.h btfiles.h btrequest.h btstream.h bufio.h connect_nonb.h ctcs.h def.h downloader.h httpencode.h iplist.h msgencode.h peer.h peerlist.h rate.h setnonblock.h sigint.h tracker.h sha1.h
+ all: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-am
+ .SUFFIXES:
+-.SUFFIXES: .cpp .o .obj
+-
+-am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+- configure.lineno
+-$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.ac $(ACLOCAL_M4)
++.SUFFIXES: .c .cpp .o .obj
++am--refresh:
++      @:
++$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
++      @for dep in $?; do \
++        case '$(am__configure_deps)' in \
++          *$$dep*) \
++            echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
++            cd $(srcdir) && $(AUTOMAKE) --gnu  \
++              && exit 0; \
++            exit 1;; \
++        esac; \
++      done; \
++      echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  Makefile
+-Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+-      cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
++.PRECIOUS: Makefile
++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
++      @case '$?' in \
++        *config.status*) \
++          echo ' $(SHELL) ./config.status'; \
++          $(SHELL) ./config.status;; \
++        *) \
++          echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
++          cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
++      esac;
+-$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+-$(srcdir)/configure:  $(srcdir)/configure.ac $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+-      cd $(srcdir) && $(AUTOCONF)
+-$(ACLOCAL_M4):  configure.ac 
++$(top_srcdir)/configure:  $(am__configure_deps)
++      cd $(srcdir) && $(AUTOCONF)
++$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+ config.h: stamp-h1
+@@ -190,24 +217,23 @@
+ stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+       @rm -f stamp-h1
+       cd $(top_builddir) && $(SHELL) ./config.status config.h
+-
+-$(srcdir)/config.h.in:  $(top_srcdir)/configure.ac $(ACLOCAL_M4) 
++$(srcdir)/config.h.in:  $(am__configure_deps) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+-      touch $(srcdir)/config.h.in
++      rm -f stamp-h1
++      touch $@
+ distclean-hdr:
+       -rm -f config.h stamp-h1
+-binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+ install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+-      $(mkinstalldirs) $(DESTDIR)$(bindir)
++      test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         if test -f $$p \
+         ; then \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+-         echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
+-         $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \
++         echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
++         $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+         else :; fi; \
+       done
+@@ -215,8 +241,8 @@
+       @$(NORMAL_UNINSTALL)
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+-        echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+-        rm -f $(DESTDIR)$(bindir)/$$f; \
++        echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
++        rm -f "$(DESTDIR)$(bindir)/$$f"; \
+       done
+ clean-binPROGRAMS:
+@@ -226,7 +252,7 @@
+       $(CXXLINK) $(ctorrent_LDFLAGS) $(ctorrent_OBJECTS) $(ctorrent_LDADD) $(LIBS)
+ mostlyclean-compile:
+-      -rm -f *.$(OBJEXT) core *.core
++      -rm -f *.$(OBJEXT)
+ distclean-compile:
+       -rm -f *.tab.c
+@@ -240,6 +266,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btstream.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bufio.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connect_nonb.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctcs.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctorrent.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/downloader.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpencode.Po@am__quote@
+@@ -248,43 +275,39 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peerlist.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rate.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setnonblock.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigint.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tracker.Po@am__quote@
+-distclean-depend:
+-      -rm -rf ./$(DEPDIR)
++.c.o:
++@am__fastdepCC_TRUE@  if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
++@am__fastdepCC_TRUE@  then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
++@AMDEP_TRUE@@am__fastdepCC_FALSE@     source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@     DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@ $(COMPILE) -c $<
++
++.c.obj:
++@am__fastdepCC_TRUE@  if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
++@am__fastdepCC_TRUE@  then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
++@AMDEP_TRUE@@am__fastdepCC_FALSE@     source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@     DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+ .cpp.o:
+-@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+-@am__fastdepCXX_TRUE@   -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+-@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+-@am__fastdepCXX_TRUE@ fi
++@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
++@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+ @AMDEP_TRUE@@am__fastdepCXX_FALSE@    source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+-@AMDEP_TRUE@@am__fastdepCXX_FALSE@    depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+-@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+-@am__fastdepCXX_FALSE@        $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
++@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCXX_FALSE@        $(CXXCOMPILE) -c -o $@ $<
+ .cpp.obj:
+-@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+-@am__fastdepCXX_TRUE@   -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+-@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+-@am__fastdepCXX_TRUE@ fi
++@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
++@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+ @AMDEP_TRUE@@am__fastdepCXX_FALSE@    source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+-@AMDEP_TRUE@@am__fastdepCXX_FALSE@    depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+-@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+-@am__fastdepCXX_FALSE@        $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
++@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCXX_FALSE@        $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+ uninstall-info-am:
+-ETAGS = etags
+-ETAGSFLAGS =
+-
+-CTAGS = ctags
+-CTAGSFLAGS =
+-
+-tags: TAGS
+-
+ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+@@ -293,6 +316,7 @@
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
++tags: TAGS
+ TAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+@@ -304,10 +328,11 @@
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+-      test -z "$(ETAGS_ARGS)$$tags$$unique" \
+-        || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+-           $$tags $$unique
+-
++      if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
++        test -n "$$unique" || unique=$$empty_fix; \
++        $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++          $$tags $$unique; \
++      fi
+ ctags: CTAGS
+ CTAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+@@ -330,19 +355,6 @@
+ distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+-
+-top_distdir = .
+-distdir = $(PACKAGE)-$(VERSION)
+-
+-am__remove_distdir = \
+-  { test ! -d $(distdir) \
+-    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+-         && rm -fr $(distdir); }; }
+-
+-GZIP_ENV = --best
+-distuninstallcheck_listfiles = find . -type f -print
+-distcleancheck_listfiles = find . -type f -print
+ distdir: $(DISTFILES)
+       $(am__remove_distdir)
+@@ -358,7 +370,7 @@
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+-          $(mkinstalldirs) "$(distdir)$$dir"; \
++          $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+@@ -379,19 +391,46 @@
+         ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+       || chmod -R a+r $(distdir)
+ dist-gzip: distdir
+-      $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
++      tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
++      $(am__remove_distdir)
++
++dist-bzip2: distdir
++      tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
++      $(am__remove_distdir)
++
++dist-tarZ: distdir
++      tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
++      $(am__remove_distdir)
++
++dist-shar: distdir
++      shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
++      $(am__remove_distdir)
++
++dist-zip: distdir
++      -rm -f $(distdir).zip
++      zip -rq $(distdir).zip $(distdir)
+       $(am__remove_distdir)
+ dist dist-all: distdir
+-      $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
++      tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(am__remove_distdir)
+ # This target untars the dist file and tries a VPATH configuration.  Then
+ # it guarantees that the distribution is self-contained by making another
+ # tarfile.
+ distcheck: dist
+-      $(am__remove_distdir)
+-      GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
++      case '$(DIST_ARCHIVES)' in \
++      *.tar.gz*) \
++        GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
++      *.tar.bz2*) \
++        bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
++      *.tar.Z*) \
++        uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
++      *.shar.gz*) \
++        GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
++      *.zip*) \
++        unzip $(distdir).zip ;;\
++      esac
+       chmod -R a-w $(distdir); chmod a+w $(distdir)
+       mkdir $(distdir)/_build
+       mkdir $(distdir)/_inst
+@@ -411,19 +450,20 @@
+               distuninstallcheck \
+         && chmod -R a-w "$$dc_install_base" \
+         && ({ \
+-             (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \
++             (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+                   distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+             } || { rm -rf "$$dc_destdir"; exit 1; }) \
+         && rm -rf "$$dc_destdir" \
+-        && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
+-        && rm -f $(distdir).tar.gz \
++        && $(MAKE) $(AM_MAKEFLAGS) dist \
++        && rm -rf $(DIST_ARCHIVES) \
+         && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+       $(am__remove_distdir)
+-      @echo "$(distdir).tar.gz is ready for distribution" | \
+-        sed 'h;s/./=/g;p;x;p;x'
++      @(echo "$(distdir) archives ready for distribution: "; \
++        list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
++        sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+ distuninstallcheck:
+       @cd $(distuninstallcheck_dir) \
+       && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+@@ -445,9 +485,10 @@
+ check-am: all-am
+ check: check-am
+ all-am: Makefile $(PROGRAMS) config.h
+-
+ installdirs:
+-      $(mkinstalldirs) $(DESTDIR)$(bindir)
++      for dir in "$(DESTDIR)$(bindir)"; do \
++        test -z "$$dir" || $(mkdir_p) "$$dir"; \
++      done
+ install: install-am
+ install-exec: install-exec-am
+ install-data: install-data-am
+@@ -459,7 +500,7 @@
+ installcheck: installcheck-am
+ install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+-        INSTALL_STRIP_FLAG=-s \
++        install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ mostlyclean-generic:
+@@ -467,7 +508,7 @@
+ clean-generic:
+ distclean-generic:
+-      -rm -f Makefile $(CONFIG_CLEAN_FILES)
++      -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+@@ -478,13 +519,17 @@
+ distclean: distclean-am
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+-distclean-am: clean-am distclean-compile distclean-depend \
+-      distclean-generic distclean-hdr distclean-tags
++      -rm -rf ./$(DEPDIR)
++      -rm -f Makefile
++distclean-am: clean-am distclean-compile distclean-generic \
++      distclean-hdr distclean-tags
+ dvi: dvi-am
+ dvi-am:
++html: html-am
++
+ info: info-am
+ info-am:
+@@ -502,6 +547,8 @@
+ maintainer-clean: maintainer-clean-am
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf $(top_srcdir)/autom4te.cache
++      -rm -rf ./$(DEPDIR)
++      -rm -f Makefile
+ maintainer-clean-am: distclean-am maintainer-clean-generic
+ mostlyclean: mostlyclean-am
+@@ -518,11 +565,12 @@
+ uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+-      clean-generic ctags dist dist-all dist-gzip distcheck distclean \
+-      distclean-compile distclean-depend distclean-generic \
+-      distclean-hdr distclean-tags distcleancheck distdir \
+-      distuninstallcheck dvi dvi-am info info-am install install-am \
++.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
++      clean-binPROGRAMS clean-generic ctags dist dist-all dist-bzip2 \
++      dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
++      distclean-compile distclean-generic distclean-hdr \
++      distclean-tags distcleancheck distdir distuninstallcheck dvi \
++      dvi-am html html-am info info-am install install-am \
+       install-binPROGRAMS install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am install-man \
+       install-strip installcheck installcheck-am installdirs \
+--- bencode.cpp.orig   Wed Sep  8 16:10:51 2004
++++ bencode.cpp        Sun Jan  1 18:38:01 2006
+@@ -1,6 +1,6 @@
++#include "./def.h"
+ #include <sys/types.h>
+-#include "./def.h"
+ #include "bencode.h"
+ #ifndef WINDOWS
+@@ -29,7 +29,7 @@
+   return keylen;
+ }
+-size_t buf_int(const char *b,size_t len,char beginchar,char endchar,size_t *pi)
++size_t buf_long(const char *b,size_t len,char beginchar,char endchar,int64_t *pi)
+ {
+   const char *p = b;
+   const char *psave;
+@@ -46,12 +46,26 @@
+   if(!len || MAX_INT_SIZ < (p - psave) || *p != endchar) return 0;
+   if( pi ){
+-    if( beginchar ) *pi = (size_t)strtol(b + 1,(char**) 0,10);
+-    else  *pi=(size_t)strtol(b,(char**) 0,10);
++    if( beginchar ) *pi = strtoll(b + 1,(char**) 0,10);
++    else  *pi=strtoll(b,(char**) 0,10);
+   }
+   return (size_t)( p - b + 1 );
+ }
++size_t buf_int(const char *b,size_t len,char beginchar,char endchar,size_t *pi)
++{
++  size_t r;
++
++  if( pi ){
++    int64_t pl;
++    r = buf_long(b,len,beginchar,endchar,&pl);
++    *pi = (size_t) pl;
++  }else{
++    r = buf_long(b,len,beginchar,endchar,(int64_t*) 0);
++  }
++  return r;
++}
++
+ size_t buf_str(const char *b,size_t len,const char **pstr,size_t* slen)
+ {
+   size_t rl,sl;
+@@ -69,7 +83,7 @@
+ size_t decode_int(const char *b,size_t len)
+ {
+-  return(buf_int(b,len,'i','e',(size_t*) 0));
++  return(buf_long(b,len,'i','e',(int64_t*) 0));
+ }
+ size_t decode_str(const char *b,size_t len)
+@@ -136,7 +150,7 @@
+   }
+ }
+-size_t decode_query(const char *b,size_t len,const char *keylist,const char **ps,size_t *pi,int method)
++size_t decode_query(const char *b,size_t len,const char *keylist,const char **ps,size_t *pi,int64_t *pl,int method)
+ {
+   size_t pos;
+   char kl[KEYNAME_LISTSIZ];
+@@ -147,8 +161,9 @@
+   case QUERY_STR: return(buf_str(b + pos,len - pos, ps, pi));
+   case QUERY_INT: return(buf_int(b + pos,len - pos, 'i', 'e', pi));
+   case QUERY_POS:
+-        if(pi) *pi = decode_rev(b + pos, len - pos, (const char*) 0);
+-        return pos;
++          if(pi) *pi = decode_rev(b + pos, len - pos, (const char*) 0);
++          return pos;
++  case QUERY_LONG: return(buf_long(b + pos,len - pos, 'i', 'e', pl));
+   default: return 0;
+   }
+ }
+--- bencode.h.orig     Wed Sep  8 16:10:51 2004
++++ bencode.h  Fri Aug 26 20:43:00 2005
+@@ -13,7 +13,9 @@
+ #define QUERY_STR 0
+ #define QUERY_INT 1
+ #define QUERY_POS 2
++#define QUERY_LONG 3
++size_t buf_long(const char *b,size_t len,char beginchar,char endchar,int64_t *pi);
+ size_t buf_int(const char *b,size_t len,char beginchar,char endchar,size_t *pi);
+ size_t buf_str(const char *b,size_t len,const char **pstr,size_t* slen);
+ size_t decode_int(const char *b,size_t len);
+@@ -21,7 +23,7 @@
+ size_t decode_dict(const char *b,size_t len,const char *keylist);
+ size_t decode_list(const char *b,size_t len,const char *keylist);
+ size_t decode_rev(const char *b,size_t len,const char *keylist);
+-size_t decode_query(const char *b,size_t len,const char *keylist,const char **ps,size_t *pi,int method);
++size_t decode_query(const char *b,size_t len,const char *keylist,const char **ps,size_t *pi,int64_t *pl,int method);
+ size_t decode_list2path(const char *b, size_t n, char *pathname);
+ size_t bencode_buf(const char *str,size_t len,FILE *fp);
+ size_t bencode_str(const char *str, FILE *fp);
+--- bitfield.cpp.orig  Wed Sep  8 16:10:51 2004
++++ bitfield.cpp       Mon Nov 21 16:26:52 2005
+@@ -143,8 +143,8 @@
+     size_t s = nset;
+     for( ; i < nbytes - 1; i++ ) b[i] = ~b[i];
+-    if( nbits % nbytes ){
+-      for( i = 8 * (nbytes - 1); i < nbits; i++ ) if( _isset(i) ) UnSet(i); else Set(i);
++    if( nbits % 8 ){
++      for( i = 8 * (nbytes - 1); i < nbits; i++ ) if( _isset(i) ) UnSet(i); else _set(i);
+     }else
+       b[nbytes - 1] = ~b[nbytes - 1];
+@@ -152,6 +152,16 @@
+   }
+ }
++// _set() sets the bit but doesn't increment nset or set the isfull case.
++// Use instead of Set() when you know nset is incorrect and will be corrected
++// afterward (as in Invert or by _recalc),
++// and either bitfield won't get full or you'll _recalc() afterward to fix it.
++void BitField::_set(size_t idx)
++{
++  if( idx < nbits && !_isfull() && !_isset(idx) )
++    b[idx / 8] |= BIT_HEX[idx % 8];
++}
++
+ void BitField::Comb(const BitField &bf)
+ {
+   size_t i;
+@@ -167,7 +177,10 @@
+ {
+    size_t i;
+   char c;
+-  if( bf.nset != 0 ){
++  if( _isfull_sp(bf) ){
++    SetAll();
++    Invert();
++  }else if( bf.nset != 0 ){
+     if( nset >= nbits ){
+       b = new unsigned char[nbytes];
+ #ifndef WINDOWS
+@@ -184,6 +197,26 @@
+   }
+ }
++void BitField::And(const BitField &bf)
++{
++   size_t i;
++
++  if( bf.nset == 0 ){
++    SetAll();
++    Invert();
++  }else if( !_isfull_sp(bf) ){
++    if( nset >= nbits ){
++      b = new unsigned char[nbytes];
++#ifndef WINDOWS
++      if( !b ) throw 9;
++#endif
++      _setall(b);
++    }
++    for(i = 0; i < nbytes; i++) b[i] &= bf.b[i];
++    _recalc();
++  }
++}
++
+ size_t BitField::Random() const
+ {
+    size_t idx;
+@@ -300,3 +333,4 @@
+   fclose(fp);
+   return -1;
+ }
++
+--- bitfield.h.orig    Wed Sep  8 16:10:51 2004
++++ bitfield.h Sat Nov 12 12:58:02 2005
+@@ -14,6 +14,7 @@
+   inline void _recalc();
+   inline void _setall(unsigned char* buf);
++  inline void _set(size_t idx);
+  public:
+   BitField();
+@@ -40,6 +41,7 @@
+   void Comb(const BitField &bf); 
+   void Except(const BitField &bf);
+   void Invert();
++  void And(const BitField &bf);
+   int WriteToFile(const char *fname);
+   int SetReferFile(const char *fname);
+--- btconfig.cpp.orig  Wed Sep  8 16:10:51 2004
++++ btconfig.cpp       Sun Jan  1 18:39:06 2006
+@@ -1,19 +1,23 @@
+ #include <sys/types.h>
+-size_t cfg_req_slice_size = 32768;
++size_t cfg_req_slice_size = 16384;
++size_t cfg_req_queue_length = 74;
+ size_t cfg_cache_size = 16;
+ size_t cfg_max_peers = 100;
+-size_t cfg_min_peers = 40;
++size_t cfg_min_peers = 1;
++unsigned long cfg_listen_ip = 0;
+ int cfg_listen_port = 0;
+ int cfg_max_listen_port = 2706;
+ int cfg_min_listen_port = 2106;
+-int cfg_max_bandwidth = -1;
++int cfg_max_bandwidth_down = -1;
++int cfg_max_bandwidth_up = -1;
+ time_t cfg_seed_hours = 72;
++double cfg_seed_ratio = 0;
+ // arguments global value
+ char *arg_metainfo_file = (char*) 0;
+@@ -25,6 +29,12 @@
+ unsigned char arg_flg_check_only = 0;
+ unsigned char arg_flg_exam_only = 0;
+ unsigned char arg_flg_make_torrent = 0;
++size_t arg_file_to_download = 0;
++unsigned char arg_verbose = 0;
+ size_t arg_piece_length = 262144;
+ char *arg_announce = (char*) 0;
++
++char *arg_ctcs = (char*) 0;
++int cfg_exit_zero_peers = 0;
++
+--- btconfig.h.orig    Wed Sep  8 16:10:51 2004
++++ btconfig.h Sat Jan 14 12:20:10 2006
+@@ -4,24 +4,32 @@
+ extern size_t cfg_req_slice_size;
+ #define MAX_METAINFO_FILESIZ  4194304
+-#define cfg_max_slice_size 131072
+-#define cfg_req_queue_length 64
++// According to specs the max slice size is 128K.  But most clients do not
++// accept a value that large, so we limit to 64K.  Note that there is a
++// comparison in RequestQueue::IsValidRequest() (see btrequest.cpp) that
++// doubles the value so that we will accept a request for 128K.
++#define cfg_max_slice_size 65536
++extern size_t cfg_req_queue_length;
+ #define MAX_PF_LEN 8
+ #define PEER_ID_LEN 20
+-#define PEER_PFX "-CT1304-"
++#define PEER_PFX "-CD0200-"
+ extern size_t cfg_cache_size;
+ extern size_t cfg_max_peers;
+ extern size_t cfg_min_peers;
++extern unsigned long cfg_listen_ip;
+ extern int cfg_listen_port;
+ extern int cfg_max_listen_port;
+ extern int cfg_min_listen_port;
+ extern time_t cfg_seed_hours;
++extern double cfg_seed_ratio;
+ extern int cfg_max_bandwidth;
++extern int cfg_max_bandwidth_down;
++extern int cfg_max_bandwidth_up;
+ // arguments global value
+ extern char *arg_metainfo_file;
+@@ -33,7 +41,12 @@
+ extern unsigned char arg_flg_check_only;
+ extern unsigned char arg_flg_exam_only;
+ extern unsigned char arg_flg_make_torrent;
++extern size_t arg_file_to_download;
++extern unsigned char arg_verbose;
+ extern size_t arg_piece_length;
+ extern char *arg_announce;
++
++extern char *arg_ctcs;
++extern int cfg_exit_zero_peers;
+ #endif
+--- btcontent.cpp.orig Wed Sep  8 16:10:51 2004
++++ btcontent.cpp      Sun Jan  1 18:40:49 2006
+@@ -9,8 +9,12 @@
+ #else
+ #include <unistd.h>
+ #include <sys/param.h>
++#if defined(HAVE_LIBCRYPT) || defined(HAVE_LIBMD) || defined(HAVE_LIBCRYPTO)
++#include <sha.h>
++#elif defined(HAVE_LIBSSL)
+ #include <openssl/sha.h>
+ #endif
++#endif
+ #include <time.h>
+ #include <sys/stat.h>
+@@ -23,10 +27,15 @@
+ #include "bencode.h"
+ #include "peer.h"
+ #include "httpencode.h"
++#include "tracker.h"
++
++#if defined(USE_STANDALONE_SHA1)
++#include "sha1.h"
++#endif
+-#define meta_str(keylist,pstr,pint) decode_query(b,flen,(keylist),(pstr),(pint),QUERY_STR)
+-#define meta_int(keylist,pint) decode_query(b,flen,(keylist),(const char**) 0,(pint),QUERY_INT)
+-#define meta_pos(keylist) decode_query(b,flen,(keylist),(const char**) 0,(size_t*) 0,QUERY_POS)
++#define meta_str(keylist,pstr,pint) decode_query(b,flen,(keylist),(pstr),(pint),(int64_t*) 0,QUERY_STR)
++#define meta_int(keylist,pint) decode_query(b,flen,(keylist),(const char**) 0,(pint),(int64_t*) 0,QUERY_INT)
++#define meta_pos(keylist) decode_query(b,flen,(keylist),(const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_POS)
+ #define CACHE_FIT(ca,roff,rlen)       \
+ (max_u_int64_t((ca)->bc_off,(roff)) <= \
+@@ -38,6 +47,12 @@
+ static void Sha1(char *ptr,size_t len,unsigned char *dm)
+ {
++#if defined(USE_STANDALONE_SHA1)
++  SHA1_CTX context;
++  SHA1Init(&context);
++  SHA1Update(&context,(unsigned char*)ptr,len);
++  SHA1Final(dm,&context);
++#else
+ #ifdef WINDOWS
+   ;
+ #else
+@@ -46,6 +61,7 @@
+   SHA1_Update(&context,(unsigned char*)ptr,len);
+   SHA1_Final(dm,&context);
+ #endif
++#endif
+ }
+ btContent::btContent()
+@@ -53,6 +69,7 @@
+   m_announce = global_piece_buffer = (char*) 0;
+   m_hash_table = (unsigned char *) 0;
+   pBF = (BitField*) 0;
++  pBFilter = (BitField*) 0;
+   m_create_date = m_seed_timestamp = (time_t) 0;
+   time(&m_start_timestamp);
+   m_cache = (BTCACHE*) 0;
+@@ -121,7 +138,8 @@
+     m_piece_length *= 65536;
+   }
+-  if( !m_piece_length || m_piece_length > cfg_req_queue_length * cfg_req_slice_size )
++  // This is really just a sanity check on the piece length to create.
++  if( !m_piece_length || m_piece_length > 4096*1024 )
+     m_piece_length = 262144;
+   
+   m_announce = ann_url;
+@@ -209,26 +227,24 @@
+   if(!meta_int("info|piece length",&m_piece_length)) ERR_RETURN();
+   m_npieces = m_hashtable_length / 20;
+-  if( m_piece_length > cfg_max_slice_size * cfg_req_queue_length ){
+-    fprintf(stderr,"error, piece length too long[%u]. please recompile CTorrent with a larger cfg_max_slice_size in <btconfig.h>.\n", m_piece_length);
+-    ERR_RETURN();
+-  }
++  cfg_req_queue_length = (m_piece_length / cfg_req_slice_size) * 2 - 1;
+   if( m_piece_length < cfg_req_slice_size )
+     cfg_req_slice_size = m_piece_length;
+-  else{
+-    for( ;(m_piece_length / cfg_req_slice_size) >= cfg_req_queue_length; ){
+-      cfg_req_slice_size *= 2;
+-      if( cfg_req_slice_size > cfg_max_slice_size ) ERR_RETURN();
+-    }
+-  }
+   
+   if( m_btfiles.BuildFromMI(b, flen, saveas) < 0) ERR_RETURN();
+   delete []b;
+-  PrintOut();
++  b = (char *)0;
+   
+-  if( arg_flg_exam_only ) return 0;
++  if( arg_flg_exam_only ){
++    PrintOut();
++    return 0;
++  }else{
++    arg_flg_exam_only = 1;
++    PrintOut();
++    arg_flg_exam_only = 0;
++  }
+   if( ( r = m_btfiles.CreateFiles() ) < 0) ERR_RETURN();
+@@ -242,6 +258,17 @@
+   if( !pBF ) ERR_RETURN();
+ #endif
++    //create the file filter
++    pBFilter = new BitField(m_npieces);
++#ifndef WINDOWS
++     if( !pBFilter ) ERR_RETURN();
++#endif
++  if(arg_file_to_download>0){
++    m_btfiles.SetFilter(arg_file_to_download,pBFilter,m_piece_length);
++  }
++
++
++
+   m_left_bytes = m_btfiles.GetTotalLength() / m_piece_length;
+   if( m_btfiles.GetTotalLength() % m_piece_length ) m_left_bytes++;
+   if( m_left_bytes != m_npieces ) ERR_RETURN();
+@@ -252,13 +279,13 @@
+     if( !arg_flg_check_only ){
+       if( pBF->SetReferFile(arg_bitfield_file) >= 0){
+-      size_t idx;
+-      r = 0;
+-      for( idx = 0; idx < m_npieces; idx++ )
+-        if( pBF->IsSet(idx) ) m_left_bytes -= GetPieceLength(idx);
++        size_t idx;
++        r = 0;
++        for( idx = 0; idx < m_npieces; idx++ )
++          if( pBF->IsSet(idx) ) m_left_bytes -= GetPieceLength(idx);
+       }
+       else{
+-      fprintf(stderr,"warn, couldn't set bit field refer file %s.\n",arg_bitfield_file);
++        fprintf(stderr,"warn, couldn't set bit field refer file %s.\n",arg_bitfield_file);
+       }
+     }
+     
+@@ -271,7 +298,9 @@
+     CheckExist();
+   }
+   
+-  printf("Already/Total: %u/%u\n",pBF->Count(),m_npieces);
++  PrintOut();
++  printf("Already/Total: %u/%u (%d%%)\n",pBF->Count(),m_npieces,
++    100 * pBF->Count() / m_npieces);
+   
+   if( arg_flg_check_only ){
+     if( arg_bitfield_file ) pBF->WriteToFile(arg_bitfield_file);
+@@ -285,11 +314,11 @@
+   memset(ptr,0,8);            // reserved set zero.
+   {                           // peer id
+-      char *sptr = arg_user_agent;
+-      char *dptr = (char *)m_shake_buffer + 48;
+-      char *eptr = dptr + PEER_ID_LEN;
+-      while (*sptr) *dptr++ = *sptr++;
+-      while (dptr < eptr) *dptr++ = (unsigned char)random();
++        char *sptr = arg_user_agent;
++        char *dptr = (char *)m_shake_buffer + 48;
++        char *eptr = dptr + PEER_ID_LEN;
++        while (*sptr) *dptr++ = *sptr++;
++        while (dptr < eptr) *dptr++ = (unsigned char)random();
+   }
+   return 0;
+ }
+@@ -309,7 +338,8 @@
+ ssize_t btContent::ReadSlice(char *buf,size_t idx,size_t off,size_t len)
+ {
+-  u_int64_t offset = idx * m_piece_length + off;
++  //changed
++  u_int64_t offset = (u_int64_t)idx * (u_int64_t)m_piece_length + (u_int64_t)off;
+   if( !m_cache_size ) return m_btfiles.IO(buf, offset, len, 0);
+   else{
+@@ -322,16 +352,16 @@
+     for( ; len && p && CACHE_FIT(p, offset, len);){
+       flg_rescan = 0;
+       if( offset < p->bc_off ){
+-      len2 = p->bc_off - offset;
+-      if( CacheIO(buf, offset, len2, 0) < 0) return -1;
+-      flg_rescan = 1;
++        len2 = p->bc_off - offset;
++        if( CacheIO(buf, offset, len2, 0) < 0) return -1;
++        flg_rescan = 1;
+       }else if( offset > p->bc_off ){
+-      len2 = p->bc_off + p->bc_len - offset;
+-      if( len2 > len ) len2 = len;
+-      memcpy(buf, p->bc_buf + offset - p->bc_off, len2);
++        len2 = p->bc_off + p->bc_len - offset;
++        if( len2 > len ) len2 = len;
++        memcpy(buf, p->bc_buf + offset - p->bc_off, len2);
+       }else{
+-      len2 = (len > p->bc_len) ? p->bc_len : len;
+-      memcpy(buf, p->bc_buf, len2);
++        len2 = (len > p->bc_len) ? p->bc_len : len;
++        memcpy(buf, p->bc_buf, len2);
+       }
+       buf += len2;
+@@ -339,14 +369,14 @@
+       len -= len2;
+       if( len ){
+-      if( flg_rescan ){
+-        for( p = m_cache;
+-             p && (offset + len) > p->bc_off && !CACHE_FIT(p,offset,len);
+-             p = p->bc_next) ;
+-      }else{
+-        time(&p->bc_last_timestamp);
+-        p = p->bc_next;
+-      }
++        if( flg_rescan ){
++          for( p = m_cache;
++               p && (offset + len) > p->bc_off && !CACHE_FIT(p,offset,len);
++               p = p->bc_next) ;
++        }else{
++          time(&p->bc_last_timestamp);
++          p = p->bc_next;
++        }
+       }
+     }// end for;
+   
+@@ -399,13 +429,17 @@
+     if( p->bc_f_flush ){
+       p->bc_f_flush = 0;
+       if(m_btfiles.IO(p->bc_buf, p->bc_off, p->bc_len, 1) < 0)
+-      fprintf(stderr,"warn, write file failed while flush cache.\n");
++        fprintf(stderr,"warn, write file failed while flush cache.\n");
+     }
+ }
+ ssize_t btContent::WriteSlice(char *buf,size_t idx,size_t off,size_t len)
+ {
+-  u_int64_t offset = (u_int64_t)(idx * m_piece_length + off);
++  //u_int64_t offset = (u_int64_t)(idx * m_piece_length + off);
++  //changed
++  u_int64_t offset = (u_int64_t)idx * (u_int64_t)m_piece_length + (u_int64_t)off;
++
++  //  printf("\nOffset-write: %lu - Piece:%lu\n",offset,(unsigned long)idx);
+   if( !m_cache_size ) return m_btfiles.IO(buf, offset, len, 1);
+   else{
+@@ -418,18 +452,18 @@
+     for( ; len && p && CACHE_FIT(p, offset, len);){
+       flg_rescan = 0;
+       if( offset < p->bc_off ){
+-      len2 = p->bc_off - offset;
+-      if( CacheIO(buf, offset, len2, 1) < 0) return -1;
+-      flg_rescan = 1;
++        len2 = p->bc_off - offset;
++        if( CacheIO(buf, offset, len2, 1) < 0) return -1;
++        flg_rescan = 1;
+       }else if( offset > p->bc_off ){
+-      len2 = p->bc_off + p->bc_len - offset;
+-      if( len2 > len ) len2 = len;
+-      memcpy(p->bc_buf + offset - p->bc_off, buf, len2);
+-      p->bc_f_flush = 1;
++        len2 = p->bc_off + p->bc_len - offset;
++        if( len2 > len ) len2 = len;
++        memcpy(p->bc_buf + offset - p->bc_off, buf, len2);
++        p->bc_f_flush = 1;
+       }else{
+-      len2 = (len > p->bc_len) ? p->bc_len : len;
+-      memcpy(p->bc_buf, buf, len2);
+-      p->bc_f_flush = 1;
++        len2 = (len > p->bc_len) ? p->bc_len : len;
++        memcpy(p->bc_buf, buf, len2);
++        p->bc_f_flush = 1;
+       }
+       buf += len2;
+@@ -437,12 +471,12 @@
+       len -= len2;
+       if( len ){
+-      if( flg_rescan ){
+-        for( p = m_cache; p && (offset + len) > p->bc_off && !CACHE_FIT(p,offset,len); p = p->bc_next) ;
+-      }else{
+-        time(&p->bc_last_timestamp);
+-        p = p->bc_next;
+-      }
++        if( flg_rescan ){
++          for( p = m_cache; p && (offset + len) > p->bc_off && !CACHE_FIT(p,offset,len); p = p->bc_next) ;
++        }else{
++          time(&p->bc_last_timestamp);
++          p = p->bc_next;
++        }
+       }
+     }// end for;
+   
+@@ -514,12 +548,12 @@
+   if( !percent ) percent = 1;
+   for( ; idx < m_npieces; idx++){
+-    if( GetHashValue(idx, md) == 0 && memcmp(md, m_hash_table + idx * 20, 20) == 0){
+-      m_left_bytes -= GetPieceLength(idx);
+-      pBF->Set(idx);
++     if( GetHashValue(idx, md) == 0 && memcmp(md, m_hash_table + idx * 20, 20) == 0){
++       m_left_bytes -= GetPieceLength(idx);
++       pBF->Set(idx);
+     }
+-    if(idx % percent == 0){
+-      printf("\rCheck exist: %d/%d",idx,pBF->NBits());
++    if(idx % percent == 0 || idx == m_npieces-1){
++      printf("\rCheck exist: %d/%d",idx+1,pBF->NBits());
+       fflush(stdout);
+     }
+   }
+@@ -575,7 +609,6 @@
+     fprintf(stderr,"warn,piece %d hash check failed.\n",idx);
+     return 0;
+   }
+-
+   pBF->Set(idx);
+   m_left_bytes -= GetPieceLength(idx);
+   return 1;
+@@ -590,8 +623,10 @@
+ int btContent::SeedTimeout(const time_t *pnow)
+ {
++  u_int64_t dl;
+   if( pBF->IsFull() ){
+     if( !m_seed_timestamp ){
++      Tracker.Reset(1);
+       Self.ResetDLTimer();
+       Self.ResetULTimer();
+       ReleaseHashTable();
+@@ -599,9 +634,27 @@
+       FlushCache();
+       printf("\nDownload complete.\n");
+       printf("Total time used: %lu minutes.\n",(*pnow - m_start_timestamp) / 60);
+-      printf("Seed for other %lu hours.\n\n", cfg_seed_hours);
++      printf("Seed for other %lu hours", cfg_seed_hours);
++      if(cfg_seed_ratio) printf(" or to ratio of %f", cfg_seed_ratio);
++      printf(".\n\n");
+     }
+-    if( (*pnow - m_seed_timestamp) >= (cfg_seed_hours * 60 * 60) ) return 1;
++    dl = (Self.TotalDL() > 0) ? Self.TotalDL() : GetTotalFilesLength();
++    if( (cfg_seed_ratio == 0 && cfg_seed_hours == 0) ||
++        (cfg_seed_hours > 0 &&
++          (*pnow - m_seed_timestamp) >= (cfg_seed_hours * 60 * 60)) ||
++        (cfg_seed_ratio > 0 &&
++          cfg_seed_ratio <= Self.TotalUL() / dl) ) return 1;
+   }
+   return 0;
+ }
++
++
++size_t btContent::getFilePieces(size_t nfile){
++   return m_btfiles.getFilePieces(nfile);
++}
++
++
++void btContent::SetFilter(){
++  m_btfiles.SetFilter(arg_file_to_download,pBFilter,m_piece_length);
++}
++
+--- btcontent.h.orig   Wed Sep  8 16:10:51 2004
++++ btcontent.h        Sun Nov 27 21:58:31 2005
+@@ -1,9 +1,8 @@
+ #ifndef BTCONTENT_H
+ #define BTCONTENT_H
+-#include <sys/types.h>
+-
+ #include "def.h"
++#include <sys/types.h>
+ #include <stdio.h>
+ #include "bitfield.h"
+@@ -60,6 +59,7 @@
+   
+  public:
+   BitField *pBF;
++  BitField *pBFilter;
+   char *global_piece_buffer;
+   
+   btContent();
+@@ -93,6 +93,15 @@
+   int PrintOut();
+   int SeedTimeout(const time_t *pnow);
++
++
++  void SetFilter();
++  void SetTmpFilter(int nfile, BitField *pFilter) { m_btfiles.SetFilter(nfile, pFilter, m_piece_length); }
++  size_t getFilePieces(size_t nfile);
++
++  BTFILE *GetNextFile(BTFILE *file) { return m_btfiles.GetNextFile(file); }
++  time_t GetStartTime() { return m_start_timestamp; }
++  time_t GetSeedTime() { return m_seed_timestamp; }
+ };
+ extern btContent BTCONTENT;
+--- btfiles.cpp.orig   Wed Sep  8 16:10:51 2004
++++ btfiles.cpp        Sun Jan  1 18:41:21 2006
+@@ -8,8 +8,12 @@
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <sys/param.h>
++#if defined(HAVE_LIBCRYPT) || defined(HAVE_LIBMD) || defined(HAVE_LIBCRYPTO)
++#include <sha.h>
++#elif defined(HAVE_LIBSSL)
+ #include <openssl/sha.h>
+ #endif
++#endif
+ #include <time.h>
+ #include <sys/stat.h>
+@@ -19,6 +23,9 @@
+ #include <errno.h>
+ #include "bencode.h"
++#include "btconfig.h"
++#include "btcontent.h"
++#include "bitfield.h"
+ #define MAX_OPEN_FILES 20
+@@ -66,7 +73,7 @@
+     for(pbf_n = m_btfhead; pbf_n ; pbf_n = pbf_n->bf_next){
+       if(!pbf_n->bf_flag_opened) continue; // file not been opened.
+       if( !pbf_close || pbf_n->bf_last_timestamp < pbf_close->bf_last_timestamp) 
+-      pbf_close = pbf_n;
++        pbf_close = pbf_n;
+     }
+     if(!pbf_close || fclose(pbf_close->bf_fp) < 0) return -1;
+     pbf_close->bf_flag_opened = 0;
+@@ -90,7 +97,7 @@
+ ssize_t btFiles::IO(char *buf, u_int64_t off, size_t len, const int iotype)
+ {
+   u_int64_t n = 0;
+-  size_t pos,nio;
++  off_t pos,nio;
+   BTFILE *pbf = m_btfhead;
+   if( ( off + (u_int64_t)len ) > m_total_files_length) return -1;
+@@ -102,16 +109,21 @@
+   if( !pbf ) return -1;
+-  pos = (size_t) (off - (n - pbf->bf_length));
++  pos = off - (n - pbf->bf_length);
+   for(; len ;){
++
+     if( !pbf->bf_flag_opened ){
+       if( _btf_open(pbf) < 0 ) return -1;
+     }
+     if( m_flag_automanage ) time(&pbf->bf_last_timestamp);
++#ifdef HAVE_FSEEKO
++    if( fseeko(pbf->bf_fp,pos,SEEK_SET) < 0) return -1;
++#else
+     if( fseek(pbf->bf_fp,(long) pos,SEEK_SET) < 0) return -1;
++#endif
+     nio = (len < pbf->bf_length - pos) ? len : (pbf->bf_length - pos);
+@@ -119,6 +131,7 @@
+       if( 1 != fread(buf,nio,1,pbf->bf_fp) ) return -1;
+     }else{
+       if( 1 != fwrite(buf,nio,1,pbf->bf_fp) ) return -1;
++      fflush(pbf->bf_fp);
+     }
+     len -= nio;
+@@ -149,14 +162,19 @@
+   return 0;
+ }
+-int btFiles::_btf_ftruncate(int fd,size_t length)
++int btFiles::_btf_ftruncate(int fd,int64_t length)
+ {
+ #ifdef WINDOWS
+   char c = (char)0;
+   if(lseek(fd,length - 1, SEEK_SET) < 0 ) return -1;
+   return write(fd, &c, 1);
+ #else
+-  return ftruncate(fd,length);
++  // ftruncate() not allowed on [v]fat under linux
++  if( ftruncate(fd,length) < 0 ) {
++    char c = (char)0;
++    if(lseek(fd,length - 1, SEEK_SET) < 0 ) return -1;
++    return write(fd, &c, 1);
++  }
+ #endif
+ }
+@@ -169,7 +187,7 @@
+   DIR *dp;
+   BTFILE *pbf;
+-  if( !getwd(full_cur) ) return -1;
++  if( !getcwd(full_cur,MAXPATHLEN) ) return -1;
+   if( cur_path ){
+     strcpy(fn, full_cur);
+@@ -185,12 +203,12 @@
+   while( (struct dirent*) 0 != (dirp = readdir(dp)) ){
+     
+     if( 0 == strcmp(dirp->d_name, ".") ||
+-      0 == strcmp(dirp->d_name, "..") ) continue;
++        0 == strcmp(dirp->d_name, "..") ) continue;
+     if( cur_path ){
+       if(MAXPATHLEN < snprintf(fn, MAXPATHLEN, "%s%c%s", cur_path, PATH_SP, dirp->d_name)){
+-      fprintf(stderr,"error, pathname too long\n");
+-      return -1;
++        fprintf(stderr,"error, pathname too long\n");
++        return -1;
+       }
+     }else{
+       strcpy(fn, dirp->d_name);
+@@ -232,7 +250,7 @@
+   return 0;
+ }
+-int btFiles::_btf_creat_by_path(const char *pathname, size_t file_length)
++int btFiles::_btf_creat_by_path(const char *pathname, int64_t file_length)
+ {
+   struct stat sb;
+   int fd;
+@@ -251,17 +269,17 @@
+     *p = '\0';
+     if(stat(sp,&sb) < 0){
+       if( ENOENT == errno ){
+-      if( !last ){
++        if( !last ){
+ #ifdef WINDOWS
+-        if(mkdir(sp) < 0) break;
++          if(mkdir(sp) < 0) break;
+ #else
+-        if(mkdir(sp,0755) < 0) break;
++          if(mkdir(sp,0755) < 0) break;
+ #endif
+-      }else{
+-        if((fd = creat(sp,0644)) < 0) { last = 0; break; }
+-        if(file_length && _btf_ftruncate(fd, file_length) < 0){close(fd); last = 0; break;}
+-        close(fd);
+-      }
++        }else{
++          if((fd = creat(sp,0644)) < 0) { last = 0; break; }
++          if(file_length && _btf_ftruncate(fd, file_length) < 0){close(fd); last = 0; break;}
++          close(fd);
++        }
+       }else{last = 0; break;}
+     }
+     if( !last ){ *p = PATH_SP; pnext = p + 1;}
+@@ -293,7 +311,7 @@
+     m_btfhead = pbf;
+   }else if( S_IFDIR & sb.st_mode ){
+     char wd[MAXPATHLEN];
+-    if( !getwd(wd) ) return -1;
++    if( !getcwd(wd,MAXPATHLEN) ) return -1;
+     m_directory = new char[strlen(pathname) + 1];
+ #ifndef WINDOWS
+     if( !m_directory ) return -1;
+@@ -319,20 +337,21 @@
+   char path[MAXPATHLEN];
+   const char *s, *p;
+   size_t r,q,n;
+-  if( !decode_query(metabuf, metabuf_len, "info|name",&s,&q,QUERY_STR) ||
++  int64_t t;
++  if( !decode_query(metabuf, metabuf_len, "info|name",&s,&q,(int64_t*) 0,QUERY_STR) ||
+       MAXPATHLEN <= q) return -1;
+   memcpy(path, s, q);
+   path[q] = '\0';
+-  r = decode_query(metabuf,metabuf_len,"info|files",(const char**) 0, &q,QUERY_POS);
++  r = decode_query(metabuf,metabuf_len,"info|files",(const char**) 0, &q,(int64_t*) 0,QUERY_POS);
+   if( r ){
+     BTFILE *pbf_last = (BTFILE*) 0; 
+     BTFILE *pbf = (BTFILE*) 0;
+     size_t dl;
+     if( decode_query(metabuf,metabuf_len,"info|length",
+-                   (const char**) 0,(size_t*) 0,QUERY_INT) )
++                    (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) )
+       return -1;
+     if( saveas ){
+@@ -355,14 +374,14 @@
+     for(; q && 'e' != *p; p += dl, q -= dl){
+       if(!(dl = decode_dict(p, q, (const char*) 0)) ) return -1;
+       if( !decode_query(p, dl, "length", (const char**) 0,
+-                      &r,QUERY_INT) ) return -1;
++                       (size_t*) 0,&t,QUERY_LONG) ) return -1;
+       pbf = _new_bfnode();
+ #ifndef WINDOWS
+       if( !pbf ) return -1;
+ #endif
+-      pbf->bf_length = r;
+-      m_total_files_length += r;
+-      r = decode_query(p, dl, "path", (const char **) 0, &n,QUERY_POS);
++      pbf->bf_length = t;
++      m_total_files_length += t;
++      r = decode_query(p, dl, "path", (const char **) 0, &n,(int64_t*) 0,QUERY_POS);
+       if( !r ) return -1;
+       if(!decode_list2path(p + r, n, path)) return -1;
+       pbf->bf_filename = new char[strlen(path) + 1];
+@@ -375,13 +394,13 @@
+     }
+   }else{
+     if( !decode_query(metabuf,metabuf_len,"info|length",
+-                    (const char**) 0,(size_t*) &q,QUERY_INT) )
++                     (const char**) 0,(size_t*) 0,&t,QUERY_LONG) )
+       return -1;
+     m_btfhead = _new_bfnode();
+ #ifndef WINDOWS
+     if( !m_btfhead) return -1;
+ #endif
+-    m_btfhead->bf_length = m_total_files_length = q;
++    m_btfhead->bf_length = m_total_files_length = t;
+     if( saveas ){
+       m_btfhead->bf_filename = new char[strlen(saveas) + 1];
+ #ifndef WINDOWS
+@@ -409,31 +428,31 @@
+   for(; pbt; pbt = pbt->bf_next){
+     if( m_directory ){
+       if( MAXPATHLEN <= snprintf(fn, MAXPATHLEN, "%s%c%s", m_directory, PATH_SP, pbt->bf_filename) )
+-      return -1;
++        return -1;
+     }else{
+       strcpy(fn, pbt->bf_filename);
+     }
+     
+     if(stat(fn ,&sb) < 0){
+       if(ENOENT == errno){
+-      if( !_btf_creat_by_path(fn,pbt->bf_length)){
+-        fprintf(stderr,"error, create file %s failed.\n",fn);
+-        return -1;
+-      }
++        if( !_btf_creat_by_path(fn,pbt->bf_length)){
++          fprintf(stderr,"error, create file %s failed.\n",fn);
++          return -1;
++        }
+       }else{
+-      fprintf(stderr,"error, couldn't create file %s\n", fn);
+-      return -1;
++        fprintf(stderr,"error, couldn't create file %s\n", fn);
++        return -1;
+       }
+     }else{
+       if( !check_exist) check_exist = 1;
+       if( !(S_IFREG & sb.st_mode) ){
+-      fprintf(stderr,"error, file %s not a regular file.\n", fn);
+-      return -1;
++        fprintf(stderr,"error, file %s not a regular file.\n", fn);
++        return -1;
+       }
+       if(sb.st_size != pbt->bf_length){
+-      fprintf(stderr,"error, file %s 's size not match. must be %u\n",
+-              fn, pbt->bf_length);
+-      return -1;
++        fprintf(stderr,"error, file %s 's size not match. must be %u\n",
++                fn, pbt->bf_length);
++        return -1;
+       }
+     }
+   } //end for
+@@ -445,10 +464,21 @@
+   BTFILE *p = m_btfhead;
+   size_t id = 1;
+   printf("FILES INFO\n");
++  BitField tmpBitField, tmpFilter;
+   if(m_directory) printf("Directory: %s\n",m_directory);
+   for( ; p ; p = p->bf_next ){
+-    printf("<%d> %c%s [%u]\n",id++,
+-         m_directory ? '\t': ' ',p->bf_filename, p->bf_length);
++    printf("<%d> %c%s [%llu]",id,
++           m_directory ? '\t': ' ',p->bf_filename, p->bf_length);
++    if( !arg_flg_exam_only ){
++      BTCONTENT.SetTmpFilter(id, &tmpFilter);
++      tmpBitField = *BTCONTENT.pBF;
++      tmpBitField.Except(tmpFilter);
++      printf(" %u/%u (%d%%)",
++        tmpBitField.Count(), BTCONTENT.getFilePieces(id),
++        100 * tmpBitField.Count() / BTCONTENT.getFilePieces(id));
++    }
++    ++id;
++    printf("\n");
+   }
+   printf("Total: %lu MB\n\n",(unsigned long)(m_total_files_length / 1024 / 1024));
+ }
+@@ -488,3 +518,73 @@
+   }
+   return 1;
+ }
++
++
++void btFiles::SetFilter(int nfile, BitField *pFilter,  size_t pieceLength)
++{
++  //set the filter
++
++  BTFILE *p = m_btfhead;
++  size_t id = 1;
++  u_int64_t sizeBuffer=0;
++  size_t index;
++
++
++   pFilter->SetAll();
++     for( ; p ; p = p->bf_next ){
++      if(id++ == nfile){
++        size_t start,stop;
++        start = sizeBuffer/pieceLength;
++        stop  = (sizeBuffer+p->bf_length)/pieceLength;
++        // This "if" cuts down on false prints with CTCS.
++        if(arg_file_to_download == nfile){
++          printf ("\rDownloading file: <%d> %s        \nPieces: %d - %d (%d)\n",nfile,p->bf_filename,start,stop,stop-start+1);
++        }
++        p->bf_npieces = stop-start+1;
++        for(index=sizeBuffer/pieceLength;index<=(sizeBuffer+p->bf_length)/pieceLength;index++){
++          pFilter->UnSet(index);
++        }
++     }
++     sizeBuffer+=(u_int64_t) p->bf_length;
++   }
++    if(nfile>=id || nfile==0){
++      printf("\nEnd of files list. Resuming normal behaviour\n");
++      pFilter->Invert();
++      arg_file_to_download = 0;
++    }
++}
++
++size_t btFiles::getFilePieces(size_t nfile)
++{
++  //returns the pieces of the file already gotten
++
++  BTFILE *p = m_btfhead;
++  size_t id = 1;
++
++     for( ; p ; p = p->bf_next ){
++      if(id++ == nfile){
++        return p->bf_npieces;
++        }
++     }
++return 0;
++}
++
++BTFILE *btFiles::GetNextFile(BTFILE *file)
++{
++  static BTFILE *p = m_btfhead;
++
++  if( 0==file ) p = m_btfhead;
++  else if( p==file ){
++    p = p->bf_next;
++  }else{
++    for( p=m_btfhead; p && (p != file); p = p->bf_next);
++    if( 0==p ){
++      p = m_btfhead;
++    }else{
++      p = p->bf_next;
++    }
++  }
++  return p;
++}
++
++
+--- btfiles.h.orig     Wed Sep  8 16:10:51 2004
++++ btfiles.h  Sun Jan  1 18:41:33 2006
+@@ -1,18 +1,22 @@
+ #ifndef BTFILES_H
+ #define BTFILES_H
++#include "./def.h"
+ #include <sys/types.h>
+ #include <stdio.h>
+-#include "./def.h"
++
++#include "bitfield.h"
+ typedef struct _btfile{
+   char *bf_filename;  // full path of file.
+-  size_t bf_length;           //single file length limits to 4 GB
++  u_int64_t bf_length;
+   FILE *bf_fp;
+   time_t bf_last_timestamp;   // last io timestamp.
+-  size_t bf_completed;                // already downloaded length
++  u_int64_t bf_completed;             // already downloaded length
++
++  size_t bf_npieces;  //number of pieces
+   unsigned char bf_flag_opened:1;
+   unsigned char bf_flag_need:1;
+@@ -36,8 +40,8 @@
+   BTFILE* _new_bfnode();
+   int _btf_open(BTFILE *sbf_p);
+-  int _btf_ftruncate(int fd,size_t length);
+-  int _btf_creat_by_path(const char *pathname, size_t file_length);
++  int _btf_ftruncate(int fd,int64_t length);
++  int _btf_creat_by_path(const char *pathname, int64_t file_length);
+   int _btf_destroy();
+   int _btf_recurses_directory(const char *cur_path, BTFILE *lastnode);
+@@ -53,9 +57,14 @@
+   u_int64_t GetTotalLength() const { return m_total_files_length; }
+   ssize_t IO(char *buf, u_int64_t off, size_t len, const int iotype);
+   size_t FillMetaInfo(FILE* fp);
++
++  void SetFilter(int nfile, BitField *pFilter,size_t pieceLength);
++  size_t getFilePieces(size_t nfile);
++
+ #ifndef WINDOWS
+   void PrintOut();
+ #endif
++  BTFILE *GetNextFile(BTFILE *file);
+ };
+ #endif
+--- btrequest.cpp.orig Wed Sep  8 16:10:51 2004
++++ btrequest.cpp      Sun Jan  1 18:46:17 2006
+@@ -24,24 +24,179 @@
+ RequestQueue::RequestQueue()
+ {
+   rq_head = (PSLICE) 0;
++  rq_send = rq_head;
+ }
+ void RequestQueue::Empty()
+ {
+   if(rq_head) _empty_slice_list(&rq_head);
++  rq_send = rq_head;
+ }
+ void RequestQueue::SetHead(PSLICE ps)
+ {
+   if( rq_head ) _empty_slice_list(&rq_head);
+   rq_head = ps;
++  rq_send = rq_head;
+ }
+ void RequestQueue::operator=(RequestQueue &rq)
+ {
++  PSLICE n, u = (PSLICE) 0;
++  size_t idx;
++  int flag = 0;
++
+   if( rq_head ) _empty_slice_list(&rq_head);
+   rq_head = rq.rq_head;
+-  rq.rq_head = (PSLICE) 0;
++  rq_send = rq_head;
++
++  // Reassign only the first piece represented in the queue.
++  n = rq_head;
++  idx = n->index;
++  for( ; n ; u = n,n = u->next){
++    if( rq.rq_send == n ) flag = 1;
++    if( n->index != idx ) break;
++  }
++  if(n){
++    u->next = (PSLICE) 0;
++    rq.rq_head = n;
++    if(flag) rq.rq_send = rq.rq_head;
++  }else{
++    rq.rq_head = (PSLICE) 0;
++    rq.rq_send = rq.rq_head;
++  }
++}
++
++int RequestQueue::Copy(RequestQueue *prq)
++{
++  PSLICE n, u=(PSLICE)0, ps;
++  size_t idx;
++
++  if( prq->IsEmpty() ) return 0;
++
++  ps = prq->GetHead();
++  idx = ps->index;
++  for ( ; ps; ps = ps->next) {
++    if( ps->index != idx ) break;
++    if( Add(ps->index, ps->offset, ps->length) < 0 ) return -1;
++  }
++  return 0;
++}
++
++int RequestQueue::CopyShuffle(RequestQueue *prq, size_t piece)
++{
++  PSLICE n, u=(PSLICE)0, ps, start;
++  size_t idx;
++  unsigned long rndbits;
++  int i=0;
++
++  if( prq->IsEmpty() ) return 0;
++
++  n = rq_head;
++  for( ; n ; u = n,n = u->next); // move to end
++
++  ps = prq->GetHead();
++  for ( ; ps && ps->index != piece; ps = ps->next);
++  start = ps;
++
++  idx = ps->index;
++
++  // First, skip to the slices that haven't been sent to the original peer.
++  if( prq->rq_send && prq->rq_send->index == idx ){
++    ps = prq->rq_send;
++    for ( ; ps; ps = ps->next){
++      if( ps->index != idx ) break;
++      if( !i-- ){
++        rndbits = random();
++        i = 30;
++      }
++      if( (rndbits>>=1)&01 ){
++        if( Add(ps->index, ps->offset, ps->length) < 0 ) return -1;
++      }
++      else if( Insert(u, ps->index, ps->offset, ps->length) < 0 ) return -1;
++    }
++    if(u) n = u->next;
++    else n = rq_head;
++    for( ; n ; u = n,n = u->next); // move to end
++  }
++
++  // Now put the already-requested slices at the end.
++  ps = start;
++  for ( ; ps && ps != prq->rq_send; ps = ps->next){
++    if( ps->index != idx ) break;
++    if( !i-- ){
++      rndbits = random();
++      i = 30;
++    }
++    if( (rndbits>>=1)&01 ){
++      if( Add(ps->index, ps->offset, ps->length) < 0 ) return -1;
++    }
++    else if( Insert(u, ps->index, ps->offset, ps->length) < 0 ) return -1;
++  }
++  return 0;
++}
++
++// Counts all queued slices.
++size_t RequestQueue::Qsize()
++{
++  size_t cnt = 0;
++  PSLICE n = rq_head;
++  PSLICE u = (PSLICE) 0;
++
++  for( ; n ; u = n,n = u->next) cnt++; // move to end
++  return cnt;
++}
++
++// Counts only slices from one piece.
++size_t RequestQueue::Qlen(size_t piece)
++{
++  size_t cnt = 0;
++  PSLICE n = rq_head;
++  PSLICE u = (PSLICE) 0;
++  size_t idx;
++
++  for ( ; n && n->index != piece; n = n->next);
++
++  if(n) idx = n->index;
++  for( ; n ; u = n,n = u->next){
++    if( n->index != idx ) break;
++    cnt++;
++  }
++  return cnt;
++}
++
++int RequestQueue::Insert(PSLICE ps,size_t idx,size_t off,size_t len)
++{
++  size_t cnt = 0;
++  PSLICE n = rq_head;
++  PSLICE u = (PSLICE) 0;
++
++  for( ; n ; u = n,n = u->next) cnt++; // move to end (count)
++
++  if( cnt >= cfg_req_queue_length ) return -1;        // already full
++
++  n = new SLICE;
++
++#ifndef WINDOWS
++  if( !n ) return -1;
++#endif
++
++  n->index = idx;
++  n->offset = off;
++  n->length = len;
++
++  // ps is the slice to insert after; if 0, insert at the head.
++  if(ps){
++    n->next = ps->next;
++    ps->next = n;
++    if( rq_send == n->next ) rq_send = n;
++  }else{
++    n->next = rq_head;
++    rq_head = n;
++    rq_send = rq_head;
++  }
++
++  return 0;
+ }
+ int RequestQueue::Add(size_t idx,size_t off,size_t len)
+@@ -64,8 +219,33 @@
+   n->index = idx;
+   n->offset = off;
+   n->length = len;
++  n->reqtime = (time_t) 0;
++
++  if( u ) u->next = n;
++  else{
++    rq_head = n;
++    rq_send = rq_head;
++  }
+-  if( u ) u->next = n; else rq_head = n;
++  if( !rq_send ) rq_send = n;
++
++  return 0;
++}
++
++int RequestQueue::Append(PSLICE ps)
++{
++  size_t cnt = 0;
++  PSLICE n = rq_head;
++  PSLICE u = (PSLICE) 0;
++
++  for( ; n ; u = n,n = u->next) cnt++; // move to end
++
++  if( cnt >= cfg_req_queue_length ) return -1;        // already full
++
++  if(u) u->next = ps;
++  else rq_head = ps;
++
++  if( !rq_send ) rq_send = ps;
+   return 0;
+ }
+@@ -82,11 +262,41 @@
+   if( !n ) return -1; /* not found */
+   if( u ) u->next = n->next; else rq_head = n->next;
++  if( rq_send == n ) rq_send = n->next;
+   delete n;
+   return 0;
+ }
++int RequestQueue::HasIdx(size_t idx)
++{
++  PSLICE n = rq_head;
++
++  for( ; n ; n = n->next){
++    if(n->index == idx) break;
++  }
++
++  return n ? 1 : 0;
++}
++
++time_t RequestQueue::GetReqTime(size_t idx,size_t off,size_t len)
++{
++  PSLICE n = rq_head;
++
++  for( ; n ; n = n->next){
++    if(n->index == idx && n->offset == off && n->length == len ) break;
++  }
++
++  if( !n ) return -1; /* not found */
++
++  return n->reqtime;
++}
++
++void RequestQueue::SetReqTime(PSLICE n,time_t t)
++{
++  n->reqtime = t;
++}
++
+ int RequestQueue::Pop(size_t *pidx,size_t *poff,size_t *plen)
+ {
+   PSLICE n;
+@@ -99,6 +309,7 @@
+   if(poff) *poff = rq_head->offset;
+   if(plen) *plen = rq_head->length;
++  if( rq_send == rq_head ) rq_send = n;
+   delete rq_head;
+   rq_head = n;
+@@ -121,8 +332,6 @@
+ {
+   size_t i,off,len,ns;
+   
+-  if( rq_head ) _empty_slice_list(&rq_head);
+-
+   ns = NSlices(idx);
+   for( i = off = 0; i < ns; i++){
+@@ -154,9 +363,11 @@
+ int RequestQueue::IsValidRequest(size_t idx,size_t off,size_t len)
+ {
+   return ( idx < BTCONTENT.GetNPieces() &&
+-         len &&
+-         (off + len) <= BTCONTENT.GetPieceLength(idx) &&
+-         len <= cfg_max_slice_size) ?
++           len &&
++           (off + len) <= BTCONTENT.GetPieceLength(idx) &&
++//         len <= cfg_max_slice_size) ?
++           // See note for cfg_max_slice_size in btconfig.h
++           len <= 2 * cfg_max_slice_size) ?
+     1 : 0;
+ }
+@@ -196,20 +407,51 @@
+ int PendingQueue::Pending(RequestQueue *prq)
+ {
+-   int i = 0;
++   int i = 0, j = 0;
++  PSLICE n, u = (PSLICE) 0;
++  size_t idx, off, len;
++  RequestQueue tmprq;
+   if( pq_count >= PENDING_QUEUE_SIZE ){
+     prq->Empty();
+     return -1;
+   }
++  if( prq->Qlen(prq->GetRequestIdx()) >=
++      BTCONTENT.GetPieceLength() / cfg_req_slice_size ){
++    // This shortcut relies on the fact that we don't add to a queue if it
++    // already contains a full piece.
++    prq->Empty();
++    return 0;
++  }
+-  for( ; i < PENDING_QUEUE_SIZE; i++)
++  for( ; i < PENDING_QUEUE_SIZE; i++){
+     if(pending_array[i] == (PSLICE) 0){
+-      pending_array[i] = prq->GetHead();
+-      prq->Release();
+-      pq_count++;
+-      break;
++      // Don't add a piece to Pending more than once.
++      if(!j) j = i;
++    }else if(prq->GetRequestIdx() == pending_array[i]->index){
++      while( !prq->IsEmpty() &&
++          prq->GetRequestIdx() == pending_array[i]->index )
++        prq->Pop(&idx,&off,&len);
++      if( prq->IsEmpty() ) return 0;
++      i = 0;
+     }
++  }
++  i = j;
++  pending_array[i] = prq->GetHead();
++  prq->Release();
++  pq_count++;
++
++  // If multiple pieces are queued, break up the queue separately.
++  n = pending_array[i];
++  idx = n->index;
++  for( ; n ; u = n, n = u->next)
++    if( n->index != idx ) break;
++  if(n){
++    u->next = (PSLICE) 0;
++    tmprq.SetHead(n);
++    Pending(&tmprq);
++    tmprq.Release();
++  }
+   return 0;
+ }
+@@ -218,16 +460,57 @@
+ {
+    int i = 0;
+   size_t sc = pq_count;
++  size_t idx;
+   for( ; i < PENDING_QUEUE_SIZE && sc; i++){
+     if( pending_array[i] != (PSLICE) 0){
++      if( bf.IsSet(pending_array[i]->index) &&
++          !prq->HasIdx(pending_array[i]->index) ){
++        idx = pending_array[i]->index;
++        prq->Append(pending_array[i]);
++        pending_array[i] = (PSLICE) 0;
++        pq_count--;
++        Delete(idx); // delete any copies from Pending
++        break;
++      }
+       sc--;
+-      if( bf.IsSet(pending_array[i]->index) ){
+-      prq->SetHead(pending_array[i]);
+-      pending_array[i] = (PSLICE) 0;
+-      pq_count--;
+-      break;
++    }
++  }
++  // Return value now indicates whether a piece was assigned.
++  return sc;
++}
++
++// This routine should no longer be necessary, but keeping it as a failsafe.
++int PendingQueue::Delete(size_t idx)
++{
++   int i = 0;
++  for ( ; i < PENDING_QUEUE_SIZE && pq_count; i++){
++    if( (PSLICE) 0 != pending_array[i] && idx == pending_array[i]->index){
++      if(arg_verbose) fprintf(stderr, "PQD found %d\n", (int)idx);
++      _empty_slice_list(&(pending_array[i])); 
++      pq_count--;
++      break;
++    }
++  }
++  return 0;
++}
++
++int PendingQueue::DeleteSlice(size_t idx, size_t off, size_t len)
++{
++   int i = 0;
++   RequestQueue rq;
++  for ( ; i < PENDING_QUEUE_SIZE && pq_count; i++){
++    if( (PSLICE) 0 != pending_array[i] && idx == pending_array[i]->index){
++      //check if off & len match any slice
++      //remove the slice if so
++      rq.SetHead(pending_array[i]);
++      if( rq.Remove(idx, off, len) == 0 ){
++        pending_array[i] = rq.GetHead();
++        if( (PSLICE) 0 == pending_array[i] ) pq_count--;
++        i = PENDING_QUEUE_SIZE;   // exit loop
+       }
++      rq.Release();
+     }
+   }
+   return 0;
+ }
++
+--- btrequest.h.orig   Wed Sep  8 16:10:51 2004
++++ btrequest.h        Sat Dec 24 12:02:30 2005
+@@ -2,6 +2,7 @@
+ #define SLICE_H
+ #include <sys/types.h>
++#include <time.h>
+ #include "btcontent.h"
+ #include "bitfield.h"
+@@ -9,6 +10,7 @@
+    size_t index;
+    size_t offset;
+    size_t length;
++   time_t reqtime;
+    struct _slice *next;
+ }SLICE,*PSLICE;
+@@ -17,6 +19,7 @@
+  private:
+   PSLICE rq_head;
+  public:
++  PSLICE rq_send;  // next slice to request
+   RequestQueue();
+   ~RequestQueue();
+@@ -24,18 +27,30 @@
+   void Empty();
+   void SetHead(PSLICE ps);
++  void SetNextSend(PSLICE ps) { rq_send = ps; }
+   PSLICE GetHead() const { return rq_head; }
++  PSLICE NextSend() const { return rq_send; }
+   size_t GetRequestIdx(){ return rq_head ? rq_head->index : BTCONTENT.GetNPieces(); }
+   size_t GetRequestLen(){ return rq_head ? rq_head->length : 0; }
+-  void Release(){ rq_head = (PSLICE) 0; }
++  void Release(){ rq_head = rq_send = (PSLICE) 0; }
+   int IsValidRequest(size_t idx,size_t off,size_t len);
+   void operator=(RequestQueue &rq);
++  int Copy(RequestQueue *prq);
++  int CopyShuffle(RequestQueue *prq, size_t piece);
++  size_t Qsize();
++  size_t Qlen(size_t piece);
+   int IsEmpty() const { return rq_head ? 0 : 1; }
++  int Insert(PSLICE ps,size_t idx,size_t off,size_t len);
+   int Add(size_t idx,size_t off,size_t len);
++  int Append(PSLICE ps);
+   int Remove(size_t idx,size_t off,size_t len);
++  int HasIdx(size_t idx);
++  time_t GetReqTime(size_t idx,size_t off,size_t len);
++  void SetReqTime(PSLICE n,time_t t);
++
+   int Pop(size_t *pidx,size_t *poff,size_t *plen);
+   int Peek(size_t *pidx,size_t *poff,size_t *plen) const;
+@@ -60,6 +75,8 @@
+   int Pending(RequestQueue *prq);
+   int ReAssign(RequestQueue *prq, BitField &bf);
+   int Exist(size_t idx);
++  int Delete(size_t idx);
++  int DeleteSlice(size_t idx, size_t off, size_t len);
+ };
+ extern PendingQueue PENDINGQUEUE;
+--- btstream.cpp.orig  Wed Sep  8 16:10:51 2004
++++ btstream.cpp       Sun Jan  1 18:46:40 2006
+@@ -1,5 +1,6 @@
+ #include <arpa/inet.h>
+ #include "btstream.h"
++#include "peer.h"
+ #include "msgencode.h"
+ #include "btconfig.h"
+@@ -11,22 +12,21 @@
+ ssize_t btStream::Send_State(unsigned char state)
+ {
+   char msg[H_BASE_LEN + 4];
+-  *(size_t*)msg = htonl(H_BASE_LEN);
++
++  set_nl(msg, H_BASE_LEN);
+   msg[4] = (char)state;
+-  return out_buffer.PutFlush(sock,msg,H_BASE_LEN + 4);
++  return out_buffer.Put(sock,msg,H_BASE_LEN + 4);
+ }
+ ssize_t btStream::Send_Have(size_t idx)
+ {
+   char msg[H_HAVE_LEN + 4];
+-  size_t *p = (size_t*)msg;
+-  *p = htonl(H_HAVE_LEN);
++  set_nl(msg, H_HAVE_LEN);
+   msg[4] = (char)M_HAVE;
+-  p = (size_t*)(msg + 5);
+-  *p = htonl(idx);
++  set_nl(msg + 5, idx);
+-  return out_buffer.PutFlush(sock,msg,H_HAVE_LEN + 4);
++  return out_buffer.Put(sock,msg,H_HAVE_LEN + 4);
+ }
+ ssize_t btStream::Send_Bitfield(char *bit_buf,size_t len)
+@@ -37,20 +37,18 @@
+   if(r < 0) return r;
+   r = out_buffer.Put(sock,(char*)&t,1);
+   if(r < 0) return r;
+-  return out_buffer.PutFlush(sock,bit_buf,len);
++  return out_buffer.Put(sock,bit_buf,len);
+ }
+ ssize_t btStream::Send_Cancel(size_t idx,size_t off,size_t len)
+ {
+   char msg[H_CANCEL_LEN + 4];
+-  size_t *p = (size_t*)msg;
+-  *p = htonl(H_CANCEL_LEN);
++  set_nl(msg, H_CANCEL_LEN);
+   msg[4] = M_CANCEL;
+-  p = (size_t*)(msg + 5);
+-  *p = htonl(idx); p++;
+-  *p = htonl(off); p++;
+-  *p = htonl(len);
++  set_nl(msg + 5, idx);
++  set_nl(msg + 9, off);
++  set_nl(msg + 13, len);
+   return out_buffer.Put(sock,msg,H_CANCEL_LEN + 4);
+ }
+@@ -72,21 +70,19 @@
+ ssize_t btStream::Send_Request(size_t idx, size_t off,size_t len)
+ {
+   char msg[H_REQUEST_LEN + 4];
+-  size_t *p = (size_t*) msg;
+-  *p = htonl(H_REQUEST_LEN);
++  set_nl(msg, H_REQUEST_LEN);
+   msg[4] = (char)M_REQUEST;
+-  p = (size_t*)(msg + 5);
+-  *p = htonl(idx); p++;
+-  *p = htonl(off); p++;
+-  *p = htonl(len);
++  set_nl(msg + 5, idx);
++  set_nl(msg + 9, off);
++  set_nl(msg + 13, len);
+   return out_buffer.Put(sock,msg,H_REQUEST_LEN + 4);
+ }
+ ssize_t btStream::Send_Keepalive()
+ {
+   size_t i = 0;
+-  return out_buffer.PutFlush(sock,(char*)&i,4);
++  return out_buffer.Put(sock,(char*)&i,4);
+ }
+ int btStream::HaveMessage()
+@@ -94,7 +90,7 @@
+   // if message arrived.
+   size_t r;
+   if( 4 <= in_buffer.Count() ){
+-    r = ntohl(*(size_t*)in_buffer.BasePointer());
++    r = get_nl(in_buffer.BasePointer());
+     if( (cfg_max_slice_size + H_PIECE_LEN + 4) < r) return -1; //message too long
+     if( (r + 4) <= in_buffer.Count() ) return 1;
+   }
+@@ -113,5 +109,5 @@
+ ssize_t btStream::Send_Buffer(char *buf, size_t len)
+ {
+-  return out_buffer.PutFlush(sock,buf,len);
++  return out_buffer.Put(sock,buf,len);
+ }
+--- bttime.h.orig      Sun Jan 15 00:28:13 2006
++++ bttime.h   Sun Nov 27 14:52:45 2005
+@@ -0,0 +1,7 @@
++#ifndef BTTIME_H
++#define BTTIME_H
++
++extern time_t now;
++
++#endif
++
+--- bufio.cpp.orig     Wed Sep  8 16:10:51 2004
++++ bufio.cpp  Thu Jan  5 20:49:00 2006
+@@ -61,7 +61,7 @@
+ #ifndef WINDOWS
+       if(errno == EINTR) continue;
+ #endif
+-      return (EWOULDBLOCK == errno) ? (ssize_t)t : -1;
++      return (EWOULDBLOCK == errno || EAGAIN == errno) ? (ssize_t)t : -1;
+     }else if( 0 == r ){
+       return t;                       // no possible???
+     }else{
+@@ -83,7 +83,7 @@
+ #ifndef WINDOWS
+       if(errno == EINTR) continue;
+ #endif
+-      return (EWOULDBLOCK == errno) ? (ssize_t)t : -1;
++      return (EWOULDBLOCK == errno || EAGAIN == errno) ? (ssize_t)t : -1;
+     }else if( 0 == r ){
+       f_socket_remote_closed = 1;
+       return t;               //connection closed by remote.
+--- bufio.h.orig       Wed Sep  8 16:10:51 2004
++++ bufio.h    Mon Nov 21 16:24:43 2005
+@@ -1,8 +1,8 @@
+ #ifndef BUFIO_H
+ #define BUFIO_H
+-#include <sys/types.h>
+ #include "def.h"
++#include <sys/types.h>
+ #ifdef WINDOWS
+ #include <Winsock2.h>
+--- config.h.in.orig   Wed Sep  8 16:10:51 2004
++++ config.h.in        Thu Nov 10 21:00:00 2005
+@@ -10,6 +10,9 @@
+ /* Define to 1 if you have the <fcntl.h> header file. */
+ #undef HAVE_FCNTL_H
++/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
++#undef HAVE_FSEEKO
++
+ /* Define to 1 if you have the `ftruncate' function. */
+ #undef HAVE_FTRUNCATE
+@@ -31,6 +34,9 @@
+ /* Define to 1 if you have the `crypt' library (-lcrypt). */
+ #undef HAVE_LIBCRYPT
++/* Define to 1 if you have the `crypto' library (-lcrypto). */
++#undef HAVE_LIBCRYPTO
++
+ /* Define to 1 if you have the `md' library (-lmd). */
+ #undef HAVE_LIBMD
+@@ -107,6 +113,9 @@
+ /* Define to 1 if you have the `strtol' function. */
+ #undef HAVE_STRTOL
++/* Define to 1 if you have the `strtoll' function. */
++#undef HAVE_STRTOLL
++
+ /* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+    */
+ #undef HAVE_SYS_DIR_H
+@@ -164,15 +173,29 @@
+ /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+ #undef TIME_WITH_SYS_TIME
++/* Define to 1 to use the Steve Reid's public-domain SHA-1 code. */
++#undef USE_STANDALONE_SHA1
++
+ /* Version number of package */
+ #undef VERSION
++/* Number of bits in a file offset, on hosts where this is settable. */
++#undef _FILE_OFFSET_BITS
++
++/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
++#undef _LARGEFILE_SOURCE
++
++/* Define for large files, on AIX-style hosts. */
++#undef _LARGE_FILES
++
+ /* Define to empty if `const' does not conform to ANSI C. */
+ #undef const
+-/* Define as `__inline' if that's what the C compiler calls it, or to nothing
+-   if it is not supported. */
++/* Define to `__inline__' or `__inline' if that's what the C compiler
++   calls it, or to nothing if 'inline' is not supported under any name.  */
++#ifndef __cplusplus
+ #undef inline
++#endif
+ /* Define to `unsigned' if <sys/types.h> does not define. */
+ #undef size_t
+--- configure.orig     Wed Sep  8 16:10:51 2004
++++ configure  Thu Nov 10 20:57:00 2005
+@@ -1,11 +1,10 @@
+ #! /bin/sh
+ # Guess values for system-dependent variables and create Makefiles.
+-# Generated by GNU Autoconf 2.57 for CTorrent devel.
++# Generated by GNU Autoconf 2.59 for CTorrent dnh2.
+ #
+-# Report bugs to <bsdi@sina.com>.
++# Report bugs to <dholmes@ct.boxmail.com>.
+ #
+-# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+-# Free Software Foundation, Inc.
++# Copyright (C) 2003 Free Software Foundation, Inc.
+ # This configure script is free software; the Free Software Foundation
+ # gives unlimited permission to copy, distribute and modify it.
+ ## --------------------- ##
+@@ -22,9 +21,10 @@
+ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+   set -o posix
+ fi
++DUALCASE=1; export DUALCASE # for MKS sh
+ # Support unset when possible.
+-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
++if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+   as_unset=unset
+ else
+   as_unset=false
+@@ -43,7 +43,7 @@
+   LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+   LC_TELEPHONE LC_TIME
+ do
+-  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+     eval $as_var=C; export $as_var
+   else
+     $as_unset $as_var
+@@ -220,16 +220,17 @@
+ if mkdir -p . 2>/dev/null; then
+   as_mkdir_p=:
+ else
++  test -d ./-p && rmdir ./-p
+   as_mkdir_p=false
+ fi
+ as_executable_p="test -f"
+ # Sed expression to map a string onto a valid CPP name.
+-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+ # Sed expression to map a string onto a valid variable name.
+-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+ # IFS
+@@ -268,9 +269,9 @@
+ # Identity of this package.
+ PACKAGE_NAME='CTorrent'
+ PACKAGE_TARNAME='ctorrent'
+-PACKAGE_VERSION='devel'
+-PACKAGE_STRING='CTorrent devel'
+-PACKAGE_BUGREPORT='bsdi@sina.com'
++PACKAGE_VERSION='dnh2'
++PACKAGE_STRING='CTorrent dnh2'
++PACKAGE_BUGREPORT='dholmes@ct.boxmail.com'
+ ac_unique_file="ctorrent.cpp"
+ # Factoring default headers for most tests.
+@@ -310,7 +311,7 @@
+ # include <unistd.h>
+ #endif"
+-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CC CFLAGS ac_ct_CC CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP LIBOBJS LTLIBOBJS'
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CC CFLAGS ac_ct_CC CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP LIBOBJS LTLIBOBJS'
+ ac_subst_files=''
+ # Initialize some variables set by options.
+@@ -669,7 +670,7 @@
+ # Be sure to have absolute paths.
+ for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+-              localstatedir libdir includedir oldincludedir infodir mandir
++            localstatedir libdir includedir oldincludedir infodir mandir
+ do
+   eval ac_val=$`echo $ac_var`
+   case $ac_val in
+@@ -709,10 +710,10 @@
+   # Try the directory containing this script, then its parent.
+   ac_confdir=`(dirname "$0") 2>/dev/null ||
+ $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X"$0" : 'X\(//\)[^/]' \| \
+-         X"$0" : 'X\(//\)$' \| \
+-         X"$0" : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X"$0" : 'X\(//\)[^/]' \| \
++       X"$0" : 'X\(//\)$' \| \
++       X"$0" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X"$0" |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+@@ -787,7 +788,7 @@
+   # Omit some internal or obsolete options to make the list less imposing.
+   # This message is too long to be a string in the A/UX 3.1 sh.
+   cat <<_ACEOF
+-\`configure' configures CTorrent devel to adapt to many kinds of systems.
++\`configure' configures CTorrent dnh2 to adapt to many kinds of systems.
+ Usage: $0 [OPTION]... [VAR=VALUE]...
+@@ -812,9 +813,9 @@
+   cat <<_ACEOF
+ Installation directories:
+   --prefix=PREFIX         install architecture-independent files in PREFIX
+-                          [$ac_default_prefix]
++                        [$ac_default_prefix]
+   --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+-                          [PREFIX]
++                        [PREFIX]
+ By default, \`make install' will install all the files in
+ \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+@@ -849,15 +850,16 @@
+ if test -n "$ac_init_help"; then
+   case $ac_init_help in
+-     short | recursive ) echo "Configuration of CTorrent devel:";;
++     short | recursive ) echo "Configuration of CTorrent dnh2:";;
+    esac
+   cat <<\_ACEOF
+ Optional Features:
+   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+-  --disable-dependency-tracking Speeds up one-time builds
+-  --enable-dependency-tracking  Do not reject slow dependency extractors
++  --disable-dependency-tracking  speeds up one-time build
++  --enable-dependency-tracking   do not reject slow dependency extractors
++  --disable-largefile     omit support for large files
+ Some influential environment variables:
+   CXX         C++ compiler command
+@@ -873,7 +875,7 @@
+ Use these variables to override the choices made by `configure' or to help
+ it to find libraries and programs with nonstandard names/locations.
+-Report bugs to <bsdi@sina.com>.
++Report bugs to <dholmes@ct.boxmail.com>.
+ _ACEOF
+ fi
+@@ -907,12 +909,45 @@
+     ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+     ac_top_srcdir=$ac_top_builddir$srcdir ;;
+ esac
+-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+-# absolute.
+-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
++
++# Do not use `cd foo && pwd` to compute absolute paths, because
++# the directories may not exist.
++case `pwd` in
++.) ac_abs_builddir="$ac_dir";;
++*)
++  case "$ac_dir" in
++  .) ac_abs_builddir=`pwd`;;
++  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
++  *) ac_abs_builddir=`pwd`/"$ac_dir";;
++  esac;;
++esac
++case $ac_abs_builddir in
++.) ac_abs_top_builddir=${ac_top_builddir}.;;
++*)
++  case ${ac_top_builddir}. in
++  .) ac_abs_top_builddir=$ac_abs_builddir;;
++  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
++  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
++  esac;;
++esac
++case $ac_abs_builddir in
++.) ac_abs_srcdir=$ac_srcdir;;
++*)
++  case $ac_srcdir in
++  .) ac_abs_srcdir=$ac_abs_builddir;;
++  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
++  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
++  esac;;
++esac
++case $ac_abs_builddir in
++.) ac_abs_top_srcdir=$ac_top_srcdir;;
++*)
++  case $ac_top_srcdir in
++  .) ac_abs_top_srcdir=$ac_abs_builddir;;
++  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
++  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
++  esac;;
++esac
+     cd $ac_dir
+     # Check for guested configure; otherwise get Cygnus style configure.
+@@ -923,7 +958,7 @@
+       echo
+       $SHELL $ac_srcdir/configure  --help=recursive
+     elif test -f $ac_srcdir/configure.ac ||
+-           test -f $ac_srcdir/configure.in; then
++         test -f $ac_srcdir/configure.in; then
+       echo
+       $ac_configure --help
+     else
+@@ -936,11 +971,10 @@
+ test -n "$ac_init_help" && exit 0
+ if $ac_init_version; then
+   cat <<\_ACEOF
+-CTorrent configure devel
+-generated by GNU Autoconf 2.57
++CTorrent configure dnh2
++generated by GNU Autoconf 2.59
+-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+-Free Software Foundation, Inc.
++Copyright (C) 2003 Free Software Foundation, Inc.
+ This configure script is free software; the Free Software Foundation
+ gives unlimited permission to copy, distribute and modify it.
+ _ACEOF
+@@ -951,8 +985,8 @@
+ This file contains any messages produced by compilers while
+ running configure, to aid debugging if configure makes a mistake.
+-It was created by CTorrent $as_me devel, which was
+-generated by GNU Autoconf 2.57.  Invocation command line was
++It was created by CTorrent $as_me dnh2, which was
++generated by GNU Autoconf 2.59.  Invocation command line was
+   $ $0 $@
+@@ -1029,19 +1063,19 @@
+     2)
+       ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+       if test $ac_must_keep_next = true; then
+-        ac_must_keep_next=false # Got value, back to normal.
++      ac_must_keep_next=false # Got value, back to normal.
+       else
+-        case $ac_arg in
+-          *=* | --config-cache | -C | -disable-* | --disable-* \
+-          | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+-          | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+-          | -with-* | --with-* | -without-* | --without-* | --x)
+-            case "$ac_configure_args0 " in
+-              "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+-            esac
+-            ;;
+-          -* ) ac_must_keep_next=true ;;
+-        esac
++      case $ac_arg in
++        *=* | --config-cache | -C | -disable-* | --disable-* \
++        | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
++        | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
++        | -with-* | --with-* | -without-* | --without-* | --x)
++          case "$ac_configure_args0 " in
++            "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
++          esac
++          ;;
++        -* ) ac_must_keep_next=true ;;
++      esac
+       fi
+       ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+       # Get rid of the leading space.
+@@ -1075,12 +1109,12 @@
+     case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+     *ac_space=\ *)
+       sed -n \
+-        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+-        s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
++      "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
++        s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+       ;;
+     *)
+       sed -n \
+-        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
++      "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+       ;;
+     esac;
+ }
+@@ -1109,7 +1143,7 @@
+       for ac_var in $ac_subst_files
+       do
+       eval ac_val=$`echo $ac_var`
+-        echo "$ac_var='"'"'$ac_val'"'"'"
++      echo "$ac_var='"'"'$ac_val'"'"'"
+       done | sort
+       echo
+     fi
+@@ -1128,7 +1162,7 @@
+       echo "$as_me: caught signal $ac_signal"
+     echo "$as_me: exit $exit_status"
+   } >&5
+-  rm -f core core.* *.core &&
++  rm -f core *.core &&
+   rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+     exit $exit_status
+      ' 0
+@@ -1208,7 +1242,7 @@
+ # value.
+ ac_cache_corrupted=false
+ for ac_var in `(set) 2>&1 |
+-               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
++             sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+   eval ac_old_set=\$ac_cv_env_${ac_var}_set
+   eval ac_new_set=\$ac_env_${ac_var}_set
+   eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+@@ -1225,13 +1259,13 @@
+     ,);;
+     *)
+       if test "x$ac_old_val" != "x$ac_new_val"; then
+-        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
++      { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+ echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+-        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
++      { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+ echo "$as_me:   former value:  $ac_old_val" >&2;}
+-        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
++      { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+ echo "$as_me:   current value: $ac_new_val" >&2;}
+-        ac_cache_corrupted=:
++      ac_cache_corrupted=:
+       fi;;
+   esac
+   # Pass precious variables to config.status.
+@@ -1287,7 +1321,7 @@
+-am__api_version="1.7"
++am__api_version="1.9"
+ ac_aux_dir=
+ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+   if test -f $ac_dir/install-sh; then
+@@ -1324,6 +1358,7 @@
+ # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+ # AFS /usr/afsws/bin/install, which mishandles nonexistent args
+ # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# OS/2's system install, which has a completely different semantic
+ # ./install, which can be erroneously created by make from ./install.sh.
+ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+ echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+@@ -1340,6 +1375,7 @@
+ case $as_dir/ in
+   ./ | .// | /cC/* | \
+   /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
++  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+   /usr/ucb/* ) ;;
+   *)
+     # OSF1 and SCO ODT 3.0 have their own names for install.
+@@ -1347,20 +1383,20 @@
+     # by default.
+     for ac_prog in ginstall scoinst install; do
+       for ac_exec_ext in '' $ac_executable_extensions; do
+-        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+-          if test $ac_prog = install &&
+-            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+-            # AIX install.  It has an incompatible calling convention.
+-            :
+-          elif test $ac_prog = install &&
+-            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+-            # program-specific install script used by HP pwplus--don't use.
+-            :
+-          else
+-            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+-            break 3
+-          fi
+-        fi
++      if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
++        if test $ac_prog = install &&
++          grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++          # AIX install.  It has an incompatible calling convention.
++          :
++        elif test $ac_prog = install &&
++          grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++          # program-specific install script used by HP pwplus--don't use.
++          :
++        else
++          ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
++          break 3
++        fi
++      fi
+       done
+     done
+     ;;
+@@ -1448,7 +1484,6 @@
+ program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+ rm conftest.sed
+-
+ # expand $ac_aux_dir to an absolute path
+ am_aux_dir=`cd $ac_aux_dir && pwd`
+@@ -1462,6 +1497,39 @@
+ echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+ fi
++if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
++  # We used to keeping the `.' as first argument, in order to
++  # allow $(mkdir_p) to be used without argument.  As in
++  #   $(mkdir_p) $(somedir)
++  # where $(somedir) is conditionally defined.  However this is wrong
++  # for two reasons:
++  #  1. if the package is installed by a user who cannot write `.'
++  #     make install will fail,
++  #  2. the above comment should most certainly read
++  #     $(mkdir_p) $(DESTDIR)$(somedir)
++  #     so it does not work when $(somedir) is undefined and
++  #     $(DESTDIR) is not.
++  #  To support the latter case, we have to write
++  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
++  #  so the `.' trick is pointless.
++  mkdir_p='mkdir -p --'
++else
++  # On NextStep and OpenStep, the `mkdir' command does not
++  # recognize any option.  It will interpret all options as
++  # directories to create, and then abort because `.' already
++  # exists.
++  for d in ./-p ./--version;
++  do
++    test -d $d && rmdir $d
++  done
++  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
++  if test -f "$ac_aux_dir/mkinstalldirs"; then
++    mkdir_p='$(mkinstalldirs)'
++  else
++    mkdir_p='$(install_sh) -d'
++  fi
++fi
++
+ for ac_prog in gawk mawk nawk awk
+ do
+   # Extract the first word of "$ac_prog", so it can be a program name with args.
+@@ -1504,7 +1572,7 @@
+ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+ echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
++set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+ if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+@@ -1540,7 +1608,7 @@
+ fi
+ rmdir .tst 2>/dev/null
+- # test to see if srcdir already configured
++# test to see if srcdir already configured
+ if test "`cd $srcdir && pwd`" != "`pwd`" &&
+    test -f $srcdir/config.status; then
+   { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+@@ -1560,7 +1628,7 @@
+ # Define the identity of the package.
+  PACKAGE=ctorrent
+- VERSION=devel
++ VERSION=dnh2
+ cat >>confdefs.h <<_ACEOF
+@@ -1588,9 +1656,6 @@
+ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+-
+-AMTAR=${AMTAR-"${am_missing_run}tar"}
+-
+ install_sh=${install_sh-"$am_aux_dir/install-sh"}
+ # Installed binaries are usually stripped using `strip' when the user
+@@ -1683,6 +1748,13 @@
+ # We need awk for the "check" target.  The system "awk" is bad on
+ # some platforms.
++# Always define AMTAR for backward compatibility.
++
++AMTAR=${AMTAR-"${am_missing_run}tar"}
++
++am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
++
++
+@@ -1806,7 +1878,6 @@
+   (exit $ac_status); }
+ cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -1826,8 +1897,8 @@
+ # Try to create an executable without -o first, disregard a.out.
+ # It will help us diagnose broken compilers, and finding out an intuition
+ # of exeext.
+-echo "$as_me:$LINENO: checking for C++ compiler default output" >&5
+-echo $ECHO_N "checking for C++ compiler default output... $ECHO_C" >&6
++echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5
++echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6
+ ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+ if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+   (eval $ac_link_default) 2>&5
+@@ -1847,23 +1918,23 @@
+   test -f "$ac_file" || continue
+   case $ac_file in
+     *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+-        ;;
++      ;;
+     conftest.$ac_ext )
+-        # This is the source file.
+-        ;;
++      # This is the source file.
++      ;;
+     [ab].out )
+-        # We found the default executable, but exeext='' is most
+-        # certainly right.
+-        break;;
++      # We found the default executable, but exeext='' is most
++      # certainly right.
++      break;;
+     *.* )
+-        ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+-        # FIXME: I believe we export ac_cv_exeext for Libtool,
+-        # but it would be cool to find out if it's true.  Does anybody
+-        # maintain Libtool? --akim.
+-        export ac_cv_exeext
+-        break;;
++      ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
++      # FIXME: I believe we export ac_cv_exeext for Libtool,
++      # but it would be cool to find out if it's true.  Does anybody
++      # maintain Libtool? --akim.
++      export ac_cv_exeext
++      break;;
+     * )
+-        break;;
++      break;;
+   esac
+ done
+ else
+@@ -1937,8 +2008,8 @@
+   case $ac_file in
+     *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+     *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+-          export ac_cv_exeext
+-          break;;
++        export ac_cv_exeext
++        break;;
+     * ) break;;
+   esac
+ done
+@@ -1963,7 +2034,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -2014,7 +2084,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -2034,11 +2103,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_cxx_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -2051,7 +2130,7 @@
+ ac_compiler_gnu=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+ fi
+@@ -2067,7 +2146,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -2084,11 +2162,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_cxx_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -2101,7 +2189,7 @@
+ ac_cv_prog_cxx_g=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+ echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+@@ -2121,8 +2209,7 @@
+   fi
+ fi
+ for ac_declaration in \
+-   ''\
+-   '#include <stdlib.h>' \
++   '' \
+    'extern "C" void std::exit (int) throw (); using std::exit;' \
+    'extern "C" void std::exit (int); using std::exit;' \
+    'extern "C" void exit (int) throw ();' \
+@@ -2130,14 +2217,13 @@
+    'void exit (int);'
+ do
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+-#include <stdlib.h>
+ $ac_declaration
++#include <stdlib.h>
+ int
+ main ()
+ {
+@@ -2148,11 +2234,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_cxx_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -2165,9 +2261,8 @@
+ continue
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -2184,11 +2279,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_cxx_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -2200,7 +2305,7 @@
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ rm -f conftest*
+ if test -n "$ac_declaration"; then
+@@ -2321,7 +2426,9 @@
+     : > sub/conftest.c
+     for i in 1 2 3 4 5 6; do
+       echo '#include "conftst'$i'.h"' >> sub/conftest.c
+-      : > sub/conftst$i.h
++      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
++      # Solaris 8's {/usr,}/bin/sh.
++      touch sub/conftst$i.h
+     done
+     echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+@@ -2349,9 +2456,14 @@
+        grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+        ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+       # icc doesn't choke on unknown options, it will just issue warnings
+-      # (even with -Werror).  So we grep stderr for any message
+-      # that says an option was ignored.
+-      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
++      # or remarks (even with -Werror).  So we grep stderr for any message
++      # that says an option was ignored or not supported.
++      # When given -MP, icc 7.0 and 7.1 complain thusly:
++      #   icc: Command line warning: ignoring option '-M'; no argument required
++      # The diagnosis changed in icc 8.0:
++      #   icc: Command line remark: option '-MP' not supported
++      if (grep 'ignoring option' conftest.err ||
++          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+         am_cv_CXX_dependencies_compiler_type=$depmode
+         break
+       fi
+@@ -2723,7 +2835,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -2743,11 +2854,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -2760,7 +2881,7 @@
+ ac_compiler_gnu=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_c_compiler_gnu=$ac_compiler_gnu
+ fi
+@@ -2776,7 +2897,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -2793,11 +2913,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -2810,7 +2940,7 @@
+ ac_cv_prog_cc_g=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+ echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+@@ -2837,7 +2967,6 @@
+   ac_cv_prog_cc_stdc=no
+ ac_save_CC=$CC
+ cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -2865,6 +2994,16 @@
+   va_end (v);
+   return s;
+ }
++
++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
++   function prototypes and stuff, but not '\xHH' hex character constants.
++   These don't provoke an error unfortunately, instead are silently treated
++   as 'x'.  The following induces an error, until -std1 is added to get
++   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
++   array size at least.  It's necessary to write '\x00'==0 to get something
++   that's true only with -std1.  */
++int osf4_cc_array ['\x00' == 0 ? 1 : -1];
++
+ int test (int i, double x);
+ struct s1 {int (*f) (int a);};
+ struct s2 {int (*f) (double a);};
+@@ -2891,11 +3030,21 @@
+   CC="$ac_save_CC $ac_arg"
+   rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -2908,7 +3057,7 @@
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+-rm -f conftest.$ac_objext
++rm -f conftest.err conftest.$ac_objext
+ done
+ rm -f conftest.$ac_ext conftest.$ac_objext
+ CC=$ac_save_CC
+@@ -2936,19 +3085,28 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }; }; then
+   for ac_declaration in \
+-   ''\
+-   '#include <stdlib.h>' \
++   '' \
+    'extern "C" void std::exit (int) throw (); using std::exit;' \
+    'extern "C" void std::exit (int); using std::exit;' \
+    'extern "C" void exit (int) throw ();' \
+@@ -2956,14 +3114,13 @@
+    'void exit (int);'
+ do
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+-#include <stdlib.h>
+ $ac_declaration
++#include <stdlib.h>
+ int
+ main ()
+ {
+@@ -2974,11 +3131,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -2991,9 +3158,8 @@
+ continue
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3010,11 +3176,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3026,7 +3202,7 @@
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ rm -f conftest*
+ if test -n "$ac_declaration"; then
+@@ -3040,7 +3216,7 @@
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ ac_cpp='$CPP $CPPFLAGS'
+ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+@@ -3088,7 +3264,9 @@
+     : > sub/conftest.c
+     for i in 1 2 3 4 5 6; do
+       echo '#include "conftst'$i'.h"' >> sub/conftest.c
+-      : > sub/conftst$i.h
++      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
++      # Solaris 8's {/usr,}/bin/sh.
++      touch sub/conftst$i.h
+     done
+     echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+@@ -3116,9 +3294,14 @@
+        grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+        ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+       # icc doesn't choke on unknown options, it will just issue warnings
+-      # (even with -Werror).  So we grep stderr for any message
+-      # that says an option was ignored.
+-      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
++      # or remarks (even with -Werror).  So we grep stderr for any message
++      # that says an option was ignored or not supported.
++      # When given -MP, icc 7.0 and 7.1 complain thusly:
++      #   icc: Command line warning: ignoring option '-M'; no argument required
++      # The diagnosis changed in icc 8.0:
++      #   icc: Command line remark: option '-MP' not supported
++      if (grep 'ignoring option' conftest.err ||
++          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+         am_cv_CC_dependencies_compiler_type=$depmode
+         break
+       fi
+@@ -3161,7 +3344,6 @@
+   ac_check_lib_save_LIBS=$LIBS
+ LIBS="-lssl  $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3185,11 +3367,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+-  (eval $ac_link) 2>&5
++  (eval $ac_link) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest$ac_exeext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3202,7 +3394,8 @@
+ ac_cv_lib_ssl_SHA1_Init=no
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
+ LIBS=$ac_check_lib_save_LIBS
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SHA1_Init" >&5
+@@ -3224,7 +3417,6 @@
+   ac_check_lib_save_LIBS=$LIBS
+ LIBS="-lcrypt  $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3248,11 +3440,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+-  (eval $ac_link) 2>&5
++  (eval $ac_link) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest$ac_exeext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3265,7 +3467,8 @@
+ ac_cv_lib_crypt_SHA1_Init=no
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
+ LIBS=$ac_check_lib_save_LIBS
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_SHA1_Init" >&5
+@@ -3279,6 +3482,79 @@
+ else
++echo "$as_me:$LINENO: checking for SHA1_Init in -lcrypto" >&5
++echo $ECHO_N "checking for SHA1_Init in -lcrypto... $ECHO_C" >&6
++if test "${ac_cv_lib_crypto_SHA1_Init+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lcrypto  $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++
++/* Override any gcc2 internal prototype to avoid an error.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++   builtin and then its argument prototype would still apply.  */
++char SHA1_Init ();
++int
++main ()
++{
++SHA1_Init ();
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++  (eval $ac_link) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  ac_cv_lib_crypto_SHA1_Init=yes
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ac_cv_lib_crypto_SHA1_Init=no
++fi
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_SHA1_Init" >&5
++echo "${ECHO_T}$ac_cv_lib_crypto_SHA1_Init" >&6
++if test $ac_cv_lib_crypto_SHA1_Init = yes; then
++  cat >>confdefs.h <<_ACEOF
++#define HAVE_LIBCRYPTO 1
++_ACEOF
++
++  LIBS="-lcrypto $LIBS"
++
++else
++
+ echo "$as_me:$LINENO: checking for SHA1_Init in -lmd" >&5
+ echo $ECHO_N "checking for SHA1_Init in -lmd... $ECHO_C" >&6
+ if test "${ac_cv_lib_md_SHA1_Init+set}" = set; then
+@@ -3287,7 +3563,6 @@
+   ac_check_lib_save_LIBS=$LIBS
+ LIBS="-lmd  $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3311,11 +3586,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+-  (eval $ac_link) 2>&5
++  (eval $ac_link) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest$ac_exeext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3328,7 +3613,8 @@
+ ac_cv_lib_md_SHA1_Init=no
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
+ LIBS=$ac_check_lib_save_LIBS
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_lib_md_SHA1_Init" >&5
+@@ -3341,9 +3627,13 @@
+   LIBS="-lmd $LIBS"
+ else
+-  { { echo "$as_me:$LINENO: error: error, Please install OpenSSL first!" >&5
+-echo "$as_me: error: error, Please install OpenSSL first!" >&2;}
+-   { (exit 1); exit 1; }; }
++
++cat >>confdefs.h <<\_ACEOF
++#define USE_STANDALONE_SHA1
++_ACEOF
++
++fi
++
+ fi
+ fi
+@@ -3366,7 +3656,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3386,11 +3675,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3403,7 +3702,7 @@
+ eval "$as_ac_Header=no"
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+ echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+@@ -3426,7 +3725,6 @@
+   ac_func_search_save_LIBS=$LIBS
+ ac_cv_search_opendir=no
+ cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3450,11 +3748,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+-  (eval $ac_link) 2>&5
++  (eval $ac_link) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest$ac_exeext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3466,12 +3774,12 @@
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
+ if test "$ac_cv_search_opendir" = no; then
+   for ac_lib in dir; do
+     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+     cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3495,11 +3803,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+-  (eval $ac_link) 2>&5
++  (eval $ac_link) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest$ac_exeext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3512,7 +3830,8 @@
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
+   done
+ fi
+ LIBS=$ac_func_search_save_LIBS
+@@ -3533,7 +3852,6 @@
+   ac_func_search_save_LIBS=$LIBS
+ ac_cv_search_opendir=no
+ cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3557,11 +3875,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+-  (eval $ac_link) 2>&5
++  (eval $ac_link) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest$ac_exeext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3573,12 +3901,12 @@
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
+ if test "$ac_cv_search_opendir" = no; then
+   for ac_lib in x; do
+     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+     cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3602,11 +3930,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+-  (eval $ac_link) 2>&5
++  (eval $ac_link) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest$ac_exeext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3619,7 +3957,8 @@
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
+   done
+ fi
+ LIBS=$ac_func_search_save_LIBS
+@@ -3661,7 +4000,6 @@
+   # On the NeXT, cc -E runs the code through the compiler's parser,
+   # not just through cpp. "Syntax error" is here to catch this case.
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3672,7 +4010,7 @@
+ #else
+ # include <assert.h>
+ #endif
+-                     Syntax error
++                   Syntax error
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+@@ -3684,6 +4022,7 @@
+   (exit $ac_status); } >/dev/null; then
+   if test -s conftest.err; then
+     ac_cpp_err=$ac_c_preproc_warn_flag
++    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+   else
+     ac_cpp_err=
+   fi
+@@ -3704,7 +4043,6 @@
+   # OK, works on sane cases.  Now check whether non-existent headers
+   # can be detected and how.
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3722,6 +4060,7 @@
+   (exit $ac_status); } >/dev/null; then
+   if test -s conftest.err; then
+     ac_cpp_err=$ac_c_preproc_warn_flag
++    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+   else
+     ac_cpp_err=
+   fi
+@@ -3768,7 +4107,6 @@
+   # On the NeXT, cc -E runs the code through the compiler's parser,
+   # not just through cpp. "Syntax error" is here to catch this case.
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3779,7 +4117,7 @@
+ #else
+ # include <assert.h>
+ #endif
+-                     Syntax error
++                   Syntax error
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+@@ -3791,6 +4129,7 @@
+   (exit $ac_status); } >/dev/null; then
+   if test -s conftest.err; then
+     ac_cpp_err=$ac_c_preproc_warn_flag
++    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+   else
+     ac_cpp_err=
+   fi
+@@ -3811,7 +4150,6 @@
+   # OK, works on sane cases.  Now check whether non-existent headers
+   # can be detected and how.
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3829,6 +4167,7 @@
+   (exit $ac_status); } >/dev/null; then
+   if test -s conftest.err; then
+     ac_cpp_err=$ac_c_preproc_warn_flag
++    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+   else
+     ac_cpp_err=
+   fi
+@@ -3889,7 +4228,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3910,11 +4248,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -3927,12 +4275,11 @@
+ ac_cv_header_stdc=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_header_stdc = yes; then
+   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3954,7 +4301,6 @@
+ if test $ac_cv_header_stdc = yes; then
+   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3979,7 +4325,6 @@
+   :
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -3991,9 +4336,9 @@
+ # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+ #else
+ # define ISLOWER(c) \
+-                   (('a' <= (c) && (c) <= 'i') \
+-                     || ('j' <= (c) && (c) <= 'r') \
+-                     || ('s' <= (c) && (c) <= 'z'))
++                 (('a' <= (c) && (c) <= 'i') \
++                   || ('j' <= (c) && (c) <= 'r') \
++                   || ('s' <= (c) && (c) <= 'z'))
+ # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+ #endif
+@@ -4004,7 +4349,7 @@
+   int i;
+   for (i = 0; i < 256; i++)
+     if (XOR (islower (i), ISLOWER (i))
+-        || toupper (i) != TOUPPER (i))
++      || toupper (i) != TOUPPER (i))
+       exit(2);
+   exit (0);
+ }
+@@ -4029,7 +4374,7 @@
+ ( exit $ac_status )
+ ac_cv_header_stdc=no
+ fi
+-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+ fi
+ fi
+@@ -4054,7 +4399,7 @@
+ for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+-                  inttypes.h stdint.h unistd.h
++                inttypes.h stdint.h unistd.h
+ do
+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+@@ -4063,7 +4408,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4075,11 +4419,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -4092,7 +4446,7 @@
+ eval "$as_ac_Header=no"
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+ echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+@@ -4135,7 +4489,6 @@
+ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+ echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4146,16 +4499,26 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+-  (exit $ac_status); }; }; then
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
+   ac_header_compiler=yes
+ else
+   echo "$as_me: failed program was:" >&5
+@@ -4163,7 +4526,7 @@
+ ac_header_compiler=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+ echo "${ECHO_T}$ac_header_compiler" >&6
+@@ -4171,7 +4534,6 @@
+ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+ echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4189,6 +4551,7 @@
+   (exit $ac_status); } >/dev/null; then
+   if test -s conftest.err; then
+     ac_cpp_err=$ac_c_preproc_warn_flag
++    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+   else
+     ac_cpp_err=
+   fi
+@@ -4208,33 +4571,32 @@
+ echo "${ECHO_T}$ac_header_preproc" >&6
+ # So?  What about this header?
+-case $ac_header_compiler:$ac_header_preproc in
+-  yes:no )
++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
++  yes:no: )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+-    (
+-      cat <<\_ASBOX
+-## ------------------------------------ ##
+-## Report this to bug-autoconf@gnu.org. ##
+-## ------------------------------------ ##
+-_ASBOX
+-    ) |
+-      sed "s/^/$as_me: WARNING:     /" >&2
++    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
++echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
++    ac_header_preproc=yes
+     ;;
+-  no:yes )
++  no:yes:* )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+-    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
++    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
++echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
++    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
++echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
++    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
++echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
++    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
++echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+     (
+       cat <<\_ASBOX
+-## ------------------------------------ ##
+-## Report this to bug-autoconf@gnu.org. ##
+-## ------------------------------------ ##
++## ------------------------------------- ##
++## Report this to dholmes@ct.boxmail.com ##
++## ------------------------------------- ##
+ _ASBOX
+     ) |
+       sed "s/^/$as_me: WARNING:     /" >&2
+@@ -4245,7 +4607,7 @@
+ if eval "test \"\${$as_ac_Header+set}\" = set"; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+-  eval "$as_ac_Header=$ac_header_preproc"
++  eval "$as_ac_Header=\$ac_header_preproc"
+ fi
+ echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+ echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+@@ -4268,7 +4630,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4331,11 +4692,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -4348,7 +4719,7 @@
+ ac_cv_c_const=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+ echo "${ECHO_T}$ac_cv_c_const" >&6
+@@ -4368,7 +4739,6 @@
+   ac_cv_c_inline=no
+ for ac_kw in inline __inline__ __inline; do
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4383,11 +4753,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -4399,23 +4779,27 @@
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+ echo "${ECHO_T}$ac_cv_c_inline" >&6
++
++
+ case $ac_cv_c_inline in
+   inline | yes) ;;
+-  no)
+-cat >>confdefs.h <<\_ACEOF
+-#define inline
+-_ACEOF
+- ;;
+-  *)  cat >>confdefs.h <<_ACEOF
+-#define inline $ac_cv_c_inline
++  *)
++    case $ac_cv_c_inline in
++      no) ac_val=;;
++      *) ac_val=$ac_cv_c_inline;;
++    esac
++    cat >>confdefs.h <<_ACEOF
++#ifndef __cplusplus
++#define inline $ac_val
++#endif
+ _ACEOF
+- ;;
++    ;;
+ esac
+ echo "$as_me:$LINENO: checking for size_t" >&5
+@@ -4424,7 +4808,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4444,11 +4827,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -4461,7 +4854,7 @@
+ ac_cv_type_size_t=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+ echo "${ECHO_T}$ac_cv_type_size_t" >&6
+@@ -4481,7 +4874,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4502,11 +4894,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -4519,7 +4921,7 @@
+ ac_cv_header_time=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+ echo "${ECHO_T}$ac_cv_header_time" >&6
+@@ -4541,7 +4943,6 @@
+ else
+     ac_pattern="Autoconf.*'x'"
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4561,7 +4962,6 @@
+   if test $ac_cv_prog_gcc_traditional = no; then
+     cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4594,13 +4994,12 @@
+   ac_cv_func_memcmp_working=no
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+-
++$ac_includes_default
+ int
+ main ()
+ {
+@@ -4619,12 +5018,12 @@
+     int i;
+     for (i = 0; i < 4; i++)
+       {
+-        char *a = foo + i;
+-        char *b = bar + i;
+-        strcpy (a, "--------01111111");
+-        strcpy (b, "--------10000000");
+-        if (memcmp (a, b, 16) >= 0)
+-          exit (1);
++      char *a = foo + i;
++      char *b = bar + i;
++      strcpy (a, "--------01111111");
++      strcpy (b, "--------10000000");
++      if (memcmp (a, b, 16) >= 0)
++        exit (1);
+       }
+     exit (0);
+   }
+@@ -4653,12 +5052,19 @@
+ ( exit $ac_status )
+ ac_cv_func_memcmp_working=no
+ fi
+-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5
+ echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6
+-test $ac_cv_func_memcmp_working = no && LIBOBJS="$LIBOBJS memcmp.$ac_objext"
++test $ac_cv_func_memcmp_working = no && case $LIBOBJS in
++    "memcmp.$ac_objext"   | \
++  *" memcmp.$ac_objext"   | \
++    "memcmp.$ac_objext "* | \
++  *" memcmp.$ac_objext "* ) ;;
++  *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" ;;
++esac
++
+ echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+ echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+@@ -4666,7 +5072,6 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4693,11 +5098,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+-  (eval $ac_compile) 2>&5
++  (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest.$ac_objext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -4710,7 +5125,7 @@
+ ac_cv_type_signal=int
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+ echo "${ECHO_T}$ac_cv_type_signal" >&6
+@@ -4732,7 +5147,6 @@
+   ac_cv_func_lstat_dereferences_slashed_symlink=no
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4744,8 +5158,8 @@
+ {
+ struct stat sbuf;
+      /* Linux will dereference the symlink and fail.
+-        That is better in the sense that it means we will not
+-        have to compile and use the lstat wrapper.  */
++      That is better in the sense that it means we will not
++      have to compile and use the lstat wrapper.  */
+      exit (lstat ("conftest.sym/", &sbuf) ? 0 : 1);
+   ;
+   return 0;
+@@ -4771,7 +5185,7 @@
+ ( exit $ac_status )
+ ac_cv_func_lstat_dereferences_slashed_symlink=no
+ fi
+-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+ else
+   # If the `ln -s' command failed, then we probably don't even
+@@ -4792,7 +5206,14 @@
+ if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then
+-  LIBOBJS="$LIBOBJS lstat.$ac_objext"
++  case $LIBOBJS in
++    "lstat.$ac_objext"   | \
++  *" lstat.$ac_objext"   | \
++    "lstat.$ac_objext "* | \
++  *" lstat.$ac_objext "* ) ;;
++  *) LIBOBJS="$LIBOBJS lstat.$ac_objext" ;;
++esac
++
+ fi
+ echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5
+@@ -4804,7 +5225,6 @@
+   ac_cv_func_stat_empty_string_bug=yes
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+@@ -4840,13 +5260,20 @@
+ ( exit $ac_status )
+ ac_cv_func_stat_empty_string_bug=no
+ fi
+-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5
+ echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6
+ if test $ac_cv_func_stat_empty_string_bug = yes; then
+-  LIBOBJS="$LIBOBJS stat.$ac_objext"
++  case $LIBOBJS in
++    "stat.$ac_objext"   | \
++  *" stat.$ac_objext"   | \
++    "stat.$ac_objext "* | \
++  *" stat.$ac_objext "* ) ;;
++  *) LIBOBJS="$LIBOBJS stat.$ac_objext" ;;
++esac
++
+ cat >>confdefs.h <<_ACEOF
+ #define HAVE_STAT_EMPTY_STRING_BUG 1
+@@ -4871,7 +5298,8 @@
+-for ac_func in ftruncate gethostbyname gettimeofday getwd inet_ntoa memchr memmove memset mkdir select socket strchr strerror strncasecmp strstr strtol strnstr
++
++for ac_func in ftruncate gethostbyname gettimeofday getwd inet_ntoa memchr memmove memset mkdir select socket strchr strerror strncasecmp strstr strtol strtoll strnstr
+ do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ echo "$as_me:$LINENO: checking for $ac_func" >&5
+@@ -4880,21 +5308,28 @@
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
++/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
++   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
++#define $ac_func innocuous_$ac_func
++
+ /* System header to define __stub macros and hopefully few prototypes,
+     which can conflict with char $ac_func (); below.
+     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+     <limits.h> exists even on freestanding compilers.  */
++
+ #ifdef __STDC__
+ # include <limits.h>
+ #else
+ # include <assert.h>
+ #endif
++
++#undef $ac_func
++
+ /* Override any gcc2 internal prototype to avoid an error.  */
+ #ifdef __cplusplus
+ extern "C"
+@@ -4925,11 +5360,21 @@
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+-  (eval $ac_link) 2>&5
++  (eval $ac_link) 2>conftest.er1
+   ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+-         { ac_try='test -s conftest$ac_exeext'
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+@@ -4942,7 +5387,8 @@
+ eval "$as_ac_var=no"
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+ echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+@@ -4955,6 +5401,547 @@
+ done
++# Enable/check large file support
++# Check whether --enable-largefile or --disable-largefile was given.
++if test "${enable_largefile+set}" = set; then
++  enableval="$enable_largefile"
++
++fi;
++if test "$enable_largefile" != no; then
++
++  echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
++echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
++if test "${ac_cv_sys_largefile_CC+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++  ac_cv_sys_largefile_CC=no
++     if test "$GCC" != yes; then
++       ac_save_CC=$CC
++       while :; do
++       # IRIX 6.2 and later do not support large files by default,
++       # so use the C compiler's -n32 option if that helps.
++       cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <sys/types.h>
++ /* Check that off_t can represent 2**63 - 1 correctly.
++    We can't simply define LARGE_OFF_T to be 9223372036854775807,
++    since some C++ compilers masquerading as C compilers
++    incorrectly reject 9223372036854775807.  */
++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
++  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
++                     && LARGE_OFF_T % 2147483647 == 1)
++                    ? 1 : -1];
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++       rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  break
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext
++       CC="$CC -n32"
++       rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  ac_cv_sys_largefile_CC=' -n32'; break
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext
++       break
++       done
++       CC=$ac_save_CC
++       rm -f conftest.$ac_ext
++    fi
++fi
++echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
++echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
++  if test "$ac_cv_sys_largefile_CC" != no; then
++    CC=$CC$ac_cv_sys_largefile_CC
++  fi
++
++  echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
++echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
++if test "${ac_cv_sys_file_offset_bits+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++  while :; do
++  ac_cv_sys_file_offset_bits=no
++  cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <sys/types.h>
++ /* Check that off_t can represent 2**63 - 1 correctly.
++    We can't simply define LARGE_OFF_T to be 9223372036854775807,
++    since some C++ compilers masquerading as C compilers
++    incorrectly reject 9223372036854775807.  */
++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
++  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
++                     && LARGE_OFF_T % 2147483647 == 1)
++                    ? 1 : -1];
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  break
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++  cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#define _FILE_OFFSET_BITS 64
++#include <sys/types.h>
++ /* Check that off_t can represent 2**63 - 1 correctly.
++    We can't simply define LARGE_OFF_T to be 9223372036854775807,
++    since some C++ compilers masquerading as C compilers
++    incorrectly reject 9223372036854775807.  */
++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
++  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
++                     && LARGE_OFF_T % 2147483647 == 1)
++                    ? 1 : -1];
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  ac_cv_sys_file_offset_bits=64; break
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++  break
++done
++fi
++echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
++echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
++if test "$ac_cv_sys_file_offset_bits" != no; then
++
++cat >>confdefs.h <<_ACEOF
++#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
++_ACEOF
++
++fi
++rm -f conftest*
++  echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
++echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
++if test "${ac_cv_sys_large_files+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++  while :; do
++  ac_cv_sys_large_files=no
++  cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <sys/types.h>
++ /* Check that off_t can represent 2**63 - 1 correctly.
++    We can't simply define LARGE_OFF_T to be 9223372036854775807,
++    since some C++ compilers masquerading as C compilers
++    incorrectly reject 9223372036854775807.  */
++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
++  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
++                     && LARGE_OFF_T % 2147483647 == 1)
++                    ? 1 : -1];
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  break
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++  cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#define _LARGE_FILES 1
++#include <sys/types.h>
++ /* Check that off_t can represent 2**63 - 1 correctly.
++    We can't simply define LARGE_OFF_T to be 9223372036854775807,
++    since some C++ compilers masquerading as C compilers
++    incorrectly reject 9223372036854775807.  */
++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
++  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
++                     && LARGE_OFF_T % 2147483647 == 1)
++                    ? 1 : -1];
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  ac_cv_sys_large_files=1; break
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++  break
++done
++fi
++echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
++echo "${ECHO_T}$ac_cv_sys_large_files" >&6
++if test "$ac_cv_sys_large_files" != no; then
++
++cat >>confdefs.h <<_ACEOF
++#define _LARGE_FILES $ac_cv_sys_large_files
++_ACEOF
++
++fi
++rm -f conftest*
++fi
++
++echo "$as_me:$LINENO: checking for _LARGEFILE_SOURCE value needed for large files" >&5
++echo $ECHO_N "checking for _LARGEFILE_SOURCE value needed for large files... $ECHO_C" >&6
++if test "${ac_cv_sys_largefile_source+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++  while :; do
++  ac_cv_sys_largefile_source=no
++  cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <stdio.h>
++int
++main ()
++{
++return !fseeko;
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  break
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++  cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#define _LARGEFILE_SOURCE 1
++#include <stdio.h>
++int
++main ()
++{
++return !fseeko;
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  ac_cv_sys_largefile_source=1; break
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++  break
++done
++fi
++echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_source" >&5
++echo "${ECHO_T}$ac_cv_sys_largefile_source" >&6
++if test "$ac_cv_sys_largefile_source" != no; then
++
++cat >>confdefs.h <<_ACEOF
++#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
++_ACEOF
++
++fi
++rm -f conftest*
++
++# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
++# in glibc 2.1.3, but that breaks too many other things.
++# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
++echo "$as_me:$LINENO: checking for fseeko" >&5
++echo $ECHO_N "checking for fseeko... $ECHO_C" >&6
++if test "${ac_cv_func_fseeko+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++  cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <stdio.h>
++int
++main ()
++{
++return fseeko && fseeko (stdin, 0, 0);
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++  (eval $ac_link) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  ac_cv_func_fseeko=yes
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ac_cv_func_fseeko=no
++fi
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
++fi
++echo "$as_me:$LINENO: result: $ac_cv_func_fseeko" >&5
++echo "${ECHO_T}$ac_cv_func_fseeko" >&6
++if test $ac_cv_func_fseeko = yes; then
++
++cat >>confdefs.h <<\_ACEOF
++#define HAVE_FSEEKO 1
++_ACEOF
++
++fi
++
++
+           ac_config_files="$ac_config_files Makefile"
+ cat >confcache <<\_ACEOF
+ # This file is a shell script that caches the results of configure
+@@ -4984,13 +5971,13 @@
+       # `set' does not quote correctly, so add quotes (double-quote
+       # substitution turns \\\\ into \\, and sed turns \\ into \).
+       sed -n \
+-        "s/'/'\\\\''/g;
+-        s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
++      "s/'/'\\\\''/g;
++        s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+       ;;
+     *)
+       # `set' quotes correctly as required by POSIX, so do not add quotes.
+       sed -n \
+-        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
++      "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+       ;;
+     esac;
+ } |
+@@ -5020,13 +6007,13 @@
+ # trailing colons and then remove the whole line if VPATH becomes empty
+ # (actually we leave an empty line to preserve line numbers).
+ if test "x$srcdir" = x.; then
+-  ac_vpsub='/^[       ]*VPATH[        ]*=/{
++  ac_vpsub='/^[        ]*VPATH[        ]*=/{
+ s/:*\$(srcdir):*/:/;
+ s/:*\${srcdir}:*/:/;
+ s/:*@srcdir@:*/:/;
+-s/^\([^=]*=[  ]*\):*/\1/;
++s/^\([^=]*=[   ]*\):*/\1/;
+ s/:*$//;
+-s/^[^=]*=[    ]*$//;
++s/^[^=]*=[     ]*$//;
+ }'
+ fi
+@@ -5037,7 +6024,7 @@
+ for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+   # 1. Remove the extension, and $U if already installed.
+   ac_i=`echo "$ac_i" |
+-         sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
++       sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+   # 2. Add them.
+   ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+   ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+@@ -5102,9 +6089,10 @@
+ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+   set -o posix
+ fi
++DUALCASE=1; export DUALCASE # for MKS sh
+ # Support unset when possible.
+-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
++if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+   as_unset=unset
+ else
+   as_unset=false
+@@ -5123,7 +6111,7 @@
+   LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+   LC_TELEPHONE LC_TIME
+ do
+-  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+     eval $as_var=C; export $as_var
+   else
+     $as_unset $as_var
+@@ -5302,16 +6290,17 @@
+ if mkdir -p . 2>/dev/null; then
+   as_mkdir_p=:
+ else
++  test -d ./-p && rmdir ./-p
+   as_mkdir_p=false
+ fi
+ as_executable_p="test -f"
+ # Sed expression to map a string onto a valid CPP name.
+-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+ # Sed expression to map a string onto a valid variable name.
+-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+ # IFS
+@@ -5337,8 +6326,8 @@
+ } >&5
+ cat >&5 <<_CSEOF
+-This file was extended by CTorrent $as_me devel, which was
+-generated by GNU Autoconf 2.57.  Invocation command line was
++This file was extended by CTorrent $as_me dnh2, which was
++generated by GNU Autoconf 2.59.  Invocation command line was
+   CONFIG_FILES    = $CONFIG_FILES
+   CONFIG_HEADERS  = $CONFIG_HEADERS
+@@ -5382,9 +6371,9 @@
+   -d, --debug      don't remove temporary files
+       --recheck    update $as_me by reconfiguring in the same conditions
+   --file=FILE[:TEMPLATE]
+-                   instantiate the configuration file FILE
++                 instantiate the configuration file FILE
+   --header=FILE[:TEMPLATE]
+-                   instantiate the configuration header FILE
++                 instantiate the configuration header FILE
+ Configuration files:
+ $config_files
+@@ -5400,12 +6389,11 @@
+ cat >>$CONFIG_STATUS <<_ACEOF
+ ac_cs_version="\\
+-CTorrent config.status devel
+-configured by $0, generated by GNU Autoconf 2.57,
++CTorrent config.status dnh2
++configured by $0, generated by GNU Autoconf 2.59,
+   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+-Free Software Foundation, Inc.
++Copyright (C) 2003 Free Software Foundation, Inc.
+ This config.status script is free software; the Free Software Foundation
+ gives unlimited permission to copy, distribute and modify it."
+ srcdir=$srcdir
+@@ -5610,14 +6598,17 @@
+ s,@AUTOMAKE@,$AUTOMAKE,;t t
+ s,@AUTOHEADER@,$AUTOHEADER,;t t
+ s,@MAKEINFO@,$MAKEINFO,;t t
+-s,@AMTAR@,$AMTAR,;t t
+ s,@install_sh@,$install_sh,;t t
+ s,@STRIP@,$STRIP,;t t
+ s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+ s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
++s,@mkdir_p@,$mkdir_p,;t t
+ s,@AWK@,$AWK,;t t
+ s,@SET_MAKE@,$SET_MAKE,;t t
+ s,@am__leading_dot@,$am__leading_dot,;t t
++s,@AMTAR@,$AMTAR,;t t
++s,@am__tar@,$am__tar,;t t
++s,@am__untar@,$am__untar,;t t
+ s,@CXX@,$CXX,;t t
+ s,@CXXFLAGS@,$CXXFLAGS,;t t
+ s,@LDFLAGS@,$LDFLAGS,;t t
+@@ -5673,9 +6664,9 @@
+       (echo ':t
+   /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+       if test -z "$ac_sed_cmds"; then
+-      ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
++      ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+       else
+-      ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
++      ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+       fi
+       ac_sed_frag=`expr $ac_sed_frag + 1`
+       ac_beg=$ac_end
+@@ -5693,21 +6684,21 @@
+   # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+   case $ac_file in
+   - | *:- | *:-:* ) # input from stdin
+-        cat >$tmp/stdin
+-        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++      cat >$tmp/stdin
++      ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
++      ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+   *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++      ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+   * )   ac_file_in=$ac_file.in ;;
+   esac
+   # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+   ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X"$ac_file" : 'X\(//\)[^/]' \| \
+-         X"$ac_file" : 'X\(//\)$' \| \
+-         X"$ac_file" : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X"$ac_file" : 'X\(//\)[^/]' \| \
++       X"$ac_file" : 'X\(//\)$' \| \
++       X"$ac_file" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X"$ac_file" |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+@@ -5723,10 +6714,10 @@
+       as_dirs="$as_dir $as_dirs"
+       as_dir=`(dirname "$as_dir") 2>/dev/null ||
+ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X"$as_dir" : 'X\(//\)[^/]' \| \
+-         X"$as_dir" : 'X\(//\)$' \| \
+-         X"$as_dir" : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X"$as_dir" : 'X\(//\)[^/]' \| \
++       X"$as_dir" : 'X\(//\)$' \| \
++       X"$as_dir" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X"$as_dir" |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+@@ -5764,12 +6755,45 @@
+     ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+     ac_top_srcdir=$ac_top_builddir$srcdir ;;
+ esac
+-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+-# absolute.
+-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
++
++# Do not use `cd foo && pwd` to compute absolute paths, because
++# the directories may not exist.
++case `pwd` in
++.) ac_abs_builddir="$ac_dir";;
++*)
++  case "$ac_dir" in
++  .) ac_abs_builddir=`pwd`;;
++  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
++  *) ac_abs_builddir=`pwd`/"$ac_dir";;
++  esac;;
++esac
++case $ac_abs_builddir in
++.) ac_abs_top_builddir=${ac_top_builddir}.;;
++*)
++  case ${ac_top_builddir}. in
++  .) ac_abs_top_builddir=$ac_abs_builddir;;
++  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
++  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
++  esac;;
++esac
++case $ac_abs_builddir in
++.) ac_abs_srcdir=$ac_srcdir;;
++*)
++  case $ac_srcdir in
++  .) ac_abs_srcdir=$ac_abs_builddir;;
++  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
++  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
++  esac;;
++esac
++case $ac_abs_builddir in
++.) ac_abs_top_srcdir=$ac_top_srcdir;;
++*)
++  case $ac_top_srcdir in
++  .) ac_abs_top_srcdir=$ac_abs_builddir;;
++  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
++  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
++  esac;;
++esac
+   case $INSTALL in
+@@ -5791,7 +6815,7 @@
+     configure_input="$ac_file.  "
+   fi
+   configure_input=$configure_input"Generated from `echo $ac_file_in |
+-                                     sed 's,.*/,,'` by configure."
++                                   sed 's,.*/,,'` by configure."
+   # First look for the input files in the build tree, otherwise in the
+   # src tree.
+@@ -5800,24 +6824,24 @@
+       case $f in
+       -) echo $tmp/stdin ;;
+       [\\/$]*)
+-         # Absolute (can't be DOS-style, as IFS=:)
+-         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++       # Absolute (can't be DOS-style, as IFS=:)
++       test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+ echo "$as_me: error: cannot find input file: $f" >&2;}
+    { (exit 1); exit 1; }; }
+-         echo $f;;
++       echo "$f";;
+       *) # Relative
+-         if test -f "$f"; then
+-           # Build tree
+-           echo $f
+-         elif test -f "$srcdir/$f"; then
+-           # Source tree
+-           echo $srcdir/$f
+-         else
+-           # /dev/null tree
+-           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++       if test -f "$f"; then
++         # Build tree
++         echo "$f"
++       elif test -f "$srcdir/$f"; then
++         # Source tree
++         echo "$srcdir/$f"
++       else
++         # /dev/null tree
++         { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+ echo "$as_me: error: cannot find input file: $f" >&2;}
+    { (exit 1); exit 1; }; }
+-         fi;;
++       fi;;
+       esac
+     done` || { (exit 1); exit 1; }
+ _ACEOF
+@@ -5859,12 +6883,12 @@
+ # NAME is the cpp macro being defined and VALUE is the value it is being given.
+ #
+ # ac_d sets the value in "#define NAME VALUE" lines.
+-ac_dA='s,^\([         ]*\)#\([        ]*define[       ][      ]*\)'
+-ac_dB='[      ].*$,\1#\2'
++ac_dA='s,^\([  ]*\)#\([        ]*define[       ][      ]*\)'
++ac_dB='[       ].*$,\1#\2'
+ ac_dC=' '
+ ac_dD=',;t'
+ # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+-ac_uA='s,^\([         ]*\)#\([        ]*\)undef\([    ][      ]*\)'
++ac_uA='s,^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ ac_uB='$,\1#\2define\3'
+ ac_uC=' '
+ ac_uD=',;t'
+@@ -5873,11 +6897,11 @@
+   # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+   case $ac_file in
+   - | *:- | *:-:* ) # input from stdin
+-        cat >$tmp/stdin
+-        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++      cat >$tmp/stdin
++      ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
++      ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+   *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++      ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+   * )   ac_file_in=$ac_file.in ;;
+   esac
+@@ -5891,28 +6915,29 @@
+       case $f in
+       -) echo $tmp/stdin ;;
+       [\\/$]*)
+-         # Absolute (can't be DOS-style, as IFS=:)
+-         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++       # Absolute (can't be DOS-style, as IFS=:)
++       test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+ echo "$as_me: error: cannot find input file: $f" >&2;}
+    { (exit 1); exit 1; }; }
+-         echo $f;;
++       # Do quote $f, to prevent DOS paths from being IFS'd.
++       echo "$f";;
+       *) # Relative
+-         if test -f "$f"; then
+-           # Build tree
+-           echo $f
+-         elif test -f "$srcdir/$f"; then
+-           # Source tree
+-           echo $srcdir/$f
+-         else
+-           # /dev/null tree
+-           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++       if test -f "$f"; then
++         # Build tree
++         echo "$f"
++       elif test -f "$srcdir/$f"; then
++         # Source tree
++         echo "$srcdir/$f"
++       else
++         # /dev/null tree
++         { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+ echo "$as_me: error: cannot find input file: $f" >&2;}
+    { (exit 1); exit 1; }; }
+-         fi;;
++       fi;;
+       esac
+     done` || { (exit 1); exit 1; }
+   # Remove the trailing spaces.
+-  sed 's/[    ]*$//' $ac_file_inputs >$tmp/in
++  sed 's/[     ]*$//' $ac_file_inputs >$tmp/in
+ _ACEOF
+@@ -5935,9 +6960,9 @@
+ s,[\\$`],\\&,g
+ t clear
+ : clear
+-s,^[  ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
++s,^[   ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+ t end
+-s,^[  ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
++s,^[   ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+ : end
+ _ACEOF
+ # If some macros were called several times there might be several times
+@@ -5951,13 +6976,13 @@
+ # example, in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ cat >>conftest.undefs <<\_ACEOF
+-s,^[  ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
++s,^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+ _ACEOF
+ # Break up conftest.defines because some shells have a limit on the size
+ # of here documents, and old seds have small limits too (100 cmds).
+ echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+-echo '  if grep "^[   ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
++echo '  if grep "^[    ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+ echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+ echo '  :' >>$CONFIG_STATUS
+ rm -f conftest.tail
+@@ -5966,7 +6991,7 @@
+   # Write a limited-size here document to $tmp/defines.sed.
+   echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+   # Speed up: don't consider the non `#define' lines.
+-  echo '/^[   ]*#[    ]*define/!b' >>$CONFIG_STATUS
++  echo '/^[    ]*#[    ]*define/!b' >>$CONFIG_STATUS
+   # Work around the forget-to-reset-the-flag bug.
+   echo 't clr' >>$CONFIG_STATUS
+   echo ': clr' >>$CONFIG_STATUS
+@@ -5993,7 +7018,7 @@
+   # Write a limited-size here document to $tmp/undefs.sed.
+   echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+   # Speed up: don't consider the non `#undef'
+-  echo '/^[   ]*#[    ]*undef/!b' >>$CONFIG_STATUS
++  echo '/^[    ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+   # Work around the forget-to-reset-the-flag bug.
+   echo 't clr' >>$CONFIG_STATUS
+   echo ': clr' >>$CONFIG_STATUS
+@@ -6027,10 +7052,10 @@
+     else
+       ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X"$ac_file" : 'X\(//\)[^/]' \| \
+-         X"$ac_file" : 'X\(//\)$' \| \
+-         X"$ac_file" : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X"$ac_file" : 'X\(//\)[^/]' \| \
++       X"$ac_file" : 'X\(//\)$' \| \
++       X"$ac_file" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X"$ac_file" |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+@@ -6046,10 +7071,10 @@
+       as_dirs="$as_dir $as_dirs"
+       as_dir=`(dirname "$as_dir") 2>/dev/null ||
+ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X"$as_dir" : 'X\(//\)[^/]' \| \
+-         X"$as_dir" : 'X\(//\)$' \| \
+-         X"$as_dir" : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X"$as_dir" : 'X\(//\)[^/]' \| \
++       X"$as_dir" : 'X\(//\)$' \| \
++       X"$as_dir" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X"$as_dir" |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+@@ -6081,10 +7106,10 @@
+ done
+ echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+ $as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X$ac_file : 'X\(//\)[^/]' \| \
+-         X$ac_file : 'X\(//\)$' \| \
+-         X$ac_file : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X$ac_file : 'X\(//\)[^/]' \| \
++       X$ac_file : 'X\(//\)$' \| \
++       X$ac_file : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X$ac_file |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+@@ -6103,16 +7128,41 @@
+   ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+   ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+ $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X"$ac_dest" : 'X\(//\)[^/]' \| \
+-         X"$ac_dest" : 'X\(//\)$' \| \
+-         X"$ac_dest" : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X"$ac_dest" : 'X\(//\)[^/]' \| \
++       X"$ac_dest" : 'X\(//\)$' \| \
++       X"$ac_dest" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X"$ac_dest" |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
++  { if $as_mkdir_p; then
++    mkdir -p "$ac_dir"
++  else
++    as_dir="$ac_dir"
++    as_dirs=
++    while test ! -d "$as_dir"; do
++      as_dirs="$as_dir $as_dirs"
++      as_dir=`(dirname "$as_dir") 2>/dev/null ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++       X"$as_dir" : 'X\(//\)[^/]' \| \
++       X"$as_dir" : 'X\(//\)$' \| \
++       X"$as_dir" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
++echo X"$as_dir" |
++    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++        /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++        /^X\(\/\/\)$/{ s//\1/; q; }
++        /^X\(\/\).*/{ s//\1/; q; }
++        s/.*/./; q'`
++    done
++    test ! -n "$as_dirs" || mkdir $as_dirs
++  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
++echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
++   { (exit 1); exit 1; }; }; }
++
+   ac_builddir=.
+ if test "$ac_dir" != .; then
+@@ -6138,12 +7188,45 @@
+     ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+     ac_top_srcdir=$ac_top_builddir$srcdir ;;
+ esac
+-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+-# absolute.
+-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
++
++# Do not use `cd foo && pwd` to compute absolute paths, because
++# the directories may not exist.
++case `pwd` in
++.) ac_abs_builddir="$ac_dir";;
++*)
++  case "$ac_dir" in
++  .) ac_abs_builddir=`pwd`;;
++  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
++  *) ac_abs_builddir=`pwd`/"$ac_dir";;
++  esac;;
++esac
++case $ac_abs_builddir in
++.) ac_abs_top_builddir=${ac_top_builddir}.;;
++*)
++  case ${ac_top_builddir}. in
++  .) ac_abs_top_builddir=$ac_abs_builddir;;
++  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
++  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
++  esac;;
++esac
++case $ac_abs_builddir in
++.) ac_abs_srcdir=$ac_srcdir;;
++*)
++  case $ac_srcdir in
++  .) ac_abs_srcdir=$ac_abs_builddir;;
++  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
++  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
++  esac;;
++esac
++case $ac_abs_builddir in
++.) ac_abs_top_srcdir=$ac_top_srcdir;;
++*)
++  case $ac_top_srcdir in
++  .) ac_abs_top_srcdir=$ac_abs_builddir;;
++  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
++  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
++  esac;;
++esac
+   { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+@@ -6161,10 +7244,10 @@
+   if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+     dirpart=`(dirname "$mf") 2>/dev/null ||
+ $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X"$mf" : 'X\(//\)[^/]' \| \
+-         X"$mf" : 'X\(//\)$' \| \
+-         X"$mf" : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X"$mf" : 'X\(//\)[^/]' \| \
++       X"$mf" : 'X\(//\)$' \| \
++       X"$mf" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X"$mf" |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+@@ -6174,36 +7257,30 @@
+   else
+     continue
+   fi
+-  grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+-  # Extract the definition of DEP_FILES from the Makefile without
+-  # running `make'.
+-  DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
++  # Extract the definition of DEPDIR, am__include, and am__quote
++  # from the Makefile without running `make'.
++  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+   test -z "$DEPDIR" && continue
++  am__include=`sed -n 's/^am__include = //p' < "$mf"`
++  test -z "am__include" && continue
++  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+   # When using ansi2knr, U may be empty or an underscore; expand it
+-  U=`sed -n -e '/^U = / s///p' < "$mf"`
+-  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+-  # We invoke sed twice because it is the simplest approach to
+-  # changing $(DEPDIR) to its actual value in the expansion.
+-  for file in `sed -n -e '
+-    /^DEP_FILES = .*\\\\$/ {
+-      s/^DEP_FILES = //
+-      :loop
+-      s/\\\\$//
+-      p
+-      n
+-      /\\\\$/ b loop
+-      p
+-    }
+-    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
++  U=`sed -n 's/^U = //p' < "$mf"`
++  # Find all dependency output files, they are included files with
++  # $(DEPDIR) in their names.  We invoke sed twice because it is the
++  # simplest approach to changing $(DEPDIR) to its actual value in the
++  # expansion.
++  for file in `sed -n "
++    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+     # Make sure the directory exists.
+     test -f "$dirpart/$file" && continue
+     fdir=`(dirname "$file") 2>/dev/null ||
+ $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X"$file" : 'X\(//\)[^/]' \| \
+-         X"$file" : 'X\(//\)$' \| \
+-         X"$file" : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X"$file" : 'X\(//\)[^/]' \| \
++       X"$file" : 'X\(//\)$' \| \
++       X"$file" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X"$file" |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+@@ -6219,10 +7296,10 @@
+       as_dirs="$as_dir $as_dirs"
+       as_dir=`(dirname "$as_dir") 2>/dev/null ||
+ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+-         X"$as_dir" : 'X\(//\)[^/]' \| \
+-         X"$as_dir" : 'X\(//\)$' \| \
+-         X"$as_dir" : 'X\(/\)' \| \
+-         .     : '\(.\)' 2>/dev/null ||
++       X"$as_dir" : 'X\(//\)[^/]' \| \
++       X"$as_dir" : 'X\(//\)$' \| \
++       X"$as_dir" : 'X\(/\)' \| \
++       .     : '\(.\)' 2>/dev/null ||
+ echo X"$as_dir" |
+     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+--- ctcs.cpp.orig      Sun Jan 15 00:28:13 2006
++++ ctcs.cpp   Thu Jan  5 20:51:00 2006
+@@ -0,0 +1,540 @@
++#ifndef WINDOWS
++#include <unistd.h>
++#include <sys/time.h>
++#include <time.h>
++#include <netdb.h>
++#endif
++
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++
++#include <ctype.h>
++
++#include "ctcs.h"
++#include "btcontent.h"
++#include "setnonblock.h"
++#include "connect_nonb.h"
++#include "tracker.h"
++#include "peerlist.h"
++#include "peer.h"
++#include "btconfig.h"
++#include "bttime.h"
++
++#define compset(a,member)  ( (a.member==member)? 0 : ((a.member = member)||1) )
++
++Ctcs CTCS;
++
++
++Ctcs::Ctcs()
++{
++  memset(m_host,0,MAXHOSTNAMELEN);
++
++  m_sock = INVALID_SOCKET;
++  m_port = 2780;
++  m_status = T_FREE;
++  m_interval = 1;
++
++  m_last_timestamp = m_sent_ctstatus_time = (time_t) 0;
++  m_sent_ctstatus = 0;
++  m_sent_ctbw = 0;
++}
++
++
++Ctcs::~Ctcs()
++{
++  if( m_sock != INVALID_SOCKET) CLOSE_SOCKET(m_sock);
++}
++
++
++void Ctcs::Reset(time_t new_interval)
++{
++  if(new_interval) m_interval = new_interval;
++
++  if( INVALID_SOCKET != m_sock ){
++    CLOSE_SOCKET(m_sock);
++    m_sock = INVALID_SOCKET;
++  }
++
++  in_buffer.Reset();
++  out_buffer.Reset();
++  m_last_timestamp = now;
++  m_sent_ctstatus = 0;
++  m_sent_ctbw = 0;
++  m_status = T_FREE;
++}
++
++
++// borrowed from tracker.cpp (with changes)
++int Ctcs:: _s2sin(char *h,int p,struct sockaddr_in *psin)
++{
++  psin->sin_family = AF_INET;
++  psin->sin_port = htons(p);
++  psin->sin_addr.s_addr = inet_addr(h);
++  if(psin->sin_addr.s_addr == INADDR_NONE){
++    struct hostent *ph = gethostbyname(h);
++    if( !ph  || ph->h_addrtype != AF_INET){
++      memset(psin,0,sizeof(struct sockaddr_in));
++      return -1;
++    }
++    memcpy(&psin->sin_addr,ph->h_addr_list[0],sizeof(struct in_addr));
++  }
++  return ( psin->sin_addr.s_addr == INADDR_NONE ) ? -1 : 0;
++}
++
++
++int Ctcs::CheckMessage()
++{
++  ssize_t r;
++  size_t q;
++
++  r = in_buffer.FeedIn(m_sock);
++
++  if( r == 0 ) return 0;      // no data
++  if( r < 0 ){ Reset(1); return -1; } // error
++
++  q = in_buffer.Count();
++
++  if( !q ){
++    int error = 0;
++    socklen_t n = sizeof(error);
++    if(getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n) < 0 ||
++       error != 0 ){
++      fprintf(stderr,"warn, received nothing from CTCS! %s\n",strerror(error));
++    }
++    Reset(0);
++    return -1;
++  }
++
++  char *s, *msgbuf;
++  while(in_buffer.Count() && (s=strchr(msgbuf=in_buffer.BasePointer(), '\n'))){
++//  msgbuf = in_buffer.BasePointer();
++//  if( s=strchr(msgbuf, '\n') ){     //have a complete message
++    *s = '\0';
++    if(arg_verbose) fprintf(stderr, "CTCS: %s\n", msgbuf);
++    if( !strncmp("SETDLIMIT",msgbuf,9) ){
++      cfg_max_bandwidth_down = (int)(strtod(msgbuf+10, NULL));
++      if(arg_verbose) fprintf(stderr, "DLimit=%d\n", cfg_max_bandwidth_down);
++    }else if( !strncmp("SETULIMIT",msgbuf,9) ){
++      cfg_max_bandwidth_up = (int)(strtod(msgbuf+10, NULL));
++      if(arg_verbose) fprintf(stderr, "ULimit=%d\n", cfg_max_bandwidth_up);
++    }else if( !strncmp("SENDPEERS",msgbuf,9) ){
++      Send_Peers();
++    }else if( !strncmp("SENDSTATUS",msgbuf,10) ){
++      Send_Status();
++    }else if( !strncmp("SENDCONF",msgbuf,8) ){
++      Send_Config();
++    }else if( !strncmp("CTCONFIG",msgbuf,8) ){
++      Set_Config(msgbuf);
++    }else if( !strncmp("SENDDETAIL",msgbuf,10) ){
++      Send_Detail();
++    }else if( !strncmp("CTQUIT",msgbuf,6) ){
++      printf("CTCS sent Quit command\n");
++      Tracker.SetStoped();
++    }else if( !strncmp("CTRESTART",msgbuf,9) ){
++      RestartTracker();
++    }else if( !strncmp("CTUPDATE",msgbuf,8) ){
++      Tracker.Reset(1);
++    }else if( !strncmp("PROTOCOL",msgbuf,8) ){
++      // nothing yet
++    }else{
++      if(arg_verbose) fprintf(stderr, "unknown CTCS message: %s", msgbuf);
++    }
++    in_buffer.PickUp(s-msgbuf + 1);
++  }
++  return 0;
++}
++
++
++int Ctcs::SendMessage(char *message)
++{
++  int len, r=0;
++  char buf[CTCS_BUFSIZE];
++
++  if( m_status == T_READY ){
++    len = strlen(message);
++    strncpy(buf, message, len);
++    if( len+1 < CTCS_BUFSIZE ){
++      buf[len] = '\n';
++      buf[len+1] = '\0';
++    }else{
++      buf[CTCS_BUFSIZE-2] = '\n';
++      buf[CTCS_BUFSIZE-1] = '\0';
++    }
++    r = out_buffer.Put(m_sock, buf, len+1);
++    if( r<0 ) Reset(1);
++  }
++  return r;
++}
++
++
++int Ctcs::Send_Auth()
++{
++  char message[CTCS_BUFSIZE];
++
++  if(!*m_pass) return 0;
++  snprintf(message, CTCS_BUFSIZE, "AUTH %s", m_pass);
++  return SendMessage(message);
++}
++
++
++int Ctcs::Send_Protocol()
++{
++  char message[CTCS_BUFSIZE];
++
++  snprintf(message, CTCS_BUFSIZE, "PROTOCOL %s", CTCS_PROTOCOL);
++  return SendMessage(message);
++}
++
++
++int Ctcs::Send_Torrent(unsigned char *peerid, char *torrent)
++{
++  char message[CTCS_BUFSIZE];
++  char txtid[PEER_ID_LEN*2+3];
++
++  TextPeerID(peerid, txtid);
++
++  snprintf(message, CTCS_BUFSIZE, "CTORRENT %s %ld %ld %s", txtid,
++    (long)(BTCONTENT.GetStartTime()), (long)now, torrent);
++  return SendMessage(message);
++}
++
++
++int Ctcs::Report_Status(size_t seeders, size_t leechers, size_t nhave,
++  size_t ntotal, size_t navail, size_t dlrate, size_t ulrate,
++  u_int64_t dltotal, u_int64_t ultotal, size_t dlimit, size_t ulimit)
++{
++  int changebw=0,change=0;
++  int r;
++  size_t nhad;
++
++  if( T_READY != m_status ) return 0;
++
++  nhad = m_ctstatus.nhave;
++
++  changebw = (
++    compset(m_ctstatus, dlrate)               |
++    compset(m_ctstatus, ulrate)               |
++    compset(m_ctstatus, dlimit)               |
++    compset(m_ctstatus, ulimit)               );
++  change = ( changebw |
++    compset(m_ctstatus, seeders)      |
++    compset(m_ctstatus, leechers)     |
++    compset(m_ctstatus, nhave)                |
++    compset(m_ctstatus, ntotal)               |
++    compset(m_ctstatus, navail)               |
++    compset(m_ctstatus, dltotal)      |
++    compset(m_ctstatus, ultotal)      );
++
++  if( ( !m_sent_ctstatus || (nhad<nhave && nhave==ntotal) ||
++        (Tracker.GetStatus() && m_sent_ctstatus_time+30 > now) ) &&
++      (r=Send_Status()) != 0 ) return r;
++  else return (changebw || !m_sent_ctbw) ? Send_bw() : 0;
++}
++
++
++int Ctcs::Send_Status()
++{
++  char message[CTCS_BUFSIZE];
++
++  if( m_sent_ctstatus_time + 1 > now ) {
++    m_sent_ctstatus = 0;
++    return 0;
++  }
++  snprintf(message, CTCS_BUFSIZE, "CTSTATUS %u/%u %u/%u/%u %u,%u %llu,%llu %u,%u",
++    m_ctstatus.seeders, m_ctstatus.leechers,
++    m_ctstatus.nhave, m_ctstatus.ntotal, m_ctstatus.navail,
++    m_ctstatus.dlrate, m_ctstatus.ulrate,
++    m_ctstatus.dltotal, m_ctstatus.ultotal,
++    m_ctstatus.dlimit, m_ctstatus.ulimit );
++  m_sent_ctstatus = 1;
++  m_sent_ctstatus_time = now;
++  return SendMessage(message);
++}
++
++
++int Ctcs::Send_bw()
++{
++  char message[CTCS_BUFSIZE];
++
++  snprintf(message, CTCS_BUFSIZE, "CTBW %u,%u %u,%u",
++    m_ctstatus.dlrate, m_ctstatus.ulrate,
++    m_ctstatus.dlimit, m_ctstatus.ulimit );
++  m_sent_ctbw = 1;
++  return SendMessage(message);
++}
++
++
++int Ctcs::Send_Config()
++{
++  char message[CTCS_BUFSIZE];
++
++  snprintf(message, CTCS_BUFSIZE, "CTCONFIG %d %d %f %d %d %d %d %d %d",
++    (int)arg_verbose, (int)cfg_seed_hours, cfg_seed_ratio,
++    (int)cfg_max_peers, (int)cfg_min_peers, (int)arg_file_to_download,
++    (int)cfg_exit_zero_peers, Tracker.IsPaused(), Tracker.IsQuitting());
++  return SendMessage(message);
++}
++
++int Ctcs::Set_Config(char *msgbuf)
++{
++  unsigned char foo;
++
++  if(msgbuf[9] != '.') arg_verbose = atoi(msgbuf+9);
++  if(msgbuf[11] != '.') cfg_seed_hours = atoi(msgbuf+11);
++  msgbuf = strchr(msgbuf+11, ' ') + 1;
++  if(msgbuf[0] != '.') cfg_seed_ratio = atof(msgbuf);
++  msgbuf = strchr(msgbuf, ' ') + 1;
++  if(msgbuf[0] != '.') cfg_max_peers = atoi(msgbuf);
++  msgbuf = strchr(msgbuf, ' ') + 1;
++  if(msgbuf[0] != '.') cfg_min_peers = atoi(msgbuf);
++  msgbuf = strchr(msgbuf, ' ') + 1;
++  if(msgbuf[0] != '.'){
++    foo = atoi(msgbuf);
++    if(foo != arg_file_to_download){
++      arg_file_to_download = foo;
++      BTCONTENT.FlushCache();
++      BTCONTENT.SetFilter();
++      WORLD.CheckInterest();
++    }
++  }
++  msgbuf = strchr(msgbuf, ' ') + 1;
++  if(msgbuf[0] != '.') cfg_exit_zero_peers = atoi(msgbuf);
++  msgbuf = strchr(msgbuf, ' ') + 1;
++  if(msgbuf[0] != '.'){
++    if(atoi(msgbuf)){
++      if( !Tracker.IsPaused() ) Tracker.SetPause();
++    }else if( Tracker.IsPaused() ) Tracker.Resume();
++  }
++  msgbuf = strchr(msgbuf, ' ') + 1;
++  if(msgbuf[0] != '.'){
++    if(atoi(msgbuf)) Tracker.SoftQuit();
++    else Tracker.DontQuit();
++    if(atoi(msgbuf)){
++      if( !Tracker.IsQuitting() ) Tracker.SoftQuit();
++    }else if( Tracker.IsQuitting() ) Tracker.DontQuit();
++  }
++
++  return 0;
++}
++
++
++int Ctcs::Send_Detail()
++{
++  char message[CTCS_BUFSIZE];
++  int r=0;
++  size_t n=0;
++  BTFILE *file=0;
++  BitField tmpFilter;
++
++  snprintf( message, CTCS_BUFSIZE, "CTDETAIL %lld %d %ld %ld",
++    BTCONTENT.GetTotalFilesLength(),
++    (int)(BTCONTENT.GetPieceLength()), (long)now,
++    (long)(BTCONTENT.GetSeedTime()) );
++  r = SendMessage(message);
++
++  if(r==0) r = SendMessage("CTFILES");
++
++  while( r==0 && (file = BTCONTENT.GetNextFile(file)) ){
++    ++n;
++    BTCONTENT.SetTmpFilter(n, &tmpFilter);
++    BitField tmpBitField = *BTCONTENT.pBF;
++    tmpBitField.Except(tmpFilter);
++
++    snprintf( message, CTCS_BUFSIZE, "CTFILE %u %d %d %llu %s",
++      n, (int)(BTCONTENT.getFilePieces(n)),
++      (int)(tmpBitField.Count()),
++      file->bf_length, file->bf_filename );
++    r = SendMessage(message);
++  }
++  if(r==0) r = SendMessage("CTFDONE");
++  return r;
++}
++
++
++int Ctcs::Send_Peers()
++{
++  btPeer *peer=0;
++  char message[CTCS_BUFSIZE];
++  char txtid[PEER_ID_LEN*2+3];
++  struct sockaddr_in psin;
++  int r=0;
++
++  r=SendMessage("CTPEERS");
++  while( r==0 && (peer = WORLD.GetNextPeer(peer)) ){
++    TextPeerID(peer->id, txtid);
++     peer->GetAddress(&psin);
++
++     snprintf(message, CTCS_BUFSIZE, "CTPEER %s %s %c%c%c%c %d %d %llu %llu %d",
++       txtid, inet_ntoa(psin.sin_addr),
++       peer->Is_Remote_UnChoked() ? 'U' : 'C',
++       peer->Is_Local_Interested() ? 'i' : 'n',
++       peer->Is_Local_UnChoked() ? 'U' : 'C',
++       peer->Is_Remote_Interested() ? 'i' : 'n',
++       peer->RateDL(), peer->RateUL(),
++       peer->TotalDL(), peer->TotalUL(),
++       peer->bitfield.Count() );
++     r = SendMessage(message);
++  }
++  if(r==0) r = SendMessage("CTPDONE");
++  return r;
++}
++
++
++int Ctcs::Send_Info(const char *info)
++{
++  char message[CTCS_BUFSIZE];
++
++  snprintf(message, CTCS_BUFSIZE, "CTINFO %s", info);
++  return SendMessage(message);
++}
++
++
++int Ctcs::Initial()
++{
++  char *s;
++
++  strncpy(m_host, arg_ctcs, MAXHOSTNAMELEN-1);
++  m_host[MAXHOSTNAMELEN-1] = '\0';
++  if( s = strchr(m_host, ':') ) *s='\0';
++  m_port = atoi(s=(strchr(arg_ctcs, ':')+1));
++  if(strchr(s, ':')){
++    printf("Enter CTCS password: "); fflush(stdout);
++    fgets(m_pass, CTCS_PASS_SIZE, stdin);
++  } else *m_pass = '\0';
++
++  return 0;
++}
++
++
++int Ctcs::Connect()
++{
++  ssize_t r;
++  m_last_timestamp = now;
++
++  if(_s2sin(m_host,m_port,&m_sin) < 0) {
++    fprintf(stderr,"warn, get CTCS ip address failed.");
++    return -1;
++  }
++
++  m_sock = socket(AF_INET,SOCK_STREAM,0);
++  if(INVALID_SOCKET == m_sock) return -1;
++
++  if(setfd_nonblock(m_sock) < 0) {CLOSE_SOCKET(m_sock); return -1; }
++
++  r = connect_nonb(m_sock,(struct sockaddr*)&m_sin);
++
++  if( r == -1 ){ CLOSE_SOCKET(m_sock); return -1;}
++  else if( r == -2 ) m_status = T_CONNECTING;
++  else{
++    m_status = T_READY;
++    if( Send_Protocol() != 0 ){
++      fprintf(stderr,"warn, send protocol to CTCS failed. %s\n",strerror(errno));
++      return -1;
++    }
++    if( Send_Auth() != 0) {
++      fprintf(stderr,"warn, send password to CTCS failed. %s\n",strerror(errno));
++      return -1;
++    }
++    if( Send_Torrent(BTCONTENT.GetPeerId(), arg_metainfo_file) != 0 ){
++      fprintf(stderr,"warn, send torrent to CTCS failed. %s\n",strerror(errno));
++      return -1;
++    }
++  }
++  return 0;
++}
++
++
++int Ctcs::IntervalCheck(const time_t *pnow, fd_set *rfdp, fd_set *wfdp)
++{
++  if( T_FREE == m_status ){
++    if(*pnow - m_last_timestamp >= m_interval){
++      if(Connect() < 0){ Reset(15); return -1; }
++
++      if( m_status == T_CONNECTING ){
++        FD_SET(m_sock, rfdp);
++        FD_SET(m_sock, wfdp);
++      }else{
++        FD_SET(m_sock, rfdp);
++      }
++    }
++  }else{
++    if( m_status == T_CONNECTING ){
++      FD_SET(m_sock, rfdp);
++      FD_SET(m_sock, wfdp);
++    }else if (INVALID_SOCKET != m_sock){
++      FD_SET(m_sock, rfdp);
++      if( out_buffer.Count() ) FD_SET(m_sock, wfdp);
++    }
++  }
++  return m_sock;
++}
++
++
++int Ctcs::SocketReady(fd_set *rfdp, fd_set *wfdp, int *nfds)
++{
++  if( T_FREE == m_status ) return 0;
++
++  if( T_CONNECTING == m_status && FD_ISSET(m_sock,wfdp) ){
++    int error = 0;
++    socklen_t n = sizeof(error);
++    (*nfds)--;
++    FD_CLR(m_sock, wfdp); 
++    if(getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n) < 0 ||
++       error != 0 ){
++      if( ECONNREFUSED != error )
++        fprintf(stderr,"warn, connect to CTCS failed. %s\n",strerror(error));
++      Reset(15);
++      return -1;
++    }else{
++      m_status = T_READY; 
++      if( Send_Protocol() != 0 ){
++        fprintf(stderr,"warn, send protocol to CTCS failed. %s\n",strerror(errno));
++        return -1;
++      }
++      if( Send_Auth() != 0) {
++        fprintf(stderr,"warn, send password to CTCS failed. %s\n",strerror(errno));
++        return -1;
++      }
++      if( Send_Torrent(BTCONTENT.GetPeerId(), arg_metainfo_file) == 0 ){
++        fprintf(stderr,"warn, send torrent to CTCS failed. %s\n",strerror(errno));
++        return -1;
++      }
++    }
++  }else if( T_CONNECTING == m_status && FD_ISSET(m_sock,rfdp) ){
++    int error = 0;
++    socklen_t n = sizeof(error);
++    (*nfds)--;
++    FD_CLR(m_sock, rfdp);
++    getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n);
++    fprintf(stderr,"warn, connect to CTCS failed. %s\n",strerror(error));
++    Reset(15);
++    return -1;
++  }else if( INVALID_SOCKET != m_sock ){
++    if( FD_ISSET(m_sock, rfdp) ){
++      (*nfds)--;
++      FD_CLR(m_sock,rfdp);
++      CheckMessage();
++    }
++    if( INVALID_SOCKET != m_sock && FD_ISSET(m_sock, wfdp) ){
++      (*nfds)--;
++      FD_CLR(m_sock,wfdp);
++      if( out_buffer.Count() && out_buffer.FlushOut(m_sock) < 0){
++        Reset(1);
++        return -1;
++      }
++    }
++  }
++  return 0;
++}
++
++
++void Ctcs::RestartTracker()
++{
++  Tracker.SetPause();  // prevents downloader from exiting
++  Tracker.SetStoped(); // finish the tracker
++  // Now we need to wait until the tracker updates (T_FINISHED == m_status),
++  // then Tracker.Resume().
++  Tracker.SetRestart();
++}
++
+--- ctcs.h.orig        Sun Jan 15 00:28:13 2006
++++ ctcs.h     Mon Nov 14 20:40:00 2005
+@@ -0,0 +1,78 @@
++#include "tracker.h"  // for its includes/defines
++
++#define CTCS_PROTOCOL "0001"
++
++#define CTCS_BUFSIZE 200
++#define CTCS_PASS_SIZE 21
++
++#define C_TORRENT     1
++#define C_STATUS      2
++#define C_PEERS               3
++
++struct ctstatus {
++ public:
++  size_t seeders, leechers, nhave, ntotal, navail, dlrate, ulrate,
++    dlimit, ulimit;
++  u_int64_t dltotal, ultotal;
++  ctstatus() {
++    seeders=leechers=nhave=ntotal=navail=dlrate=ulrate=dltotal=
++    ultotal=dlimit=ulimit = 0;
++  }
++};
++
++class Ctcs
++{
++ private:
++  char m_host[MAXHOSTNAMELEN];
++  int m_port;
++  char m_pass[CTCS_PASS_SIZE];
++
++  struct sockaddr_in m_sin;
++
++  unsigned char m_status:2;
++
++  time_t m_interval;
++  time_t m_last_timestamp;
++  time_t m_sent_ctstatus_time;
++
++  SOCKET m_sock;
++  BufIo in_buffer;
++  BufIo out_buffer;
++  struct ctstatus m_ctstatus;
++  int m_sent_ctstatus;
++  int m_sent_ctbw;
++
++  int SendMessage(char *buf);
++
++ public:
++  Ctcs();
++  ~Ctcs();
++
++  void Reset(time_t new_interval);
++  int _s2sin(char *h,int p,struct sockaddr_in *psin);
++  int Initial();
++  int Connect();
++  int CheckMessage();
++  int Send_Protocol();
++  int Send_Auth();
++  int Send_Torrent(unsigned char *peerid, char *torrent);
++  int Report_Status(size_t seeders, size_t leechers, size_t nhave,
++    size_t ntotal, size_t navail, size_t dlrate, size_t ulrate,
++    u_int64_t dltotal, u_int64_t ultotal, size_t dlimit, size_t ulimit);
++  int Send_Status();
++  int Send_bw();
++  int Send_Config();
++  int Set_Config(char *msgbuf);
++  int Send_Detail();
++  int Send_Peers();
++  int Send_Info(const char *info);
++  int IntervalCheck(const time_t *pnow, fd_set *rfdp, fd_set *wfdp);
++  int SocketReady(fd_set *rfdp, fd_set *wfdp, int *nfds);
++  void RestartTracker();
++
++  SOCKET GetSocket() { return m_sock; }
++  unsigned char GetStatus() { return m_status;}
++};
++
++extern Ctcs CTCS;
++
+--- ctorrent.cpp.orig  Wed Sep  8 16:10:51 2004
++++ ctorrent.cpp       Sat Dec 24 19:03:58 2005
+@@ -1,6 +1,5 @@
+-#include <sys/types.h>
+-
+ #include "./def.h"
++#include <sys/types.h>
+ #ifdef WINDOWS
+ #include <windows.h>
+@@ -20,6 +19,7 @@
+ #include "downloader.h"
+ #include "peerlist.h"
+ #include "tracker.h"
++#include "ctcs.h"
+ #include "./config.h"
+@@ -46,7 +46,7 @@
+   struct timeval tv; 
+   gettimeofday(&tv,(struct timezone*) 0);
+   unsigned int seed = tv.tv_usec + tv.tv_sec + getpid();
+-  return srandom(seed);
++  srandom(seed);
+ }
+ int main(int argc, char **argv)
+@@ -65,7 +65,7 @@
+     if( !arg_announce ){ fprintf(stderr,"please use -u to specify a announce url!\n"); exit(1);}
+     if( !arg_save_as ){ fprintf(stderr,"please use -s to specify a metainfo file name!\n"); exit(1);}
+     if( BTCONTENT.InitialFromFS(arg_metainfo_file, arg_announce,  arg_piece_length) < 0 ||
+-      BTCONTENT.CreateMetainfoFile(arg_save_as) < 0){
++        BTCONTENT.CreateMetainfoFile(arg_save_as) < 0){
+       fprintf(stderr,"create metainfo failed.\n");
+       exit(1);
+     }
+@@ -81,15 +81,19 @@
+   if( !arg_flg_exam_only && !arg_flg_check_only){
+     if(WORLD.Initial_ListenPort() < 0){
+       fprintf(stderr,"warn, you couldn't accept connection.\n");
+-    }else 
+-      printf("Listen on: %d\n",cfg_listen_port);
++    }
+-      Tracker.Initial();
++    if( arg_ctcs ) CTCS.Initial();
++        Tracker.Initial();
+-      signal(SIGPIPE,SIG_IGN);
+-    signal(SIGINT,sigint_catch);
++        signal(SIGPIPE,SIG_IGN);
++    signal(SIGINT,sig_catch);
++    signal(SIGTERM,sig_catch);
+     Downloader();
+   }
++  if( cfg_cache_size ) BTCONTENT.FlushCache();
++  if( arg_bitfield_file ) BTCONTENT.pBF->WriteToFile(arg_bitfield_file);
++  WORLD.CloseAll();
+   exit(0);
+ }
+@@ -99,7 +103,8 @@
+ int param_check(int argc, char **argv)
+ {
+   int c, l;
+-  while ( ( c = getopt(argc,argv,"b:B:cC:e:fl:M:m:P:p:s:tu:xhH")) != -1)
++  char *s;
++  while ( ( c = getopt(argc,argv,"b:cC:D:e:E:fi:l:M:m:n:P:p:s:S:tu:U:vxz:hH")) != -1)
+     switch( c ){
+     case 'b':
+       arg_bitfield_file = new char[strlen(optarg) + 1];
+@@ -109,6 +114,10 @@
+       strcpy(arg_bitfield_file, optarg);
+       break;
++    case 'i':                  // listen on ip XXXX
++      cfg_listen_ip = inet_addr(optarg);
++      break;
++
+     case 'p':                 // listen on Port XXXX
+       cfg_listen_port = atoi(optarg);
+       break;
+@@ -126,6 +135,10 @@
+       cfg_seed_hours = atoi(optarg);
+       break;
++    case 'E':                 // target seed ratio
++      cfg_seed_ratio = atof(optarg);
++      break;
++
+     case 'c':                 // Check exist only
+       arg_flg_check_only = 1;
+       break;
+@@ -137,32 +150,47 @@
+     case 'M':                 // Max peers
+       cfg_max_peers = atoi(optarg);
+       if( cfg_max_peers > 1000 ||
+-        cfg_max_peers < 20){
+-      return -1;
++          cfg_max_peers < 20){
++        return -1;
+       }
+       break;
+       
+     case 'm':                 // Min peers
+       cfg_min_peers = atoi(optarg);
+       if( cfg_min_peers > 1000 ||
+-        cfg_min_peers < 20){
+-      return -1;
++          cfg_min_peers < 1){
++        return -1;
+       }
+       break;
++    case 'z':                 // slice size
++      cfg_req_slice_size = atoi(optarg) * 1024;
++      if( cfg_req_slice_size < 1024 || cfg_req_slice_size > 128*1024 )
++        return -1;
++      break;
++
++    case 'n':                  // Which file download
++      arg_file_to_download = atoi(optarg);
++    break;
++
++
+     case 'f':                 // force seed mode, skip sha1 check when startup.
+       arg_flg_force_seed_mode = 1;
+       break;
+       
+-    case 'B':
+-      cfg_max_bandwidth = atoi(optarg);
++    case 'D':
++      cfg_max_bandwidth_down = (int)(strtod(optarg, NULL) * 1024);
++      break;
++
++    case 'U':
++      cfg_max_bandwidth_up = (int)(strtod(optarg, NULL) * 1024);
+       break;
+     case 'P':
+-              l = strlen(optarg);
+-              if (l > MAX_PF_LEN) {printf("-P arg must be 8 or less characters\n"); exit(1);}
+-              if (l == 1 && *optarg == '-') *arg_user_agent = (char) 0;
+-              else strcpy(arg_user_agent,optarg);
++      l = strlen(optarg);
++      if (l > MAX_PF_LEN) {printf("-P arg must be 8 or less characters\n"); exit(1);}
++      if (l == 1 && *optarg == '-') *arg_user_agent = (char) 0;
++      else strcpy(arg_user_agent,optarg);
+       break;
+      // BELLOW OPTIONS USED FOR CREATE TORRENT.
+@@ -179,17 +207,29 @@
+     case 'l':                 // piece Length (default 262144)
+       arg_piece_length = atoi(optarg);
+       if( arg_piece_length < 65536 ||
+-        arg_piece_length > 1310720 ){
+-      // warn message:
+-      // piece length range is 65536 =>> 1310720
+-      return -1;
++          arg_piece_length > 1310720 ){
++        // warn message:
++        // piece length range is 65536 =>> 1310720
++        return -1;
+       }
+       break;
++     // ABOVE OPTIONS USED FOR CREATE TORRENT.
+     case 'x':
+       arg_flg_exam_only = 1;
+       break;
++    case 'S':                 // CTCS server
++      if( arg_ctcs ) return -1;
++      arg_ctcs = new char[strlen(optarg) + 1];
++      if( !strchr(optarg, ':') ) return -1;
++      strcpy(arg_ctcs, optarg);
++      break;
++
++    case 'v':
++      arg_verbose = 1;
++      break;
++
+     case 'h':
+     case 'H':
+     default:
+@@ -211,14 +251,17 @@
+ void usage()
+ {
+-  fprintf(stderr,"%s          Copyright: YuHong(992126018601033)",PACKAGE_STRING);
++  fprintf(stderr,"%s  Original code Copyright: YuHong(992126018601033)",PACKAGE_STRING);
+   fprintf(stderr,"\nWARNING: THERE IS NO WARRANTY FOR CTorrent. USE AT YOUR OWN RISK!!!\n");
+   fprintf(stderr,"\nGeneric Options:\n");
+   fprintf(stderr,"-h/-H\t\tShow this message.\n");
+   fprintf(stderr,"-x\t\tDecode metainfo(torrent) file only, don't download.\n");
+   fprintf(stderr,"-c\t\tCheck exist only. don't download.\n");
++  fprintf(stderr,"-v\t\tVerbose output (for debugging).\n");
+   fprintf(stderr,"\nDownload Options:\n");
+   fprintf(stderr,"-e int\t\tExit while seed <int> hours later. (default 72 hours)\n");
++  fprintf(stderr,"-E num\t\tExit after seeding to <num> ratio (UL:DL).\n");
++  fprintf(stderr,"-i ip\t\tListen for connection on ip. (default all ip's)\n");
+   fprintf(stderr,"-p port\t\tListen port. (default 2706 -> 2106)\n");
+   fprintf(stderr,"-s save_as\tSave file/directory/metainfo as... \n");
+   fprintf(stderr,"-C cache_size\tCache size,unit MB. (default 16MB)\n");
+@@ -226,8 +269,12 @@
+   fprintf(stderr,"-b bf_filename\tBit field filename. (use it carefully)\n");
+   fprintf(stderr,"-M max_peers\tMax peers count.\n");
+   fprintf(stderr,"-m min_peers\tMin peers count.\n");
+-  fprintf(stderr,"-B rate\t\tMax bandwidth (unit KB/s)\n");
++  fprintf(stderr,"-z slice_size\tDownload slice/block size, unit KB. (default 16, max 128).\n");
++  fprintf(stderr,"-n file_number\tWhich file download.\n");
++  fprintf(stderr,"-D rate\t\tMax bandwidth down (unit KB/s)\n");
++  fprintf(stderr,"-U rate\t\tMax bandwidth up (unit KB/s)\n");
+   fprintf(stderr,"-P peer_id\tSet Peer ID ["PEER_PFX"]\n");
++  fprintf(stderr,"-S host:port\tUse CTCS server\n");
+   fprintf(stderr,"\nMake metainfo(torrent) file Options:\n");
+   fprintf(stderr,"-t\t\tWith make torrent. must specify this option.\n");
+   fprintf(stderr,"-u url\t\tTracker's url.\n");
+@@ -235,5 +282,7 @@
+   fprintf(stderr,"\neg.\n");
+   fprintf(stderr,"hong> ctorrent -s new_filename -e 12 -C 32 -p 6881 eg.torrent\n\n");
+   fprintf(stderr,"home page: http://ctorrent.sourceforge.net/\n");
+-  fprintf(stderr,"bug report: %s\n\n",PACKAGE_BUGREPORT);
++  fprintf(stderr,"see also: http://www.rahul.net/dholmes/ctorrent/\n");
++  fprintf(stderr,"bug report: %s\n",PACKAGE_BUGREPORT);
++  fprintf(stderr,"original author: bsdi@sina.com\n\n");
+ }
+--- downloader.cpp.orig        Wed Sep  8 16:10:51 2004
++++ downloader.cpp     Sun Jan  1 18:48:31 2006
+@@ -21,21 +21,37 @@
+ #include "peerlist.h"
+ #include "tracker.h"
+ #include "btcontent.h"
++#include "ctcs.h"
++#include "btconfig.h"
++#include "bttime.h"
++
++time_t now = (time_t) 0;
+ void Downloader()
+ {
+   int nfds,maxfd,r;
+   struct timeval timeout;
+-  time_t now;
+   fd_set rfd;
+   fd_set wfd;
++  int stopped = 0;
+-  for(;;){
+-    time(&now);
+-    if( BTCONTENT.SeedTimeout(&now) ) break;
++  time(&now);
++  do{
++    if( !stopped &&
++        ( BTCONTENT.SeedTimeout(&now) ||
++          (( cfg_exit_zero_peers || Tracker.IsQuitting() ) &&
++            !WORLD.TotalPeers()) ) ){
++        Tracker.SetStoped();
++        stopped = 1;
++        if( arg_ctcs ) CTCS.Send_Status();
++    }
+     
+     FD_ZERO(&rfd); FD_ZERO(&wfd);
+     maxfd = Tracker.IntervalCheck(&now,&rfd, &wfd);
++    if( arg_ctcs ){
++      r = CTCS.IntervalCheck(&now,&rfd, &wfd);
++      if( r > maxfd ) maxfd = r;
++    }
+     r = WORLD.FillFDSET(&now,&rfd,&wfd);
+     if( r > maxfd ) maxfd = r;
+@@ -43,10 +59,13 @@
+     timeout.tv_usec = 0;
+     nfds = select(maxfd + 1,&rfd,&wfd,(fd_set*) 0,&timeout);
++    time(&now);
+-      if(nfds > 0){
++    if(nfds > 0){
+       if(T_FREE != Tracker.GetStatus()) Tracker.SocketReady(&rfd,&wfd,&nfds);
+-        if( nfds ) WORLD.AnyPeerReady(&rfd,&wfd,&nfds);
+-      }
+-  }/* end for(;;) */
++      if(nfds > 0 && T_FREE != CTCS.GetStatus())
++        CTCS.SocketReady(&rfd,&wfd,&nfds);
++      if(nfds > 0) WORLD.AnyPeerReady(&rfd,&wfd,&nfds);
++    }
++  } while(Tracker.GetStatus() != T_FINISHED || Tracker.IsPaused());
+ }
+--- httpencode.cpp.orig        Wed Sep  8 16:10:51 2004
++++ httpencode.cpp     Sat Dec 24 19:05:26 2005
+@@ -1,6 +1,6 @@
++#include "./def.h"
+ #include <sys/types.h>
+-#include "./def.h"
+ #include "./httpencode.h"
+ #include <stdlib.h>
+@@ -88,7 +88,7 @@
+   /* path */
+   if( *p != '/' ) return -1;
+-  for( ; *p && *p != '?'; p++,path++) *path = *p;
++  for( ; *p; p++,path++) *path = *p;
+   *path = '\0';
+   return 0;
+ }
+@@ -115,7 +115,7 @@
+       hlen = p - b;
+       *pd = ( p + addtion );
+       *dlen = n - hlen - addtion;
+-    }else{                    // Ö»ÓÐÊײ¿ÐÅÏ¢????
++    }else{            // Ö»ÓÐÊײ¿ÐÅÏ¢????
+       hlen = n;
+       *pd = (char*) 0;
+       *dlen = 0;
+@@ -131,8 +131,8 @@
+   for(; n && *b != ' ' && *b != '\n'; b++,n--) ;
+   if( !n || *b != ' ') r = -1;
+   else{
+-        r = atoi(b);
+-        if( r < 100 || r > 600 ) r = -1;
++          r = atoi(b);
++          if( r < 100 || r > 600 ) r = -1;
+   }
+   return r;
+ }
+@@ -160,11 +160,11 @@
+   
+     if( r > header_len ){
+       if( strncasecmp(b, h, header_len) == 0){
+-      /* header founded */
+-      b += header_len;
+-      for(; *b != '\n'; v++,b++) *v = *b;
+-      *v = '\0';
+-      return 0;
++        /* header founded */
++        b += header_len;
++        for(; *b != '\n'; v++,b++) *v = *b;
++        *v = '\0';
++        return 0;
+       }
+     }
+     b += r;
+--- httpencode.h.orig  Wed Sep  8 16:10:51 2004
++++ httpencode.h       Sat Dec 17 09:08:53 2005
+@@ -1,9 +1,13 @@
+ #ifndef HTTPENCODE_H
+ #define HTTPENCODE_H
+-#define REQ_URL_P1_FMT "GET %s?info_hash=%s&peer_id=%s&port=%d"
+-#define REQ_URL_P2_FMT "%s&uploaded=%d&downloaded=%d&left=%d&event=%s&compact=1 HTTP/1.0"
+-#define REQ_URL_P3_FMT "%s&uploaded=%d&downloaded=%d&left=%d&compact=1 HTTP/1.0"
++#define REQ_URL_P1_FMT "GET %s?info_hash=%s&peer_id=%s&port=%d&key=%s"
++#define REQ_URL_P1A_FMT "GET %s&info_hash=%s&peer_id=%s&port=%d&key=%s"
++//#define REQ_URL_P2_FMT "%s&uploaded=%d&downloaded=%d&left=%d&event=%s&compact=1 HTTP/1.0"
++//#define REQ_URL_P3_FMT "%s&uploaded=%d&downloaded=%d&left=%d&compact=1 HTTP/1.0"
++#define REQ_URL_P2_FMT "%s&uploaded=%llu&downloaded=%llu&left=%llu&compact=1&event=%s&numwant=%u&key=%s HTTP/1.0"
++#define REQ_URL_P3_FMT "%s&uploaded=%llu&downloaded=%llu&left=%llu&compact=1&numwant=%u&key=%s HTTP/1.0"
++
+ char* Http_url_encode(char *s,char *b,size_t n);
+ int Http_url_analyse(char *url,char *host,int *port,char *path);
+--- iplist.cpp.orig    Wed Sep  8 16:10:51 2004
++++ iplist.cpp Tue Jun 21 20:37:00 2005
+@@ -8,8 +8,8 @@
+   IPLIST *node = ipl_head;
+   for(; ipl_head;){
+     node = ipl_head;
+-    delete ipl_head;
+     ipl_head = node->next;
++    delete node;
+   }
+   count = 0;
+ }
+--- peer.cpp.orig      Wed Sep  8 16:10:51 2004
++++ peer.cpp   Mon Jan  2 14:40:24 2006
+@@ -2,14 +2,74 @@
+ #include <stdlib.h>
+ #include <string.h>
++#include <ctype.h>
++#include "btstream.h"
+ #include "./btcontent.h"
+ #include "./msgencode.h"
+ #include "./peerlist.h"
+ #include "./btconfig.h"
++#include "bttime.h"
++size_t get_nl(char *sfrom)
++{
++  unsigned char *from = (unsigned char *)sfrom;
++  size_t t;
++  t = (*from++) << 24;
++  t |= (*from++) << 16;
++  t |= (*from++) << 8;
++  t |= *from;
++  return t;
++}
++
++void set_nl(char *sto, size_t from)
++{
++  unsigned char *to = (unsigned char *)sto;
++  *to++ = (from >> 24) & 0xff;
++  *to++ = (from >> 16) & 0xff;
++  *to++ = (from >> 8) & 0xff;
++  *to = from & 0xff;
++}
++
++// Convert a peer ID to a printable string.
++int TextPeerID(unsigned char *peerid, char *txtid)
++{
++  int i, j;
++
++  for(i=j=0; i < PEER_ID_LEN; i++){
++    if( i==j && isprint(peerid[i]) && !isspace(peerid[i]) )
++      txtid[j++] = peerid[i];
++    else{
++      if(i==j){ sprintf(txtid+j, "0x"); j+=2; }
++      snprintf(txtid+j, 3, "%.2X", (int)(peerid[i]));
++      j += 2;
++    }
++  }
++  txtid[j] = '\0';
++
++  return 0;
++}
++
++
++/* g_next_up is used to rotate uploading.  If we have the opportunity to
++   upload to a peer but skip it due to bw limiting, the var is set to point to
++   that peer and it will be given priority at the next opportunity.
++   g_next_dn is similar, but for downloading.
++   g_defer_up/dn is used to let the g_next peer object know if it skipped.
++*/
++btPeer *g_next_up = (btPeer *)0;
++btPeer *g_next_dn = (btPeer *)0;
++unsigned char g_defer_up = 0;
++unsigned char g_defer_dn = 0;
+ btBasic Self;
++void btBasic::SetCurrentRates()
++{
++  m_current_dl = rate_dl.RateMeasure();
++  m_current_ul = rate_ul.RateMeasure();
++  m_use_current = 1;
++}
++
+ void btBasic::SetIp(struct sockaddr_in addr)
+ {
+   memcpy(&m_sin.sin_addr,&addr.sin_addr,sizeof(struct in_addr));
+@@ -24,7 +84,7 @@
+ {
+ //    fprintf(stdout,"IpEquiv: %s <=> ", inet_ntoa(m_sin.sin_addr));
+ //    fprintf(stdout,"%s\n", inet_ntoa(addr.sin_addr));
+-      return (memcmp(&m_sin.sin_addr,&addr.sin_addr,sizeof(struct in_addr)) == 0) ? 
++        return (memcmp(&m_sin.sin_addr,&addr.sin_addr,sizeof(struct in_addr)) == 0) ? 
+     1 : 0;
+ }
+@@ -44,11 +104,13 @@
+ int btPeer::Need_Remote_Data()
+ {
++
+   if( BTCONTENT.pBF->IsFull()) return 0;
+   else if( bitfield.IsFull() ) return 1;
+   else{
+     BitField tmpBitfield = bitfield;
+     tmpBitfield.Except(*BTCONTENT.pBF);
++    tmpBitfield.Except(*BTCONTENT.pBFilter);
+     return tmpBitfield.IsEmpty() ? 0 : 1;
+   }
+   return 0;
+@@ -59,12 +121,19 @@
+   m_f_keepalive = 0;
+   m_status = P_CONNECTING;
+   m_unchoke_timestamp = (time_t) 0;
+-  time(&m_last_timestamp);
++  m_last_timestamp = now;
+   m_state.remote_choked = m_state.local_choked = 1;
+   m_state.remote_interested = m_state.local_interested = 0;
+   m_err_count = 0;
+   m_cached_idx = BTCONTENT.GetNPieces();
++  m_standby = 0;
++  m_req_send = 5;
++  m_req_out = 0;
++  m_latency = 0;
++  m_prev_dlrate = 0;
++  m_health_time = m_receive_time = m_choketime = m_last_timestamp;
++  m_bad_health = 0;
+ }
+ int btPeer::SetLocal(unsigned char s)
+@@ -72,21 +141,37 @@
+   switch(s){
+   case M_CHOKE:
+     if( m_state.local_choked ) return 0;
++    m_unchoke_timestamp = now;
++//  if(arg_verbose) fprintf(stderr, "Choking %p\n", this);
++    if(arg_verbose) fprintf(stderr, "Choking %p (D=%lluMB@%uK/s)\n", this,
++      TotalDL() >> 20, RateDL() >> 10);
+     m_state.local_choked = 1; 
++    if( g_next_up == this ) g_next_up = (btPeer *)0;
++    if( !reponse_q.IsEmpty()) reponse_q.Empty();
+     break;
+   case M_UNCHOKE: 
+     if( !reponse_q.IsEmpty() ) StartULTimer();
+     if( !m_state.local_choked ) return 0;
+-    time(&m_unchoke_timestamp);
++    m_unchoke_timestamp = now;
++//  if(arg_verbose) fprintf(stderr, "Unchoking %p\n", this);
++    if(arg_verbose) fprintf(stderr, "Unchoking %p (D=%lluMB@%uK/s)\n", this,
++      TotalDL() >> 20, RateDL() >> 10);
+     m_state.local_choked = 0;
+     break;
+   case M_INTERESTED: 
++    m_standby = 0;
+     if( m_state.local_interested ) return 0;
++    if(arg_verbose) fprintf(stderr, "Interested in %p\n", this);
+     m_state.local_interested = 1;
+     break;
+   case M_NOT_INTERESTED:
+     if( !m_state.local_interested ) return 0;
++    if(arg_verbose) fprintf(stderr, "Not interested in %p\n", this);
+     m_state.local_interested = 0; 
++    if( !request_q.IsEmpty() ){
++      CancelRequest(request_q.GetHead());
++      request_q.Empty();
++    }
+     break;
+   default:
+     return -1;                        // BUG ???
+@@ -97,103 +182,195 @@
+ int btPeer::RequestPiece()
+ {
+   size_t idx;
++  int endgame = 0;
+-  PENDINGQUEUE.ReAssign(&request_q,bitfield);
++  size_t qsize = request_q.Qsize();
++  size_t psize = BTCONTENT.GetPieceLength() / cfg_req_slice_size;
+-  if( !request_q.IsEmpty() ) return SendRequest();
++  // See if there's room in the queue for a new piece.
++  // Also, don't queue another piece if we still have a full piece queued.
++  if( cfg_req_queue_length - qsize < psize || qsize >= psize ){
++    m_req_send = m_req_out;   // don't come back until you receive something.
++    return 0;
++  }
++
++  if( PENDINGQUEUE.ReAssign(&request_q,bitfield) ){
++    if(arg_verbose) fprintf(stderr, "Assigning to %p from Pending\n", this);
++    return SendRequest();
++  }
+-  if( m_cached_idx < BTCONTENT.GetNPieces() ){
++  if( m_cached_idx < BTCONTENT.GetNPieces() && !BTCONTENT.pBF->IsEmpty() ){
++    // A HAVE msg already selected what we want from this peer
++    // but ignore it in initial-piece mode.
+     idx = m_cached_idx;
+     m_cached_idx = BTCONTENT.GetNPieces();
+     if( !BTCONTENT.pBF->IsSet(idx) &&
+-      !PENDINGQUEUE.Exist(idx) &&
+-      !WORLD.AlreadyRequested(idx) ){
++        !PENDINGQUEUE.Exist(idx) &&
++        !WORLD.AlreadyRequested(idx) ){
++      if(arg_verbose) fprintf(stderr, "Assigning #%u to %p\n", idx, this);
+       return (request_q.CreateWithIdx(idx) < 0) ? -1 : SendRequest();
+     }
+-  }else{
++  }   // If we didn't want the cached piece, select another.
++  if( BTCONTENT.pBF->IsEmpty() ){
++    // If we don't have a complete piece yet, try to get one that's already
++    // in progress.  (Initial-piece mode)
++    BitField tmpBitField = bitfield;
++    idx = WORLD.What_Can_Duplicate(tmpBitField, this, BTCONTENT.GetNPieces());
++    if( idx < BTCONTENT.GetNPieces() ){
++      if(arg_verbose) fprintf(stderr, "Want to dup #%u to %p\n", idx, this);
++      btPeer *peer = WORLD.WhoHas(idx);
++      if(peer){
++        if(arg_verbose) fprintf( stderr, "Duping: %p to %p (#%u)\n",
++          peer, this, idx );
++        return (request_q.CopyShuffle(&peer->request_q, idx) < 0) ?
++          -1 : SendRequest();
++      }
++    }else if(arg_verbose) fprintf(stderr, "Nothing to dup to %p\n", this);
++  }   // Doesn't have a piece that's already in progress--choose another.
+     BitField tmpBitField;
+     if( bitfield.IsFull() ){
++      // peer is a seed
+       tmpBitField = *BTCONTENT.pBF;
+       tmpBitField.Invert();
+     }else{
+       tmpBitField = bitfield;
+       tmpBitField.Except(*BTCONTENT.pBF);
+     }
++    // The filter tells what we don't want.
++    tmpBitField.Except(*BTCONTENT.pBFilter);
++    // tmpBitField tells what we need from this peer...
+     if( !tmpBitField.IsEmpty() ){
+-      WORLD.CheckBitField(tmpBitField);
+-      if(tmpBitField.IsEmpty()){
+-      
+-      btPeer *peer = WORLD.Who_Can_Abandon(this);
+-      if(peer){
+-        peer->StopDLTimer();
+-        request_q = peer->request_q;
+-
+-        if(peer->CancelRequest(request_q.GetHead()) < 0 ||
+-           peer->RequestCheck() < 0){
+-          peer->CloseConnection();
+-        }
+-        
+-        return SendRequest();
+-      }
+-      
++      BitField tmpBitField2 = tmpBitField;
++      WORLD.CheckBitField(tmpBitField2);
++      // [tmpBitField2]... that we haven't requested from anyone.
++      if(tmpBitField2.IsEmpty()){
++        // Everything this peer has that I want, I've already requested.
++        if( arg_file_to_download ){
++          BitField afdBitField =  *BTCONTENT.pBF;
++          afdBitField.Except(*BTCONTENT.pBFilter);
++          endgame = ( BTCONTENT.getFilePieces(arg_file_to_download)
++                      - afdBitField.Count() ) < WORLD.TotalPeers();
++        }else
++          endgame = ( WORLD.Pieces_I_Can_Get() - BTCONTENT.pBF->Count() )
++                      < WORLD.TotalPeers();
++        if(endgame){  // OK to duplicate a request.
++//        idx = tmpBitField.Random();
++          idx = 0;    // flag for Who_Can_Duplicate()
++          BitField tmpBitField3 = tmpBitField2;
++          idx = WORLD.What_Can_Duplicate(tmpBitField3, this, idx);
++          if( idx < BTCONTENT.GetNPieces() ){
++            if(arg_verbose) fprintf(stderr,"Want to dup #%u to %p\n",idx,this);
++            btPeer *peer = WORLD.WhoHas(idx);
++            if(peer){
++              if(arg_verbose) fprintf( stderr, "Duping: %p to %p (#%u)\n",
++                peer, this, idx );
++              return (request_q.CopyShuffle(&peer->request_q, idx) < 0) ?
++                -1 : SendRequest();
++            }
++          }else if(arg_verbose) fprintf(stderr, "Nothing to dup to %p\n",this);
++        }else{        // not endgame mode
++          btPeer *peer = WORLD.Who_Can_Abandon(this); // slowest choice
++          if(peer){
++            // Cancel a request to the slowest peer & request it from this one.
++            if(arg_verbose) fprintf( stderr, "Reassigning %p to %p (#%u)\n",
++              peer, this, peer->request_q.GetRequestIdx() );
++            // RequestQueue class "moves" rather than "copies" in assignment!
++            if( request_q.Copy(&peer->request_q) < 0 ) return -1;
++            if(peer->CancelPiece() < 0 || peer->RequestCheck() < 0)
++              peer->CloseConnection();
++            return SendRequest();
++          }else{
++            if(arg_verbose) fprintf(stderr, "%p standby\n", this);
++            m_standby = 1;    // nothing to do at the moment
++          }
++        }
+       }else{
+-      idx = tmpBitField.Random();
+-      return (request_q.CreateWithIdx(idx) < 0) ? -1 : SendRequest();
++        // Request something that we haven't requested yet (most common case).
++        // Try to make it something that has good trade value.
++        BitField tmpBitField3 = tmpBitField2;
++        WORLD.FindValuedPieces(tmpBitField3, this, BTCONTENT.pBF->IsEmpty());
++        if( tmpBitField3.IsEmpty() ) tmpBitField3 = tmpBitField2;
++        idx = tmpBitField3.Random();
++        if(arg_verbose) fprintf(stderr, "Assigning #%u to %p\n", idx, this);
++        return (request_q.CreateWithIdx(idx) < 0) ? -1 : SendRequest();
+       }
++    }else{
++      // We don't need anything from the peer.  How'd we get here?
++      return SetLocal(M_NOT_INTERESTED);
+     }
+-  }
+   return 0;
+ }
+ int btPeer::MsgDeliver()
+ {
+   size_t r,idx,off,len;
++  int retval = 0;
+   char *msgbuf = stream.in_buffer.BasePointer();
+-  r = ntohl(*(size_t*) msgbuf);
++  r = get_nl(msgbuf);
++  // Don't require keepalives if we're receiving other messages.
++  m_last_timestamp = now;
+   if( 0 == r ){
+-    time(&m_last_timestamp);
+     if( !m_f_keepalive ) if( stream.Send_Keepalive() < 0 ) return -1;
+     m_f_keepalive = 0;
+-    return (!m_state.remote_choked && request_q.IsEmpty()) ? RequestCheck() : 0;
++    return 0;
+   }else{
+     switch(msgbuf[4]){
+     case M_CHOKE:
+       if(H_BASE_LEN != r){ return -1;}
++      if(arg_verbose) fprintf(stderr, "%p choked me\n", this);
++      if( m_lastmsg == M_UNCHOKE && m_last_timestamp <= m_choketime+1 ){
++        m_err_count+=2;
++        if(arg_verbose) fprintf(stderr,"err: %p (%d) Choke oscillation\n",
++          this, m_err_count);
++      }
++      m_choketime = m_last_timestamp;
+       m_state.remote_choked = 1;
+       StopDLTimer();
++      if( g_next_dn == this ) g_next_dn = (btPeer *)0;
+       if( !request_q.IsEmpty()){
+-      PSLICE ps = request_q.GetHead();
+-      PENDINGQUEUE.Pending(&request_q);
+-      if( CancelRequest(ps) < 0) return -1;
++        m_req_out = 0;
++        PENDINGQUEUE.Pending(&request_q);
+       }
+-      return 0;
++      break;
++
+     case M_UNCHOKE:
+       if(H_BASE_LEN != r){return -1;}
++      if(arg_verbose) fprintf(stderr, "%p unchoked me\n", this);
++      if( m_lastmsg == M_CHOKE && m_last_timestamp <= m_choketime+1 ){
++        m_err_count+=2;
++        if(arg_verbose) fprintf(stderr,"err: %p (%d) Choke oscillation\n",
++          this, m_err_count);
++      }
++      m_choketime = m_last_timestamp;
+       m_state.remote_choked = 0;
+-      return RequestCheck();
++      retval = RequestCheck();
++      break;
+     case M_INTERESTED:
+       if(H_BASE_LEN != r){return -1;}
++      if(arg_verbose) fprintf(stderr, "%p is interested\n", this);
+       m_state.remote_interested = 1;
+       break;
+     case M_NOT_INTERESTED:
+       if(r != H_BASE_LEN){return -1;}
++      if(arg_verbose) fprintf(stderr, "%p is not interested\n", this);
+       m_state.remote_interested = 0;
+       StopULTimer();
+       /* remove peer's reponse queue */
+       if( !reponse_q.IsEmpty()) reponse_q.Empty();
+-      return 0;
++      break;
++
+     case M_HAVE:
+       if(H_HAVE_LEN != r){return -1;}
+-      idx = ntohl(*(size_t*) (msgbuf + 5));
++      idx = get_nl(msgbuf + 5);
+       if( idx >= BTCONTENT.GetNPieces() || bitfield.IsSet(idx)) return -1;
+@@ -201,54 +378,90 @@
+       if( bitfield.IsFull() && BTCONTENT.pBF->IsFull() ){ return -2; }
+-      if( !BTCONTENT.pBF->IsSet(idx) ) m_cached_idx = idx;
++      if( !BTCONTENT.pBF->IsSet(idx) && !BTCONTENT.pBFilter->IsSet(idx) ){
++        m_cached_idx = idx;
++        if(arg_verbose && m_standby) fprintf(stderr, "%p un-standby\n", this);
++        m_standby = 0;
++      }
++      //      if( !BTCONTENT.pBF->IsSet(idx) ) m_cached_idx = idx;
+       
+-      return ( !m_state.remote_choked && request_q.IsEmpty() ) ? RequestCheck() : 0;
++      // see if we're Interested now
++      if(!m_standby) retval = RequestCheck();
++      break;
+     case M_REQUEST:
+       if(H_REQUEST_LEN != r || !m_state.remote_interested){ return -1; }
+-      idx = ntohl(*(size_t*)(msgbuf + 5));
++      idx = get_nl(msgbuf + 5);
+       
+       if( !BTCONTENT.pBF->IsSet(idx) ) return -1;
+       
+-      off = ntohl(*(size_t*)(msgbuf + 9));
+-      len = ntohl(*(size_t*)(msgbuf + 13));
++      off = get_nl(msgbuf + 9);
++      len = get_nl(msgbuf + 13);
+       if( !reponse_q.IsValidRequest(idx, off, len) ) return -1;
+-      
+-      return reponse_q.Add(idx, off, len);
++
++      if( m_state.local_choked ){
++        if( (m_latency && m_last_timestamp - m_unchoke_timestamp > m_latency) ||
++            (!m_latency && m_last_timestamp - m_unchoke_timestamp > 60) ){
++          m_err_count++;
++          if(arg_verbose) fprintf(stderr,"err: %p (%d) choked request\n",
++            this, m_err_count);
++          if( stream.Send_State(M_CHOKE) < 0 ) return -1;
++          // This will mess with the unchoke rotation (to this peer's
++          // disadvantage), but otherwise we may spam them with choke msgs.
++          m_unchoke_timestamp = m_last_timestamp;
++        }
++      }else retval = reponse_q.Add(idx, off, len);
++      break;
+     case M_PIECE:
++      m_receive_time = m_last_timestamp;
+       if( request_q.IsEmpty() || !m_state.local_interested){
+-      m_err_count++;
+-      return 0;
+-      }
+-      return PieceDeliver(r);
++        m_err_count++;
++             if(arg_verbose) fprintf(stderr,"err: %p (%d) Unwanted piece\n",
++               this, m_err_count);
++      }else retval = PieceDeliver(r);
++      break;
+     case M_BITFIELD:
+       if( (r - 1) != bitfield.NBytes() || !bitfield.IsEmpty()) return -1;
+       bitfield.SetReferBuffer(msgbuf + 5);
+-      if(bitfield.IsFull() && BTCONTENT.pBF->IsFull()) return -2;
+-      return 0;
++      if(bitfield.IsFull()){
++        if(arg_verbose) fprintf(stderr, "%p is a seed\n", this);
++        if(BTCONTENT.pBF->IsFull()) return -2;
++      }
++
++      //This is needed in order to set our Interested state
++      retval = RequestCheck(); // fixed client stall
++      break;
+     case M_CANCEL:
+       if(r != H_CANCEL_LEN || !m_state.remote_interested) return -1;
+-      idx = ntohl(*(size_t*)(msgbuf + 5));
+-      off = ntohl(*(size_t*)(msgbuf + 9));
+-      len = ntohl(*(size_t*)(msgbuf + 13));
++      idx = get_nl(msgbuf + 5);
++      off = get_nl(msgbuf + 9);
++      len = get_nl(msgbuf + 13);
+       if( reponse_q.Remove(idx,off,len) < 0 ){
+-      m_err_count++;
+-      return 0;
++        m_err_count++;
++        if(arg_verbose) fprintf(stderr, "err: %p (%d) Bad cancel\n",
++          this, m_err_count);
++      }else{
++        if( reponse_q.IsEmpty() ) StopULTimer();
++        if( reponse_q.IsEmpty() || !CouldReponseSlice() ){
++          if( g_next_up == this ) g_next_up = (btPeer *)0;
++        }
+       }
+-      if( reponse_q.IsEmpty() ) StopULTimer();
+-      return 0;
++      break;
++
+     default:
+-      return -1;              // unknow message type
+-    }
++      if(arg_verbose) fprintf(stderr, "Unknown message type %u from peer %p\n",
++        msgbuf[4], this);
++    } // switch
++
++    if( retval >= 0 ) m_lastmsg = msgbuf[4];
+   }
+-  return 0;
++  return retval;
+ }
+ int btPeer::ReponseSlice()
+@@ -270,6 +483,8 @@
+     Self.DataSended(len);
+     DataSended(len);
++    if(arg_verbose) fprintf(stderr, "Sending %d/%d/%d to %p\n",
++      (int)idx, (int)off, (int)len, this);
+     return stream.Send_Piece(idx,off,BTCONTENT.global_piece_buffer,len);
+   }
+@@ -278,32 +493,153 @@
+ int btPeer::SendRequest()
+ {
++  int first = 1;
++  PSLICE ps = request_q.NextSend();
++
++  if( m_req_out > cfg_req_queue_length ){
++    if(arg_verbose)
++      fprintf(stderr, "ERROR@5: %p m_req_out underflow, resetting\n", this);
++    m_req_out = 0;
++  }
++  if( ps && m_req_out < m_req_send ){
++    if(arg_verbose)
++      fprintf(stderr, "Requesting #%u from %p (%d left, %d slots):",
++      ps->index, this, request_q.Qsize(), m_req_send);
++    for( int i=0; ps && m_req_out < m_req_send && i<5; ps = ps->next, i++ ){
++      if( first && (!RateDL() ||
++          0 >= (m_req_out+1) * ps->length / (double)RateDL() - m_latency) ){
++        request_q.SetReqTime(ps, now);
++        first = 0;
++      } else request_q.SetReqTime(ps, (time_t)0);
++      if(arg_verbose) fprintf(stderr, ".");
++      if(stream.Send_Request(ps->index,ps->offset,ps->length) < 0){ return -1; }
++      request_q.SetNextSend(ps->next);
++      m_req_out++;
++    }
++    if(arg_verbose) fprintf(stderr, "\n");
++    m_receive_time = now;
++  }
++  return ( m_req_out < m_req_send ) ? RequestPiece() : 0;
++}
++
++int btPeer::CancelPiece()
++{
+   PSLICE ps = request_q.GetHead();
+-  for( ; ps ; ps = ps->next )
+-    if(stream.Send_Request(ps->index,ps->offset,ps->length) < 0){ return -1; }
++  size_t idx;
++  int cancel = 1;
++  int retval;
++
++  idx = ps->index;
++  for( ; ps; ps = ps->next){
++    if( ps->index != idx ) break;
++    if( ps == request_q.NextSend() ) cancel = 0;
++    if( cancel ){
++      if(stream.Send_Cancel(ps->index,ps->offset,ps->length) < 0)
++        return -1;
++      m_req_out--;
++      if( m_req_out > cfg_req_queue_length ){
++        if(arg_verbose)
++          fprintf(stderr, "ERROR@1: %p m_req_out underflow, resetting\n", this);
++        m_req_out = 0;
++      }
++    }
++    request_q.Remove(ps->index, ps->offset, ps->length);
++  }
++  if( !m_req_out && g_next_dn == this ) g_next_dn = (btPeer *)0;
+-  return stream.Flush();
++  return 0;
+ }
+ int btPeer::CancelRequest(PSLICE ps)
+ {
++  int retval;
++
+   for( ; ps; ps = ps->next){
++    if( ps == request_q.NextSend() ) break;
+     if(stream.Send_Cancel(ps->index,ps->offset,ps->length) < 0)
+       return -1;
++    m_req_out--;
++    if( m_req_out > cfg_req_queue_length ){
++      if(arg_verbose)
++        fprintf(stderr, "ERROR@2: %p m_req_out underflow, resetting\n", this);
++      m_req_out = 0;
++    }
+   }
+-  return stream.Flush();
++  if( !m_req_out && g_next_dn == this ) g_next_dn = (btPeer *)0;
++
++  return 0;
++}
++
++int btPeer::CancelSliceRequest(size_t idx, size_t off, size_t len)
++{
++  PSLICE ps;
++  int cancel = 1;
++  int idxfound = 0;
++  int retval;
++
++  for(ps = request_q.GetHead() ; ps; ps = ps->next){
++    if( ps == request_q.NextSend() ) cancel = 0;
++    if( idx == ps->index ){
++      if( off == ps->offset && len == ps->length ){
++        if( request_q.Remove(idx,off,len) < 0 ){
++          m_err_count++;
++          if(arg_verbose) fprintf(stderr,"err: %p (%d) Bad CS remove\n",
++            this, m_err_count);
++        }
++        if(cancel){
++          if(stream.Send_Cancel(idx,off,len) < 0)
++            return -1;
++          m_req_out--;
++          if( m_req_out > cfg_req_queue_length ){
++            if(arg_verbose) fprintf(stderr,
++              "ERROR@3: %p m_req_out underflow, resetting\n", this);
++            m_req_out = 0;
++          }
++          if( !m_req_out && g_next_dn == this ) g_next_dn = (btPeer *)0;
++
++          // Don't call RequestCheck() here since that could cause the slice
++          // we're cancelling to be dup'd from another peer.
++          return 0;
++        }
++        break;
++      }
++      idxfound = 1;
++    }else if( idxfound ) break;
++  }
++  return 0;
+ }
+ int btPeer::ReportComplete(size_t idx)
+ {
+   if( BTCONTENT.APieceComplete(idx) ){
++    if(arg_verbose) fprintf(stderr, "Piece #%u completed\n", idx);
+     WORLD.Tell_World_I_Have(idx);
++    PENDINGQUEUE.Delete(idx);
+     if( BTCONTENT.pBF->IsFull() ){
+       ResetDLTimer();
+       WORLD.CloseAllConnectionToSeed();
+     }
+-  }else
++
++    if( arg_file_to_download ){
++      BitField tmpBitField =  *BTCONTENT.pBF;
++      tmpBitField.Except(*BTCONTENT.pBFilter);
++
++      while( arg_file_to_download &&
++        tmpBitField.Count() >= BTCONTENT.getFilePieces(arg_file_to_download) ){
++        //when the file is complete, we go after the next
++        ++arg_file_to_download;
++        BTCONTENT.FlushCache();
++        BTCONTENT.SetFilter();
++        tmpBitField =  *BTCONTENT.pBF;
++        tmpBitField.Except(*BTCONTENT.pBFilter);
++      }
++      WORLD.CheckInterest();
++    }
++  }else{
+     m_err_count++;
++    if(arg_verbose) fprintf(stderr, "err: %p (%d) Bad complete\n",
++      this, m_err_count);
++  }
+   return (P_FAILED == m_status) ? -1 : RequestCheck();
+ }
+@@ -311,17 +647,37 @@
+ {
+   size_t idx,off,len;
+   char *msgbuf = stream.in_buffer.BasePointer();
++  time_t t;
++  int dup = 0, requested = 1;
+-  idx = ntohl(*(size_t*) (msgbuf + 5));
+-  off = ntohl(*(size_t*) (msgbuf + 9));
++  idx = get_nl(msgbuf + 5);
++  off = get_nl(msgbuf + 9);
+   len = mlen - 9;
++  if(arg_verbose) fprintf(stderr, "Receiving piece %d/%d/%d from %p\n",
++    (int)idx, (int)off, (int)len, this);
++
++  t = request_q.GetReqTime(idx,off,len);
++
++  PSLICE ps = request_q.GetHead();
++  if( request_q.NextSend() )
++    for( ; ps; ps = ps->next){
++      if( ps == request_q.NextSend() ){
++        requested = 0;
++        break;
++      }
++      if( idx==ps->index && off==ps->offset && len==ps->length ) break;
++    }
++
+   if( request_q.Remove(idx,off,len) < 0 ){
+     m_err_count++;
++    if(arg_verbose) fprintf(stderr, "err: %p (%d) Bad remove\n",
++      this, m_err_count);
+     return 0;
+   }
+   if(BTCONTENT.WriteSlice((char*)(msgbuf + 13),idx,off,len) < 0){
++    fprintf(stderr, "warn, WriteSlice failed; is filesystem full?\n");
+     return 0;
+   }
+@@ -329,48 +685,172 @@
+   Self.DataRecved(len);
+   DataRecved(len);
++  // Check for & cancel requests for this slice from other peers in initial
++  // and endgame modes.
++  if( BTCONTENT.pBF->Count() < 2 ||
++      WORLD.Pieces_I_Can_Get() - BTCONTENT.pBF->Count() < WORLD.TotalPeers() )
++    dup = 1;
++  else if( arg_file_to_download ){
++    BitField afdBitField =  *BTCONTENT.pBF;
++    afdBitField.Except(*BTCONTENT.pBFilter);
++    if( BTCONTENT.getFilePieces(arg_file_to_download) - afdBitField.Count()
++        < WORLD.TotalPeers() )
++      dup = 1;
++  }
++  if( dup ){
++    WORLD.CancelSlice(idx, off, len);
++    PENDINGQUEUE.DeleteSlice(idx, off, len);
++  }
++
++  // Determine how many outstanding requests we should maintain, roughly:
++  // (request turnaround latency) / (time to transmit one slice)
++  if(t){
++    m_latency = (m_last_timestamp <= t) ? 1 : m_last_timestamp - t;
++    if(arg_verbose) fprintf(stderr, "%p latency is %d sec\n",
++      this, (int)m_latency);
++    m_latency_timestamp = m_last_timestamp;
++  }
++
++  if( RateDL() > len/20 ){
++    m_req_send = (int)( m_latency / (len / (double)RateDL()) + 1 );
++    m_req_send = (m_req_send < 2) ? 2 : m_req_send;
++
++    // If latency increases, we will see this as a dlrate decrease.
++    if( RateDL() < m_prev_dlrate ) m_req_send++;
++    else if( m_last_timestamp - m_latency_timestamp >= 30 &&
++      // Try to force latency measurement every 30 seconds.
++        m_req_out == m_req_send - 1 ){
++      m_req_send--;
++      m_latency_timestamp = m_last_timestamp;
++    }
++    m_prev_dlrate = RateDL();
++  }else if (m_req_send < 5) m_req_send = 5;
++
++  if( requested ) m_req_out--;
++
+   /* if piece download complete. */
+-  return request_q.IsEmpty() ? ReportComplete(idx) : 0;
++  return ( request_q.IsEmpty() || !request_q.HasIdx(idx) ) ?
++    ReportComplete(idx) : RequestCheck();
+ }
+ int btPeer::RequestCheck()
+ {
+-  if( BandWidthLimit() ) return 0;
+-  
+   if( BTCONTENT.pBF->IsFull() ){
+-    if( bitfield.IsFull() ){ return -1; }
++    if( bitfield.IsFull() ){ return -2; }
+     return SetLocal(M_NOT_INTERESTED);
+   }
+   if( Need_Remote_Data() ){
+     if(!m_state.local_interested && SetLocal(M_INTERESTED) < 0) return -1;
+-    if(request_q.IsEmpty() && !m_state.remote_choked){
+-      if( RequestPiece() < 0 ) return -1;
++    if( !m_state.remote_choked ){
++      if( m_req_out > cfg_req_queue_length ){
++        if(arg_verbose)
++          fprintf(stderr, "ERROR@4: %p m_req_out underflow, resetting\n", this);
++        m_req_out = 0;
++      }
++      if( request_q.IsEmpty() && RequestPiece() < 0 ) return -1;
++      else if( m_req_out < m_req_send &&
++               (m_req_out < 2 || !RateDL() ||
++                1 >= (m_req_out+1) * request_q.GetRequestLen() /
++                     (double)RateDL() - m_latency)
++      // above formula is to try to allow delay between sending batches of reqs
++        && SendRequest() < 0 ) return -1;
+     }
+-  }
++  }else
++    if(m_state.local_interested && SetLocal(M_NOT_INTERESTED) < 0) return -1;
+   
+   if(!request_q.IsEmpty()) StartDLTimer();
++  else StopDLTimer();
+   return 0;
+ }
+ void btPeer::CloseConnection()
+ {
++  if(arg_verbose) fprintf(stderr, "%p closed\n", this);
+   if( P_FAILED != m_status ){
+     m_status = P_FAILED;
+     stream.Close();
++    if( !request_q.IsEmpty() )
++      PENDINGQUEUE.Pending(&request_q);
+   }
++  if( g_next_up == this ) g_next_up = (btPeer *)0;
++  if( g_next_dn == this ) g_next_dn = (btPeer *)0;
+ }
+ int btPeer::HandShake()
+ {
++  char txtid[PEER_ID_LEN*2+3];
+   ssize_t r = stream.Feed();
+-  if( r < 0 ) return -1;
++  if( r < 0 ){
++//  if(arg_verbose) fprintf(stderr, "hs: r<0 (%d)\n", r);
++    return -1;
++  }
+   else if( r < 68 ){
+-    if(r && memcmp(stream.in_buffer.BasePointer(),BTCONTENT.GetShakeBuffer(),r) != 0) return -1;
++    if(r >= 21){      // Ignore 8 reserved bytes following protocol ID.
++      if( memcmp(stream.in_buffer.BasePointer()+20,
++          BTCONTENT.GetShakeBuffer()+20, (r<28) ? r-20 : 8) != 0 ){
++        if(arg_verbose){
++          fprintf( stderr, "\npeer %p gave 0x", this);
++          for(int i=20; i<r && i<27; i++) fprintf(stderr, "%2.2hx",
++            (unsigned short)(unsigned char)(stream.in_buffer.BasePointer()[i]));
++          fprintf( stderr, " as reserved bytes (partial)\n" );
++        }
++        memcpy(stream.in_buffer.BasePointer()+20, BTCONTENT.GetShakeBuffer()+20,
++          (r<28) ? r-20 : 8);
++      }
++    }
++    if(r && memcmp(stream.in_buffer.BasePointer(),BTCONTENT.GetShakeBuffer(),
++        (r<48) ? r : 48) != 0){
++      if(arg_verbose){
++        fprintf(stderr, "\nmine: 0x");
++        for(int i=0; i<r && i<48; i++) fprintf(stderr, "%2.2hx",
++          (unsigned short)(unsigned char)(BTCONTENT.GetShakeBuffer()[i]));
++        fprintf(stderr, "\npeer: 0x");
++        for(int i=0; i<r && i<48; i++) fprintf(stderr, "%2.2hx",
++          (unsigned short)(unsigned char)(stream.in_buffer.BasePointer()[i]));
++        fprintf(stderr, "\n");
++        if( r>48 ){
++          TextPeerID((unsigned char *)(stream.in_buffer.BasePointer()+48),
++            txtid);
++          fprintf(stderr, "peer is %s\n", txtid);
++        }
++      }
++      return -1;
++    }
+     return 0;
+   }
+-  if( memcmp(stream.in_buffer.BasePointer(),BTCONTENT.GetShakeBuffer(),48) != 0 ) return -1;
++  // If the reserved bytes differ, make them the same.
++  // If they mean anything important, the handshake is likely to fail anyway.
++  if( memcmp(stream.in_buffer.BasePointer()+20, BTCONTENT.GetShakeBuffer()+20,
++      8) != 0 ){
++    if(arg_verbose){
++      fprintf(stderr, "\npeer %p gave 0x", this);
++      for(int i=20; i<27; i++) fprintf(stderr, "%2.2hx",
++        (unsigned short)(unsigned char)(stream.in_buffer.BasePointer()[i]));
++      fprintf( stderr, " as reserved bytes\n" );
++    }
++    memcpy(stream.in_buffer.BasePointer()+20, BTCONTENT.GetShakeBuffer()+20, 8);
++  }
++  if( memcmp(stream.in_buffer.BasePointer(),
++             BTCONTENT.GetShakeBuffer(),48) != 0 ){
++    if(arg_verbose){
++      fprintf(stderr, "\nmine: 0x");
++      for(int i=0; i<48; i++) fprintf(stderr, "%2.2hx",
++        (unsigned short)(unsigned char)(BTCONTENT.GetShakeBuffer()[i]));
++      fprintf(stderr, "\npeer: 0x");
++      for(int i=0; i<48; i++) fprintf(stderr, "%2.2hx",
++        (unsigned short)(unsigned char)(stream.in_buffer.BasePointer()[i]));
++      fprintf(stderr, "\n");
++    }
++    return -1;
++  }
++
++  memcpy(id, stream.in_buffer.BasePointer()+48, PEER_ID_LEN);
++  if(arg_verbose){
++    TextPeerID((unsigned char *)(stream.in_buffer.BasePointer()+48), txtid);
++    fprintf(stderr, "Peer %p ID: %s\n", this, txtid);
++  }
+   // ignore peer id verify
+   if( !BTCONTENT.pBF->IsEmpty()){
+@@ -395,20 +875,63 @@
+   return stream.Send_Buffer((char*)BTCONTENT.GetShakeBuffer(),68);
+ }
+-int btPeer::BandWidthLimit()
++int btPeer::BandWidthLimitUp()
+ {
+-  if( cfg_max_bandwidth <= 0 ) return 0;
+-  return ((Self.RateDL() + Self.RateUL()*2) / 1024 >= cfg_max_bandwidth) ?
++  if( cfg_max_bandwidth_up <= 0 ) return 0;
++  return ((Self.RateUL()) >= cfg_max_bandwidth_up) ?
++    1:0;
++}
++
++int btPeer::BandWidthLimitDown()
++{
++  if( cfg_max_bandwidth_down <= 0 ) return 0;
++  return ((Self.RateDL()) >= cfg_max_bandwidth_down) ?
+     1:0;
+ }
+ int btPeer::NeedWrite()
+ {
+   int yn = 0;
++
++  if( m_standby && WORLD.Endgame() ){
++    if(arg_verbose) fprintf(stderr, "%p un-standby (endgame)\n", this);
++    m_standby = 0;
++  }
++
+   if( stream.out_buffer.Count() || // data need send in buffer.
+-      (!reponse_q.IsEmpty() && CouldReponseSlice() && !BandWidthLimit()) ||
+-      P_CONNECTING == m_status ) // peer is connecting
++      // can upload a slice
++      (!reponse_q.IsEmpty() && CouldReponseSlice() && !BandWidthLimitUp()) ||
++
++      ( (request_q.NextSend() && m_req_out < m_req_send &&
++            (m_req_out < 2 || !RateDL() ||
++             1 >= (m_req_out+1) * request_q.GetRequestLen() /
++                  (double)RateDL() - m_latency)) // can send queued request
++        ||
++        (request_q.IsEmpty() && !m_state.remote_choked 
++          && m_state.local_interested && !m_standby) // can request a new piece
++      ) // ok to send requests
++
++      || P_CONNECTING == m_status ){ // peer is connecting
++
+     yn = 1;
++
++    if( g_next_up==this && g_defer_up ){
++      if(arg_verbose) fprintf(stderr, "%p skipped UL\n", this);
++      g_next_up = (btPeer *)0;
++    }
++  }
++  return yn;
++}
++
++int btPeer::NeedRead()
++{
++  int yn = 1;
++  if( !request_q.IsEmpty() && BandWidthLimitDown() )
++    yn = 0;
++  else if( g_next_dn==this && g_defer_dn ){
++    if(arg_verbose) fprintf(stderr, "%p skipped DL\n", this);
++    g_next_dn = (btPeer *)0;
++  }
+   return yn;
+ }
+@@ -432,20 +955,35 @@
+   ssize_t r;
+   
+   if ( 64 < m_err_count ) return -1;
+-  
+-  r = stream.Feed();
+-  if( r < 0 && r != -2 )
+-    return -1;
+-  else if ( r == -2 )
+-    f_peer_closed = 1;
++  if( request_q.IsEmpty() || !BandWidthLimitDown() ){
++    if ( request_q.IsEmpty() || !g_next_dn || g_next_dn==this ){
++      if( g_next_dn ) g_next_dn = (btPeer *)0;
++
++      r = stream.Feed();
++
++      if( r < 0 && r != -2 )
++        return -1;
++      else if ( r == -2 )
++        f_peer_closed = 1;
+   
+-  r = stream.HaveMessage();
+-  for( ; r;){
+-    if( r < 0 ) return -1;
+-    if(MsgDeliver() < 0 || stream.PickMessage() < 0) return -1;
+-    r = stream.HaveMessage();
++      r = stream.HaveMessage();
++      for( ; r;){
++        if( r < 0 ) return -1;
++        if(MsgDeliver() < 0 || stream.PickMessage() < 0) return -1;
++        r = stream.HaveMessage();
++      }
++    }else{
++      if(arg_verbose)
++        fprintf(stderr, "%p deferring DL to %p\n", this, g_next_dn);
++      if( !g_defer_dn ) g_defer_dn = 1;
++    }
++  }else if( !g_next_dn ){
++    if(arg_verbose) fprintf(stderr, "%p waiting for DL bandwidth\n", this);
++    g_next_dn = this;
++    if( g_defer_dn ) g_defer_dn = 0;
+   }
++
+   return f_peer_closed ? -1 : 0;
+ }
+@@ -453,27 +991,80 @@
+ {
+   if( stream.out_buffer.Count() && stream.Flush() < 0) return -1;
+-  if(! reponse_q.IsEmpty() &&  CouldReponseSlice() ) {
+-    StartULTimer();
+-    Self.StartULTimer();
+-  }
++  if( !reponse_q.IsEmpty() && CouldReponseSlice() ) {
++    if( !BandWidthLimitUp() ){
++      if( !g_next_up || g_next_up==this ){
++        if( g_next_up ) g_next_up = (btPeer *)0;
++
++        StartULTimer();
++        Self.StartULTimer();
++        if( ReponseSlice() < 0 ) return -1;
++      }else{
++        if(arg_verbose)
++          fprintf(stderr, "%p deferring UL to %p\n", this, g_next_up);
++        if( !g_defer_up ) g_defer_up = 1;
++      }
++    }else if( !g_next_up ){
++      if(arg_verbose) fprintf(stderr, "%p waiting for UL bandwidth\n", this);
++      g_next_up = this;
++      if( g_defer_up ) g_defer_up = 0;
++    }
++  }else if( g_next_up == this ) g_next_up = (btPeer *)0;
+-  for(; !reponse_q.IsEmpty() && CouldReponseSlice(); )
+-    if( ReponseSlice() < 0) return -1;
++  return (!m_state.remote_choked) ? RequestCheck() : 0;
++}
++// Prevent a peer object from holding g_next_up when it's not ready to write.
++void btPeer::CheckSendStatus()
++{
++  if( g_next_up == this && !BandWidthLimitUp() ){
++    if(arg_verbose) fprintf(stderr, "%p is not write-ready\n", this);
++    g_next_up = (btPeer *)0;
++  }
++}
++
++/* Detect if a peer ignored, discarded, or lost my request and we're waiting
++   for a piece that may never arrive. */
++int btPeer::HealthCheck(time_t now)
++{
++  if( m_health_time <= now - 60 ){
++    m_health_time = now;
++    if( !m_state.remote_choked && m_req_out &&
++        m_receive_time < now - (!m_latency ? 300 :
++                               ((m_latency < 30) ? 60 : 2*m_latency)) ){
++      // if a repeat occurrence, get rid of the peer
++      if( m_bad_health ) return -1;
++      m_bad_health = 1;
++      if(arg_verbose)
++        fprintf(stderr, "%p unresponsive; resetting request queue\n", this);
++      PSLICE ps = request_q.GetHead();
++      int retval = CancelRequest(ps);
++      PENDINGQUEUE.Pending(&request_q);
++      return (retval < 0) ? -1 : RequestCheck();
++    } else m_bad_health = 0;
++  }
+   return 0;
+ }
++// This handles peers that suppress HAVE messages so that we don't always think
++// that they're empty.  If we've sent the peer an amount of data equivalent to
++// two pieces, assume that they now have at least one complete piece.
++int btPeer::IsEmpty() const
++{
++  return ( bitfield.IsEmpty() && TotalUL() < BTCONTENT.GetPieceLength()*2 ) ?
++    1:0;
++}
++
+ void btPeer::dump()
+ {
+   struct sockaddr_in sin;
+   GetAddress(&sin);
+   printf("%s: %d -> %d:%d   %lud:%lud\n", inet_ntoa(sin.sin_addr), 
+-               bitfield.Count(),
+-               Is_Remote_UnChoked() ? 1 : 0,
+-               request_q.IsEmpty() ? 0 : 1,
+-               (unsigned long)TotalDL(),
+-               (unsigned long)TotalUL());
++          bitfield.Count(),
++          Is_Remote_UnChoked() ? 1 : 0,
++          request_q.IsEmpty() ? 0 : 1,
++          (unsigned long)TotalDL(),
++          (unsigned long)TotalUL());
+ }
+--- peer.h.orig        Wed Sep  8 16:10:51 2004
++++ peer.h     Mon Jan  2 14:28:59 2006
+@@ -19,6 +19,7 @@
+ #include "btstream.h"
+ #include "bitfield.h"
+ #include "rate.h"
++#include "btconfig.h"
+ #define P_CONNECTING (unsigned char) 0                // connecting
+ #define P_HANDSHAKE  (unsigned char) 1                // handshaking
+@@ -34,14 +35,24 @@
+   unsigned char reserved:4;           /* unused */
+ }BTSTATUS;
++size_t get_nl(char *from);
++void set_nl(char *to, size_t from);
++
++int TextPeerID(unsigned char *peerid, char *txtid);
++
+ class btBasic
+ {
+ private:
+   Rate rate_dl;
+   Rate rate_ul;
++  size_t m_current_dl, m_current_ul;
++  unsigned char m_use_current:1;
++  unsigned char m_reserved:7;
+ public:
+   struct sockaddr_in m_sin;
++  btBasic() { m_use_current = 0; }
++
+   //IPµØÖ·Ïà¹Øº¯Êý
+   int IpEquiv(struct sockaddr_in addr);
+   void SetIp(struct sockaddr_in addr);
+@@ -60,8 +71,10 @@
+   void DataRecved(size_t nby) { rate_dl.CountAdd(nby); }
+   void DataSended(size_t nby) { rate_ul.CountAdd(nby); }
+-  size_t RateDL() const { return rate_dl.RateMeasure(); }
+-  size_t RateUL() const { return rate_ul.RateMeasure();}
++  size_t RateDL() const { return m_use_current ? m_current_dl : rate_dl.RateMeasure(); }
++  size_t RateUL() const { return m_use_current ? m_current_ul : rate_ul.RateMeasure(); }
++  void SetCurrentRates();
++  void ClearCurrentRates() { m_use_current = 0; }
+   void StartDLTimer() { rate_dl.StartTimer(); }
+   void StartULTimer() { rate_ul.StartTimer(); }
+@@ -78,17 +91,28 @@
+   unsigned char m_f_keepalive:1;
+   unsigned char m_status:4;
+-  unsigned char m_reserved:3;
++  unsigned char m_bad_health:1;
++  unsigned char m_standby:1;
++  unsigned char m_reserved:1;
+   BTSTATUS m_state;
+   size_t m_cached_idx;
+   size_t m_err_count;
++  size_t m_req_send;  // target number of outstanding requests
++  size_t m_req_out;   // actual number of outstanding requests
++  size_t m_latency;
++  size_t m_prev_dlrate;
++  time_t m_latency_timestamp;
++  time_t m_health_time, m_receive_time;
++  char m_lastmsg;
++  time_t m_choketime;
+   
+   int PieceDeliver(size_t mlen);
+   int ReportComplete(size_t idx);
+   int RequestCheck();
+   int SendRequest();
++  int CancelPiece();
+   int CancelRequest(PSLICE ps);
+   int ReponseSlice();
+   int RequestPiece();
+@@ -96,7 +120,10 @@
+   int CouldReponseSlice();
+   int BandWidthLimit();
++  int BandWidthLimitUp();
++  int BandWidthLimitDown();
+  public:
++  unsigned char id[PEER_ID_LEN];
+   BitField bitfield;
+   btStream stream;
+   RequestQueue request_q;
+@@ -106,6 +133,8 @@
+   int RecvModule();
+   int SendModule();
++  int HealthCheck(time_t now);
++  void CheckSendStatus();
+   time_t SetLastTimestamp() { return time(&m_last_timestamp); }
+   time_t GetLastTimestamp() const { return m_last_timestamp; }
+@@ -118,10 +147,14 @@
+   int Is_Local_UnChoked() const { return m_state.local_choked ? 0 : 1; }
+   int SetLocal(unsigned char s);
++  int IsEmpty() const;
++
++  int CancelSliceRequest(size_t idx, size_t off, size_t len);
+   
+   void SetStatus(unsigned char s){ m_status = s; }
+   unsigned char GetStatus() const { return m_status; }
+   int NeedWrite();
++  int NeedRead();
+   
+   void CloseConnection();
+--- peerlist.cpp.orig  Wed Sep  8 16:10:51 2004
++++ peerlist.cpp       Mon Jan  9 11:16:21 2006
+@@ -5,6 +5,7 @@
+ #include <stdlib.h>
+ #include <stdio.h>
++#include <errno.h>
+ #include <string.h>
+@@ -16,11 +17,15 @@
+ #include "iplist.h"
+ #include "tracker.h"
++#include "ctcs.h"
++#include "bttime.h"
+ #define MAX_UNCHOKE 3
+ #define UNCHOKE_INTERVAL 10
++#define OPT_INTERVAL 30
++
+ #define KEEPALIVE_INTERVAL 117
+ #define LISTEN_PORT_MAX 2706
+@@ -36,12 +41,13 @@
+ PeerList::PeerList()
+ {
+-  m_unchoke_check_timestamp = 
+-    m_keepalive_check_timestamp = time((time_t*) 0);
++  m_unchoke_check_timestamp =
++    m_keepalive_check_timestamp =
++    m_opt_timestamp = time((time_t*) 0);
+   m_head = (PEERNODE*) 0;
+   m_listen_sock = INVALID_SOCKET;
+-  m_peers_count = 0;
++  m_peers_count = m_seeds_count = 0;
+   m_live_idx = 0;
+ }
+@@ -61,25 +67,6 @@
+   return m_peers_count ? 0 : 1;
+ }
+-void PeerList::Sort()
+-{
+-  PEERNODE *newhead = (PEERNODE*) 0;
+-  PEERNODE *p, *pp, *spn;
+-
+-  if( m_peers_count < 10 ) return;
+-
+-  for(; m_head;){
+-    pp = (PEERNODE*) 0;
+-    for(p = newhead; p && m_head->click < p->click; pp = p, p = p->next) ;
+-    
+-    spn = m_head->next;
+-    m_head->next = p;
+-    if( pp ) pp->next = m_head; else newhead = m_head;
+-    m_head = spn;
+-  }
+-  m_head = newhead;
+-}
+-
+ void PeerList::CloseAll()
+ {
+   PEERNODE *p;
+@@ -118,6 +105,8 @@
+     
+     if( setfd_nonblock(sk) < 0) goto err;
++    if(arg_verbose) fprintf(stderr, "Connecting to %s:%hu\n",
++        inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+     if( -1 == (r = connect_nonb(sk,(struct sockaddr*)&addr)) ) return -1;
+     peer = new btPeer;
+@@ -154,7 +143,6 @@
+   m_peers_count++;
+   p->peer = peer;
+-  p->click = 0;
+   
+   p->next = m_head;
+   m_head = p;
+@@ -177,28 +165,65 @@
+   struct sockaddr_in addr;
+   btPeer * UNCHOKER[MAX_UNCHOKE + 1];
+   
+-  for( ;NEED_MORE_PEERS() && !IPQUEUE.IsEmpty(); ){
+-    if(IPQUEUE.Pop(&addr) < 0) break;
+-    if(NewPeer(addr,INVALID_SOCKET) == -4) break;
+-  }
++  if( !Tracker.IsPaused() && !Tracker.IsQuitting() )
++    for( ;NEED_MORE_PEERS() && !IPQUEUE.IsEmpty(); ){
++      if(IPQUEUE.Pop(&addr) < 0) break;
++      if(NewPeer(addr,INVALID_SOCKET) == -4) break;
++    }
++
++  Self.SetCurrentRates();
+   // show status line.
+   if( m_pre_dlrate.TimeUsed(pnow) ){
+-    printf("\r                                                                           ");
+-      printf("\r%c %u,[%u/%u/%u],%u,%u | %u,%u  E:%u",
+-         LIVE_CHAR[m_live_idx],
+-         m_peers_count,
+-         BTCONTENT.pBF->Count(),
+-         BTCONTENT.pBF->NBits(),
+-         Pieces_I_Can_Get(),
+-         Self.RateDL(), Self.RateUL(),
+-         m_pre_dlrate.RateMeasure(Self.GetDLRate()),
+-         m_pre_ulrate.RateMeasure(Self.GetULRate()),
+-         Tracker.GetRefuseClick());
++    char partial[30] = "";
++    if(arg_file_to_download){
++      BitField tmpBitField =  *BTCONTENT.pBF;
++      tmpBitField.Except(*BTCONTENT.pBFilter);
++      sprintf( partial, "P:%u/%u ", 
++        tmpBitField.Count(),
++        BTCONTENT.getFilePieces(arg_file_to_download) );
++    }
++    printf("\r                                                                               ");
++    printf("\r%c %u/%u/%u [%u/%u/%u] %lluMB,%lluMB | %u,%uK/s | %u,%uK E:%u,%u %s%s ",
++           LIVE_CHAR[m_live_idx],
++
++           m_seeds_count,
++           m_peers_count - m_seeds_count,
++           Tracker.GetPeersCount(),
++
++           BTCONTENT.pBF->Count(),
++           BTCONTENT.pBF->NBits(),
++           Pieces_I_Can_Get(),
++
++           Self.TotalDL() >> 20, Self.TotalUL() >> 20,
++
++           Self.RateDL() >> 10, Self.RateUL() >> 10,
++
++           m_pre_dlrate.RateMeasure(Self.GetDLRate()) >> 10,
++           m_pre_ulrate.RateMeasure(Self.GetULRate()) >> 10,
++
++           Tracker.GetRefuseClick(),
++           Tracker.GetOkClick(),
++
++           partial,
++
++           (Tracker.GetStatus()==T_CONNECTING) ? "Connecting" :
++             ( (Tracker.GetStatus()==T_READY) ? "Connected" :
++                 (Tracker.IsPaused() ?
++                  ((Tracker.GetStatus()==T_FINISHED) ? "Paused" : "Pausing") :
++                  (Tracker.IsQuitting() ? "Quitting" : "")) )
++    );
+     fflush(stdout);
+     m_pre_dlrate = Self.GetDLRate();
+     m_pre_ulrate = Self.GetULRate();
+     m_live_idx++;
++
++    if(arg_ctcs) CTCS.Report_Status(
++           m_seeds_count, m_peers_count - m_seeds_count,
++           BTCONTENT.pBF->Count(), BTCONTENT.pBF->NBits(), Pieces_I_Can_Get(),
++           Self.RateDL(), Self.RateUL(),
++           Self.TotalDL(), Self.TotalUL(),
++           cfg_max_bandwidth_down, cfg_max_bandwidth_up);
+   }
+     
+   if(KEEPALIVE_INTERVAL <= (*pnow - m_keepalive_check_timestamp)){
+@@ -211,11 +236,14 @@
+     m_unchoke_check_timestamp = *pnow;
+     f_unchoke_check = 1;
+     
+-    Sort();
+   }
+-  if( f_unchoke_check ) memset(UNCHOKER, 0, (MAX_UNCHOKE + 1) * sizeof(btPeer*));
++  if( f_unchoke_check ) {
++    memset(UNCHOKER, 0, (MAX_UNCHOKE + 1) * sizeof(btPeer*));
++    if (OPT_INTERVAL <= *pnow - m_opt_timestamp) m_opt_timestamp = 0;
++  }
++  m_seeds_count = 0;
+   for(p = m_head; p;){
+     if( PEER_IS_FAILED(p->peer)){
+       if( pp ) pp->next = p->next; else m_head = p->next;
+@@ -225,38 +253,38 @@
+       if( pp ) p = pp->next; else p = m_head;
+       continue;
+     }else{
++      if (p->peer->bitfield.IsFull()) m_seeds_count++;
+       if( f_keepalive_check ){
+-      if(3 * KEEPALIVE_INTERVAL <= (*pnow - p->peer->GetLastTimestamp())){
+-        p->peer->CloseConnection();
+-        goto skip_continue;
+-      }
+-      
+-      if(PEER_IS_SUCCESS(p->peer) && 
+-         KEEPALIVE_INTERVAL <= (*pnow - p->peer->GetLastTimestamp()) &&
+-         p->peer->AreYouOK() < 0){
+-        p->peer->CloseConnection();
+-        goto skip_continue;
+-      }
+-      }
+-
+-      if( f_unchoke_check ){
+-
+-      if(PEER_IS_SUCCESS(p->peer) && p->peer->Need_Local_Data()){
+-
+-        if((time_t) 0 == p->peer->GetLastUnchokeTime()){
+-          if(p->peer->SetLocal(M_UNCHOKE) < 0){
+-            p->peer->CloseConnection();
+-            goto skip_continue;
+-          }
+-        }else
+-          UnChokeCheck(p->peer, UNCHOKER);
+-      }
++        if(3 * KEEPALIVE_INTERVAL <= (*pnow - p->peer->GetLastTimestamp())){
++          if(arg_verbose) fprintf(stderr, "close: keepalive expired\n");
++          p->peer->CloseConnection();
++          goto skip_continue;
++        }
++        
++        if(PEER_IS_SUCCESS(p->peer) && 
++           KEEPALIVE_INTERVAL <= (*pnow - p->peer->GetLastTimestamp()) &&
++           p->peer->AreYouOK() < 0){
++          if(arg_verbose) fprintf(stderr, "close: keepalive death\n");
++          p->peer->CloseConnection();
++          goto skip_continue;
++        }
++      }
++
++      if( f_unchoke_check && PEER_IS_SUCCESS(p->peer) ){
++
++        if( p->peer->Is_Remote_Interested() && p->peer->Need_Local_Data() )
++            UnChokeCheck(p->peer, UNCHOKER);
++        else if(p->peer->SetLocal(M_CHOKE) < 0){
++          if(arg_verbose) fprintf(stderr, "close: Can't choke peer\n");
++          p->peer->CloseConnection();
++          goto skip_continue;
++        }
+       }
+       sk = p->peer->stream.GetSocket();
+       if(maxfd < sk) maxfd = sk;
+-      FD_SET(sk,rfdp);
++      if( p->peer->NeedRead() ) FD_SET(sk,rfdp);
+       if( p->peer->NeedWrite() ) FD_SET(sk,wfdp);
+     skip_continue: 
+@@ -272,25 +300,40 @@
+   }
+   if( f_unchoke_check ){
++    if(arg_verbose) fprintf(stderr, "\nUnchoker ");
++    if (!m_opt_timestamp){
++      if(arg_verbose) fprintf(stderr, "(opt) ");
++      m_opt_timestamp = *pnow;
++    }
+     for( i = 0; i < MAX_UNCHOKE + 1; i++){
+       if( (btPeer*) 0 == UNCHOKER[i]) break;
+       if( PEER_IS_FAILED(UNCHOKER[i]) ) continue;
++      if(arg_verbose){
++        fprintf(stderr, "D=%lluMB@%uK/s:U=%lluMB ",
++          UNCHOKER[i]->TotalDL() >> 20, UNCHOKER[i]->RateDL() >> 10,
++          UNCHOKER[i]->TotalUL() >> 20);
++        if( UNCHOKER[i]->bitfield.IsEmpty() ) fprintf(stderr, "(empty) ");
++      }
+       if( UNCHOKER[i]->SetLocal(M_UNCHOKE) < 0){
+-      UNCHOKER[i]->CloseConnection();
+-      continue;
++        if(arg_verbose) fprintf(stderr, "close: Can't unchoke peer\n");
++        UNCHOKER[i]->CloseConnection();
++        continue;
+       }
+       sk = UNCHOKER[i]->stream.GetSocket();
+       if(!FD_ISSET(sk,wfdp) && UNCHOKER[i]->NeedWrite()){
+-      FD_SET(sk,wfdp);
+-      if( maxfd < sk) maxfd = sk;
++        FD_SET(sk,wfdp);
++        if( maxfd < sk) maxfd = sk;
+       }
+     } // end for
++    if(arg_verbose) fprintf(stderr, "\n");
+   }
++
++  Self.ClearCurrentRates();
+   
+   return maxfd;
+ }
+@@ -305,15 +348,148 @@
+     if(proposer->bitfield.IsSet(p->peer->request_q.GetRequestIdx())){
+       if(!peer){
+-      if( p->peer->RateDL() < proposer->RateDL() ) peer = p->peer;
++        if( p->peer->RateDL() < proposer->RateDL() ) peer = p->peer;
+       }else{
+-      if( p->peer->RateDL() < peer->RateDL() ) peer = p->peer;
++        if( p->peer->RateDL() < peer->RateDL() ) peer = p->peer;
+       }
+     }
+   }//end for
+   return peer;
+ }
++// This takes an index parameter to facilitate modification of the function to
++// allow targeting of a specific piece.  It's currently only used as a flag to
++// specify endgame or initial-piece mode though.
++size_t PeerList::What_Can_Duplicate(BitField &bf, btPeer *proposer, size_t idx)
++{
++  PEERNODE *p;
++  btPeer *peer = (btPeer*) 0;
++  int endgame;
++  PSLICE ps;
++  size_t piece, piece1, qsize, mark, bench;
++  unsigned long rndbits;
++  int r=0;
++
++  endgame = idx < BTCONTENT.GetNPieces();     // else initial-piece mode
++  if(endgame) mark = 0;
++  else mark = cfg_req_queue_length;
++  bench = BTCONTENT.GetNPieces();
++
++  // In initial mode, only dup a piece with trade value.
++  // In endgame mode, dup any if there are no pieces with trade value.
++  FindValuedPieces(bf, proposer, !endgame);
++  if( bf.IsEmpty() ){
++    if(endgame) bf = proposer->bitfield;
++    else return BTCONTENT.GetNPieces();
++  }
++
++  /* In endgame mode, select from peers with the longest request queue.
++     In initial mode, select from peers with the shortest non-empty request
++     queue.  */
++  for(p = m_head; p; p = p->next){
++    if( !PEER_IS_SUCCESS(p->peer) || p->peer == proposer ) continue;
++
++    if( p->peer->request_q.IsEmpty() ) continue;
++
++    piece = BTCONTENT.GetNPieces();
++    ps = p->peer->request_q.GetHead();
++    for( ; ps; ps = ps->next){
++      if( piece == ps->index || bench == ps->index || piece1 == ps->index ||
++          !bf.IsSet(ps->index) || proposer->request_q.HasIdx(ps->index) )
++        continue;
++      piece = ps->index;
++
++      qsize = p->peer->request_q.Qlen(piece);
++      if( (endgame && qsize > mark) ||
++          (!endgame && (qsize < mark || !peer)) ){
++        mark = qsize;
++        peer = p->peer;
++        piece1 = piece;
++      }else if( qsize == mark ){
++        if( !r-- ){
++          rndbits = random();
++          r = 30;
++        }
++        if( bench != piece && (rndbits>>=1)&01 ){
++          bench = piece1;
++          peer = p->peer;
++          piece1 = piece;
++        }
++      }
++    }
++  }
++  return peer ? piece1 : BTCONTENT.GetNPieces();
++}
++
++void PeerList::FindValuedPieces(BitField &bf, btPeer *proposer, int initial)
++{
++  PEERNODE *p;
++  BitField bf_all_have = bf, bf_int_have = bf,
++    bf_others_have, bf_only_he_has = bf, bf_prefer;
++
++  for(p = m_head; p; p = p->next){
++    if( !PEER_IS_SUCCESS(p->peer) || p->peer == proposer ) continue;
++    if( p->peer->Need_Remote_Data() )
++      bf_int_have.And(p->peer->bitfield);
++    bf_all_have.And(p->peer->bitfield);
++    if( !initial && !p->peer->bitfield.IsFull() )
++      bf_only_he_has.Except(p->peer->bitfield);
++    else bf_others_have.Comb(p->peer->bitfield);
++  }
++  /* bf_all_have is now pertinent pieces that all peers have
++     bf_int_have is pertinent pieces that all peers in which I'm interested have
++     We prefer to get pieces that those peers need, if we can.  Otherwise go
++     for pieces that any peer needs in hopes of future reciprocation. */
++  if( !bf_int_have.IsFull() )
++    bf_all_have = bf_int_have;
++  bf_all_have.Invert();
++  bf.And(bf_all_have); // bf is now pertinent pieces that not everyone has
++
++  bf_prefer = initial ? bf_others_have : bf_only_he_has;
++
++  BitField tmpBitField = bf;
++  tmpBitField.And(bf_prefer);
++  /* If initial mode, tmpBitField is now pertinent pieces that more than one
++     peer has, but not everyone.
++     Otherwise, it's pertinent pieces that only the proposer has (not
++     considering what other seeders have).
++     In either case if there are no such pieces, revert to the simple answer.*/
++  if( !tmpBitField.IsEmpty() ) bf = tmpBitField;
++}
++
++/* Find a peer with the given piece in its request queue.
++   Duplicating a request queue that's in progress rather than creating a new
++   one helps avoid requesting slices that we already have. */
++btPeer *PeerList::WhoHas(size_t idx)
++{
++  PEERNODE *p;
++  btPeer *peer = (btPeer*) 0;
++
++  for( p = m_head; p; p = p->next){
++    if( p->peer->request_q.HasIdx(idx) ){
++      peer = p->peer;
++      break;
++    }
++  }
++  return peer;
++}
++
++void PeerList::CancelSlice(size_t idx, size_t off, size_t len)
++{
++  PEERNODE *p;
++  PSLICE ps;
++
++  for( p = m_head; p; p = p->next){
++    
++    if( !PEER_IS_SUCCESS(p->peer) ) continue;
++
++    if (p->peer->CancelSliceRequest(idx,off,len) < 0) {
++      if(arg_verbose) fprintf(stderr, "close: CancelSlice\n");
++      p->peer->CloseConnection();
++    }
++  }
++}
++
+ void PeerList::Tell_World_I_Have(size_t idx)
+ {
+   PEERNODE *p;
+@@ -325,12 +501,18 @@
+     
+     if( !PEER_IS_SUCCESS(p->peer) ) continue;
+-    if( p->peer->stream.Send_Have(idx) < 0) 
++    // Don't send HAVE to seeders, except for our first piece.
++    if( (!p->peer->bitfield.IsFull() || 1==BTCONTENT.pBF->Count()) &&
++        p->peer->stream.Send_Have(idx) < 0) 
+       p->peer->CloseConnection();
+     
+     if( f_seed ){
+       if( !p->peer->request_q.IsEmpty() ) p->peer->request_q.Empty();
+-      if(p->peer->SetLocal(M_NOT_INTERESTED) < 0) p->peer->CloseConnection();
++      if(p->peer->SetLocal(M_NOT_INTERESTED) < 0) {
++        if(arg_verbose)
++          fprintf(stderr, "close: Can't set self not interested (T_W_I_H)\n");
++        p->peer->CloseConnection();
++      }
+     }
+     
+   } // end for
+@@ -350,6 +532,11 @@
+     CLOSE_SOCKET(newsk);
+     return -1;
+   }
++
++  if( Tracker.IsPaused() || Tracker.IsQuitting() ){
++    CLOSE_SOCKET(newsk);
++    return -1;
++  }
+   
+   return NewPeer(addr,newsk);
+ }
+@@ -359,18 +546,23 @@
+   int r = 0;
+   struct sockaddr_in lis_addr;
+   memset(&lis_addr,0, sizeof(sockaddr_in));
++  lis_addr.sin_family = AF_INET;
+   lis_addr.sin_addr.s_addr = INADDR_ANY;
+   m_listen_sock = socket(AF_INET,SOCK_STREAM,0);
+   if( INVALID_SOCKET == m_listen_sock ) return -1;
++  if ( cfg_listen_ip != 0 )
++    lis_addr.sin_addr.s_addr = cfg_listen_ip;
++
+   if(cfg_listen_port && cfg_listen_port != LISTEN_PORT_MAX){
+     lis_addr.sin_port = htons(cfg_listen_port);
+     if(bind(m_listen_sock,(struct sockaddr*)&lis_addr,sizeof(struct sockaddr_in)) == 0) 
+       r = 1;
+     else
+-      fprintf(stderr,"warn,couldn't bind on specified port: %d\n",cfg_listen_port);
++      fprintf(stderr,"warn,couldn't bind on specified port %d: %s\n",
++        cfg_listen_port,strerror(errno));
+   }
+   if( !r ){
+@@ -380,20 +572,21 @@
+       lis_addr.sin_port = htons(cfg_listen_port);
+       r = bind(m_listen_sock,(struct sockaddr*)&lis_addr,sizeof(struct sockaddr_in));
+       if(r != 0){
+-      cfg_listen_port--;
+-      if(cfg_listen_port < cfg_min_listen_port){
+-        CLOSE_SOCKET(m_listen_sock);
+-        fprintf(stderr,"error,couldn't bind port from %d to %d.\n",
+-                cfg_min_listen_port,cfg_max_listen_port);
+-        return -1;
+-      }
++        cfg_listen_port--;
++        if(cfg_listen_port < cfg_min_listen_port){
++          CLOSE_SOCKET(m_listen_sock);
++          fprintf(stderr,"error,couldn't bind port from %d to %d: %s\n",
++            cfg_min_listen_port,cfg_max_listen_port,strerror(errno));
++          return -1;
++        }
+       }
+     } /* end for(; r != 0;) */
+   }
+   if(listen(m_listen_sock,5) == -1){
+     CLOSE_SOCKET(m_listen_sock);
+-    fprintf(stderr,"error, couldn't listen on port %d.\n",cfg_listen_port);
++    fprintf(stderr,"error, couldn't listen on port %d: %s\n",
++      cfg_listen_port,strerror(errno));
+     return -1;
+   }
+   
+@@ -402,6 +595,9 @@
+     fprintf(stderr,"error, couldn't set socket to nonblock mode.\n");
+     return -1;
+   }
++
++  printf("Listening on %s:%d\n", inet_ntoa(lis_addr.sin_addr),
++    ntohs(lis_addr.sin_port));
+   
+   return 0;
+ }
+@@ -425,7 +621,7 @@
+   PEERNODE *p;
+   for(p = m_head; p; p = p->next){
+     if( !PEER_IS_SUCCESS(p->peer) || p->peer->request_q.IsEmpty()) continue;
+-    if( idx == p->peer->request_q.GetRequestIdx() ) return 1;
++    if( p->peer->request_q.HasIdx(idx) ) return 1;
+   }
+   return 0;
+ }
+@@ -433,9 +629,18 @@
+ void PeerList::CheckBitField(BitField &bf)
+ {
+   PEERNODE *p;
++  PSLICE ps;
++  size_t idx;
+   for(p = m_head; p ; p = p->next){
+     if( !PEER_IS_SUCCESS(p->peer) || p->peer->request_q.IsEmpty()) continue;
+-    bf.UnSet(p->peer->request_q.GetRequestIdx());
++    ps = p->peer->request_q.GetHead();
++    idx = BTCONTENT.GetNPieces();
++    for( ; ps; ps = ps->next){
++      if( ps->index != idx ){
++        bf.UnSet(ps->index);
++        idx = ps->index;
++      }
++    }
+   }
+ }
+@@ -445,8 +650,8 @@
+   struct sockaddr_in sin;
+   printf("\nPEER LIST\n");
+   for( ; p ; p = p->next){
+-      if(PEER_IS_FAILED(p->peer)) continue;
+-      p->peer->dump();
++        if(PEER_IS_FAILED(p->peer)) continue;
++        p->peer->dump();
+   }
+ }
+@@ -470,42 +675,55 @@
+     if( P_CONNECTING == peer->GetStatus()){
+       if(FD_ISSET(sk,wfdp)){
+-      (*nready)--; 
+-      FD_CLR(sk,wfdp);
++        (*nready)--; 
++        FD_CLR(sk,wfdp);
+-      if(FD_ISSET(sk,rfdp)){  // connect failed.
+-        FD_CLR(sk,rfdp);
+-        peer->CloseConnection();
+-      }else{
+-        if(peer->Send_ShakeInfo() < 0){
+-          peer->CloseConnection();
+-        }
+-        else 
+-          peer->SetStatus(P_HANDSHAKE);
+-      }
++        if(FD_ISSET(sk,rfdp)){        // connect failed.
++          (*nready)--; 
++          FD_CLR(sk,rfdp);
++          peer->CloseConnection();
++        }else{
++          if(peer->Send_ShakeInfo() < 0){
++            if(arg_verbose) fprintf(stderr, "close: Sending handshake\n");
++            peer->CloseConnection();
++          }
++          else 
++            peer->SetStatus(P_HANDSHAKE);
++        }
++      }else if(FD_ISSET(sk,rfdp)){
++        (*nready)--; 
++        peer->CloseConnection();
+       }
+     }else{
+       if(FD_ISSET(sk,rfdp)){
+-      p->click++;
+-      if( !(p->click) ) 
+-        for(p2 = m_head; p2; p2=p2->next) p2->click = 0;
+-      
+-      (*nready)--;
+-      FD_CLR(sk,rfdp);
+-      if(peer->GetStatus() == P_HANDSHAKE){
+-        if( peer->HandShake() < 0 ) peer->CloseConnection();
+-      }else{
+-        if( peer->RecvModule() < 0 ) peer->CloseConnection();
+-      }
+-      }else if(PEER_IS_SUCCESS(peer) && FD_ISSET(sk,wfdp)){
+-      p->click++;
+-      if( !(p->click) )
+-        for(p2 = m_head; p2; p2=p2->next) p2->click = 0;
+-
+-      (*nready)--;
+-      FD_CLR(sk,wfdp);
+-      if( peer->SendModule() < 0 ) peer->CloseConnection();
++        (*nready)--;
++        FD_CLR(sk,rfdp);
++        if(peer->GetStatus() == P_HANDSHAKE){
++          if( peer->HandShake() < 0 ) {
++            if(arg_verbose) fprintf(stderr, "close: bad handshake\n");
++            peer->CloseConnection();
++          }
++        } // fixed client stall
++        if(peer->GetStatus() == P_SUCCESS){
++          if( peer->RecvModule() < 0 ) {
++            if(arg_verbose) fprintf(stderr, "close: receive\n");
++            peer->CloseConnection();
++          }
++        }
++      }else if( peer->HealthCheck(now) < 0 ){
++        if(arg_verbose) fprintf(stderr, "close: unresponsive\n");
++        peer->CloseConnection();
+       }
++
++      if( (PEER_IS_SUCCESS(peer) || peer->GetStatus() == P_HANDSHAKE) &&
++          FD_ISSET(sk,wfdp) ){
++        (*nready)--;
++        FD_CLR(sk,wfdp);
++        if( peer->SendModule() < 0 ) {
++          if(arg_verbose) fprintf(stderr, "close: send\n");
++          peer->CloseConnection();
++        }
++      }else peer->CheckSendStatus();
+     }
+   }// end for
+ }
+@@ -514,7 +732,10 @@
+ {
+   PEERNODE *p = m_head;
+   for( ; p; p = p->next)
+-    if(p->peer->bitfield.IsFull()) p->peer->CloseConnection();
++    if(p->peer->bitfield.IsFull()) {
++      if(arg_verbose) fprintf(stderr, "close: seed<->seed\n");
++      p->peer->CloseConnection();
++    }
+ }
+ void PeerList::UnChokeCheck(btPeer* peer, btPeer *peer_array[])
+@@ -523,51 +744,170 @@
+   int cancel_idx = 0;
+   btPeer *loster = (btPeer*) 0;
+   int f_seed = BTCONTENT.pBF->IsFull();
+-
+-  for( cancel_idx = i = 0; i < MAX_UNCHOKE; i++ ){
+-    if((btPeer*) 0 == peer_array[i] || PEER_IS_FAILED(peer_array[i]) ){       // ÓпÕλ
++  int no_opt = 0;
++  unsigned long rndbits;
++  int r=0;
++
++  if (m_opt_timestamp) no_opt = 1;
++
++// Find my 3 or 4 fastest peers.
++// The MAX_UNCHOKE+1 (4th) slot is for the optimistic unchoke when it happens.
++
++  // Find a slot for the candidate--the slowest peer, or an available slot.
++  for( cancel_idx = i = 0; i < MAX_UNCHOKE+no_opt; i++ ){
++    if((btPeer*) 0 == peer_array[i] ||
++        PEER_IS_FAILED(peer_array[i]) ){      // ÓпÕλ
+       cancel_idx = i; 
+       break;
+     }else{
+       if(cancel_idx == i) continue;
+       if(f_seed){
+-      // compare upload rate.
+-      if(peer_array[cancel_idx]->RateUL() > peer_array[i]->RateUL())
+-        cancel_idx = i;
++        // compare upload rate.
++        if(peer_array[cancel_idx]->RateUL() > peer_array[i]->RateUL())
++          cancel_idx = i;
+       }else{
+-      // compare download rate.
+-      if(peer_array[cancel_idx]->RateDL() > peer_array[i]->RateDL())
+-        cancel_idx = i;
++        // compare download rate.
++        if( peer_array[cancel_idx]->RateDL() > peer_array[i]->RateDL()
++          //if equal, reciprocate to the peer we've sent less to, proportionally
++          ||(peer_array[cancel_idx]->RateDL() == peer_array[i]->RateDL()
++            && peer_array[cancel_idx]->TotalUL()
++                / (peer_array[cancel_idx]->TotalDL()+.001)
++              < peer_array[i]->TotalUL() / (peer_array[i]->TotalDL()+.001)) )
++          cancel_idx = i;
+       }
+     }
+   } // end for
+-  if( (btPeer*) 0 != peer_array[cancel_idx] && PEER_IS_SUCCESS(peer_array[cancel_idx]) ){
++  if( (btPeer*) 0 != peer_array[cancel_idx] &&
++      PEER_IS_SUCCESS(peer_array[cancel_idx]) ){
+     if(f_seed){
+       if(peer->RateUL() > peer_array[cancel_idx]->RateUL()){
+-      loster = peer_array[cancel_idx];
+-      peer_array[cancel_idx] = peer;
++        loster = peer_array[cancel_idx];
++        peer_array[cancel_idx] = peer;
+       }else
+-      loster = peer;
++        loster = peer;
+     }else{
+-      if(peer->RateDL() > peer_array[cancel_idx]->RateDL()){
+-      loster = peer_array[cancel_idx];
+-      peer_array[cancel_idx] = peer;
++      if( peer->RateDL() > peer_array[cancel_idx]->RateDL()
++        // If equal, reciprocate to the peer we've sent less to, proportionally
++        ||(peer_array[cancel_idx]->RateDL() == peer->RateDL()
++          && peer_array[cancel_idx]->TotalUL()
++                / (peer_array[cancel_idx]->TotalDL()+.001)
++            > peer->TotalUL() / (peer->TotalDL()+.001)) ){
++        loster = peer_array[cancel_idx];
++        peer_array[cancel_idx] = peer;
+       }else
+-      loster = peer;
++        loster = peer;
+     }
+     // opt unchoke
+-    if((btPeer*) 0 == peer_array[MAX_UNCHOKE] || PEER_IS_FAILED(peer_array[MAX_UNCHOKE]) )
++    if (no_opt) {
++      if(loster->SetLocal(M_CHOKE) < 0) loster->CloseConnection();
++    }
++    else
++    // The last slot is for the optimistic unchoke.
++    if( (btPeer*) 0 == peer_array[MAX_UNCHOKE] ||
++        PEER_IS_FAILED(peer_array[MAX_UNCHOKE]) )
+       peer_array[MAX_UNCHOKE] = loster;
+-    else{
+-      if(loster->GetLastUnchokeTime() < peer_array[MAX_UNCHOKE]->GetLastUnchokeTime())
+-      peer_array[MAX_UNCHOKE] = loster;
+-      else{
+-      if(loster->SetLocal(M_CHOKE) < 0) loster->CloseConnection();
++    else {
++      if( !r-- ){
++        rndbits = random();
++        r = 15;
++      }
++      // if loser is empty and current is not, loser gets 75% chance.
++      if( loster->IsEmpty() && !peer_array[MAX_UNCHOKE]->IsEmpty()
++            && (rndbits>>=2)&3 ) {
++        btPeer* tmp = peer_array[MAX_UNCHOKE];
++        peer_array[MAX_UNCHOKE] = loster;
++        loster = tmp;
++      } else
++        // This mess chooses the loser:
++        // if loser is choked and current is not
++        // OR if both are choked and loser has waited longer
++        // OR if both are unchoked and loser has had less time unchoked.
++      if( (!loster->Is_Local_UnChoked() &&
++            ( peer_array[MAX_UNCHOKE]->Is_Local_UnChoked() ||
++              loster->GetLastUnchokeTime() <
++                peer_array[MAX_UNCHOKE]->GetLastUnchokeTime() )) ||
++          (peer_array[MAX_UNCHOKE]->Is_Local_UnChoked() &&
++            peer_array[MAX_UNCHOKE]->GetLastUnchokeTime() <
++              loster->GetLastUnchokeTime()) ){
++        // if current is empty and loser is not, loser gets 25% chance;
++        //    else loser wins.
++        // transformed to: if loser is empty or current isn't, or 25% chance,
++        //    then loser wins.
++        if( !peer_array[MAX_UNCHOKE]->IsEmpty() || loster->IsEmpty()
++            || !((rndbits>>=2)&3) ) {
++          btPeer* tmp = peer_array[MAX_UNCHOKE];
++          peer_array[MAX_UNCHOKE] = loster;
++          loster = tmp;
++        }
+       }
++      if(loster->SetLocal(M_CHOKE) < 0) loster->CloseConnection();
+     }
+   }else //else if((btPeer*) 0 != peer_array[cancel_idx].....
+     peer_array[cancel_idx] = peer;
+ }
++
++// When we change what we're going after, we need to evaluate & set our
++// interest with each peer appropriately.
++void PeerList::CheckInterest()
++{
++  PEERNODE *p = m_head;
++  for( ; p; p = p->next) {
++    // Don't shortcut by checking Is_Local_Interested(), as we need to let
++    // SetLocal() reset the m_standby flag.
++    if( p->peer->Need_Remote_Data() ) {
++      if( p->peer->SetLocal(M_INTERESTED) < 0 )
++        p->peer->CloseConnection();
++    } else {
++      if( p->peer->SetLocal(M_NOT_INTERESTED) < 0 )
++        p->peer->CloseConnection();
++    }
++  }
++}
++
++btPeer* PeerList::GetNextPeer(btPeer *peer)
++{
++  static PEERNODE *p = m_head;
++
++  if( 0==peer ) p = m_head;
++  else if( p->peer == peer ){
++    p = p->next;
++  }else{
++    for( p=m_head; p && (p->peer != peer); p = p->next);
++    if( 0 == p->peer ){
++      p = m_head;
++    }else{
++      p = p->next;
++    }
++  }
++  for( ; p; p = p->next)
++    if( p->peer && PEER_IS_SUCCESS(p->peer) ) break;
++
++  if(p) return p->peer;
++  else return (btPeer*) 0;
++}
++
++// This is used to un-standby peers when we enter endgame mode.
++// It re-evaluates at most once per second for CPU efficiency, so isn't used
++// when greatest accuracy is desired.
++int PeerList::Endgame()
++{
++  static time_t timestamp = 0;
++  static int endgame = 0;
++
++  if( now > timestamp ){
++    timestamp = now;
++    if( arg_file_to_download ){
++      BitField afdBitField =  *BTCONTENT.pBF;
++      afdBitField.Except(*BTCONTENT.pBFilter);
++      endgame = ( BTCONTENT.getFilePieces(arg_file_to_download)
++                  - afdBitField.Count() ) < WORLD.TotalPeers();
++    }else
++      endgame = ( WORLD.Pieces_I_Can_Get() - BTCONTENT.pBF->Count() )
++                  < WORLD.TotalPeers();
++  }
++  return endgame;
++}
++
+--- peerlist.h.orig    Wed Sep  8 16:10:51 2004
++++ peerlist.h Sun Dec 25 13:34:02 2005
+@@ -1,14 +1,13 @@
+ #ifndef PEERLIST_H
+ #define PEERLIST_H
+-#include <sys/types.h>
+ #include "./def.h"
++#include <sys/types.h>
+ #include "./peer.h"
+ #include "./rate.h"
+ typedef struct _peernode{
+   btPeer *peer;
+-  size_t click;
+   struct _peernode *next;
+ }PEERNODE;
+@@ -18,7 +17,8 @@
+   SOCKET m_listen_sock;
+   PEERNODE *m_head;
+   size_t m_peers_count;
+-  time_t m_unchoke_check_timestamp, m_keepalive_check_timestamp, m_last_progress_timestamp;
++  size_t m_seeds_count;
++  time_t m_unchoke_check_timestamp, m_keepalive_check_timestamp, m_last_progress_timestamp, m_opt_timestamp;
+   unsigned char m_live_idx:2;
+   unsigned char m_reserved:6;
+@@ -26,7 +26,6 @@
+   Rate m_pre_dlrate, m_pre_ulrate;
+   
+   int Accepter();
+-  void Sort();
+   void UnChokeCheck(btPeer* peer,btPeer *peer_array[]);
+   
+  public:
+@@ -50,9 +49,16 @@
+   
+   void Tell_World_I_Have(size_t idx);
+   btPeer* Who_Can_Abandon(btPeer *proposer);
++  size_t What_Can_Duplicate(BitField &bf, btPeer *proposer, size_t idx);
++  void FindValuedPieces(BitField &bf, btPeer *proposer, int initial);
++  btPeer *WhoHas(size_t idx);
++  void CancelSlice(size_t idx, size_t off, size_t len);
+   void CheckBitField(BitField &bf);
+   int AlreadyRequested(size_t idx);
+   size_t Pieces_I_Can_Get();
++  void CheckInterest();
++  btPeer* GetNextPeer(btPeer *peer);
++  int Endgame();
+ };
+ extern PeerList WORLD;
+--- rate.cpp.orig      Wed Sep  8 16:10:51 2004
++++ rate.cpp   Sun Jan  1 20:40:15 2006
+@@ -1,14 +1,17 @@
+ #include "rate.h"
++#include "bttime.h"
++
++#define RATE_INTERVAL 20
+ void Rate::StartTimer()
+ {
+-  if( !m_last_timestamp ) time(&m_last_timestamp);
++  if( !m_last_timestamp ) m_last_timestamp = now;
+ }
+ void Rate::StopTimer()
+ {
+-  if( !m_last_timestamp ){
+-    m_total_timeused += (time((time_t*) 0) - m_last_timestamp);
++  if( m_last_timestamp ){
++    m_total_timeused += (now - m_last_timestamp);
+     m_last_timestamp = 0;
+   }
+ }
+@@ -16,27 +19,61 @@
+ void Rate::CountAdd(size_t nbytes)
+ {
+   m_count_bytes += nbytes;
++
++  // save bandwidth history data
++  for (int i=0; i <= n_samples; i++)
++  {
++    if (i < MAX_SAMPLES)
++    {
++      if (now == m_timestamp_sample[i]) {
++        m_bytes_sample[i] += nbytes;
++        break;
++      }
++      else if (now - RATE_INTERVAL > m_timestamp_sample[i]) {
++        m_timestamp_sample[i] = now;
++        m_bytes_sample[i] = nbytes;
++        if (n_samples < MAX_SAMPLES) n_samples++;
++        break;
++      }
++    }
++  }
+ }
+ void Rate::operator=(const Rate &ra)
+ {
+-  m_last_timestamp = time((time_t*) 0);
++  m_last_timestamp = now;
+   m_count_bytes = ra.m_count_bytes;
+ }
+ size_t Rate::RateMeasure() const
+ {
+-  time_t timeused = m_total_timeused;
+-  if( m_last_timestamp ) timeused += (time((time_t*) 0) - m_last_timestamp);
++  // calculate rate based on bandwidth history data
++  time_t timestamp = now;
++  u_int64_t countbytes = 0;
++  time_t timeused = 0;
++
++  if( !m_last_timestamp ) return 0; // no current rate
++
++  timeused = (TimeUsed(&timestamp) < RATE_INTERVAL) ?
++    TimeUsed(&timestamp) : RATE_INTERVAL;
+   if( timeused < 1 ) timeused = 1;
+-  return (size_t)(m_count_bytes / timeused);
++
++  for (int i=0; i<n_samples; i++)
++  {
++    if (timestamp - m_timestamp_sample[i] <= timeused)
++      countbytes += m_bytes_sample[i];
++  }
++  return (size_t)(countbytes / timeused);
+ }
+ size_t Rate::RateMeasure(const Rate &ra_to) const
+ {
+-  time_t timeused = time((time_t*) 0) - m_last_timestamp;
++  int tmp;
++  time_t timeused = now - m_last_timestamp;
+   if( timeused < 1 ) timeused = 1;
+-  return (size_t)((ra_to.m_count_bytes - m_count_bytes) / timeused);
++  tmp = (ra_to.m_count_bytes - ra_to.m_recent_base)
++      - (m_count_bytes - m_recent_base);
++  return (size_t)( (tmp>0) ? (tmp/timeused) : 0 );
+ }
+ time_t Rate::TimeUsed(const time_t *pnow) const
+--- rate.h.orig        Wed Sep  8 16:10:51 2004
++++ rate.h     Mon Nov 21 16:25:13 2005
+@@ -1,18 +1,33 @@
+ #ifndef RATE_H
+ #define RATE_H
++#include "def.h"
+ #include <sys/types.h>
+ #include <time.h>
+-#include "def.h"
++
++#define MAX_SAMPLES 20
+ class Rate{
+  private:
+   time_t m_last_timestamp;
+   time_t m_total_timeused;
+   u_int64_t m_count_bytes;
++  u_int64_t m_recent_base;
++  
++  // bandwidth history data
++  size_t n_samples;
++  time_t m_timestamp_sample[MAX_SAMPLES];
++  u_int64_t m_bytes_sample[MAX_SAMPLES];
++
+  public:
+-  Rate(){ m_last_timestamp = m_total_timeused = (time_t)0; m_count_bytes = 0; }
+-  void Reset(){ m_last_timestamp = m_total_timeused = (time_t)0; m_count_bytes = 0;}
++  Rate(){ m_last_timestamp = m_total_timeused = (time_t)0;
++    m_recent_base = m_count_bytes = 0;
++    n_samples=0; for(int i=0;i<MAX_SAMPLES;i++) m_timestamp_sample[i]=0;
++  }
++  void Reset(){ m_last_timestamp = m_total_timeused = (time_t)0;
++    m_recent_base = m_count_bytes;
++    n_samples = 0; for(int i=0;i<MAX_SAMPLES;i++) m_timestamp_sample[i]=0;
++  }
+   void StartTimer();
+   void StopTimer();
+   void CountAdd(size_t nbytes);
+--- sha1.c.orig        Sun Jan 15 00:28:13 2006
++++ sha1.c     Thu Oct 13 20:27:00 2005
+@@ -0,0 +1,146 @@
++#include <string.h>
++
++#include "sha1.h"
++
++#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
++
++/* blk0() and blk() perform the initial expand. */
++/* I got the idea of expanding during the round function from SSLeay */
++#if (defined(BYTE_ORDER) && BYTE_ORDER==LITTLE_ENDIAN) || (!defined(BYTE_ORDER) && defined(LITTLE_ENDIAN))
++#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
++    |(rol(block->l[i],8)&0x00FF00FF))
++#else
++#define blk0(i) block->l[i]
++#endif
++#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
++    ^block->l[(i+2)&15]^block->l[i&15],1))
++
++/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
++#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
++#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
++#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
++#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
++#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
++
++
++/* Hash a single 512-bit block. This is the core of the algorithm. */
++
++void SHA1Transform(unsigned long state[5], unsigned char buffer[64])
++{
++unsigned long a, b, c, d, e;
++typedef union {
++    unsigned char c[64];
++    unsigned long l[16];
++} CHAR64LONG16;
++CHAR64LONG16* block;
++#ifdef SHA1HANDSOFF
++static unsigned char workspace[64];
++    block = (CHAR64LONG16*)workspace;
++    memcpy(block, buffer, 64);
++#else
++    block = (CHAR64LONG16*)buffer;
++#endif
++    /* Copy context->state[] to working vars */
++    a = state[0];
++    b = state[1];
++    c = state[2];
++    d = state[3];
++    e = state[4];
++    /* 4 rounds of 20 operations each. Loop unrolled. */
++    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
++    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
++    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
++    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
++    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
++    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
++    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
++    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
++    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
++    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
++    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
++    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
++    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
++    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
++    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
++    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
++    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
++    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
++    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
++    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
++    /* Add the working vars back into context.state[] */
++    state[0] += a;
++    state[1] += b;
++    state[2] += c;
++    state[3] += d;
++    state[4] += e;
++    /* Wipe variables */
++    a = b = c = d = e = 0;
++}
++
++
++/* SHA1Init - Initialize new context */
++
++void SHA1Init(SHA1_CTX* context)
++{
++    /* SHA1 initialization constants */
++    context->state[0] = 0x67452301;
++    context->state[1] = 0xEFCDAB89;
++    context->state[2] = 0x98BADCFE;
++    context->state[3] = 0x10325476;
++    context->state[4] = 0xC3D2E1F0;
++    context->count[0] = context->count[1] = 0;
++}
++
++
++/* Run your data through this. */
++
++void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
++{
++unsigned int i, j;
++
++    j = (context->count[0] >> 3) & 63;
++    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
++    context->count[1] += (len >> 29);
++    if ((j + len) > 63) {
++        memcpy(&context->buffer[j], data, (i = 64-j));
++        SHA1Transform(context->state, context->buffer);
++        for ( ; i + 63 < len; i += 64) {
++            SHA1Transform(context->state, &data[i]);
++        }
++        j = 0;
++    }
++    else i = 0;
++    memcpy(&context->buffer[j], &data[i], len - i);
++}
++
++
++/* Add padding and return the message digest. */
++
++void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
++{
++unsigned long i, j;
++unsigned char finalcount[8];
++
++    for (i = 0; i < 8; i++) {
++        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
++         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
++    }
++    SHA1Update(context, (unsigned char *)"\200", 1);
++    while ((context->count[0] & 504) != 448) {
++        SHA1Update(context, (unsigned char *)"\0", 1);
++    }
++    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
++    for (i = 0; i < 20; i++) {
++        digest[i] = (unsigned char)
++         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
++    }
++    /* Wipe variables */
++    i = j = 0;
++    memset(context->buffer, 0, 64);
++    memset(context->state, 0, 20);
++    memset(context->count, 0, 8);
++    memset(&finalcount, 0, 8);
++#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
++    SHA1Transform(context->state, context->buffer);
++#endif
++}
+--- sha1.h.orig        Sun Jan 15 00:28:13 2006
++++ sha1.h     Thu Oct 13 20:27:00 2005
+@@ -0,0 +1,43 @@
++#ifndef SHA1_H
++#define SHA1_H
++
++/*
++SHA-1 in C
++By Steve Reid <steve@edmweb.com>
++100% Public Domain
++
++Test Vectors (from FIPS PUB 180-1)
++"abc"
++  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
++"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
++  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
++A million repetitions of "a"
++  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
++*/
++
++#include <sys/types.h>
++
++/* #define LITTLE_ENDIAN * This should be #define'd if true. */
++/* #define SHA1HANDSOFF * Copies data before messing with it. */
++#define SHA1HANDSOFF
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++typedef struct {
++    unsigned long state[5];
++    unsigned long count[2];
++    unsigned char buffer[64];
++} SHA1_CTX;
++
++void SHA1Transform(unsigned long state[5], unsigned char buffer[64]);
++void SHA1Init(SHA1_CTX* context);
++void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
++void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+--- sigint.cpp.orig    Wed Sep  8 16:10:51 2004
++++ sigint.cpp Mon Nov  7 20:33:00 2005
+@@ -4,17 +4,28 @@
+ #include <signal.h>
+ #include "btcontent.h"
++#include "tracker.h"
+ #include "peerlist.h"
+ #include "btconfig.h"
++#include "sigint.h"
+-void sigint_catch(int sig_no)
++void sig_catch(int sig_no)
+ {
+-  if(SIGINT == sig_no){
++  if(SIGINT == sig_no || SIGTERM == sig_no){
++    if( Tracker.IsPaused() ) Tracker.ClearPause();
++    Tracker.SetStoped();
++    signal(sig_no,sig_catch2);
++  }
++}
++
++static void sig_catch2(int sig_no)
++{
++  if(SIGINT == sig_no || SIGTERM == sig_no){
+     if( cfg_cache_size ) BTCONTENT.FlushCache();
+     if( arg_bitfield_file ) BTCONTENT.pBF->WriteToFile(arg_bitfield_file);
+     WORLD.CloseAll();
+-    signal(SIGINT,SIG_DFL);
+-    raise(SIGINT);
++    signal(sig_no,SIG_DFL);
++    raise(sig_no);
+   }
+ }
+--- sigint.h.orig      Wed Sep  8 16:10:51 2004
++++ sigint.h   Thu Jun  2 20:27:00 2005
+@@ -2,7 +2,8 @@
+ #define SIGINT_H
+ #ifndef WINDOWS
+-void sigint_catch(int sig_no);
++void sig_catch(int sig_no);
++static void sig_catch2(int sig_no);
+ #endif
+ #endif
+--- tracker.cpp.orig   Wed Sep  8 16:10:51 2004
++++ tracker.cpp        Sun Jan  1 20:40:31 2006
+@@ -20,6 +20,7 @@
+ #include "iplist.h"
+ #include "btconfig.h"
++#include "ctcs.h"
+ btTracker Tracker;
+@@ -27,15 +28,19 @@
+ {
+   memset(m_host,0,MAXHOSTNAMELEN);
+   memset(m_path,0,MAXPATHLEN);
++  memset(m_trackerid,0,PEER_ID_LEN+1);
+   m_sock = INVALID_SOCKET;
+   m_port = 80;
+   m_status = T_FREE;
+-  m_f_started = m_f_stoped = m_f_pause = 0;
++  m_f_started = m_f_stoped = m_f_pause = m_f_completed = 0;
++  m_f_softquit = m_f_restart = 0;
++
+   m_interval = 15;
+   m_connect_refuse_click = 0;
+   m_last_timestamp = (time_t) 0;
++  m_prevpeers = 0;
+ }
+ btTracker::~btTracker()
+@@ -54,7 +59,11 @@
+   
+   m_reponse_buffer.Reset();
+   time(&m_last_timestamp);
+-  m_status = T_FREE;
++  if (m_f_stoped){
++    m_status = T_FINISHED;
++    if( m_f_restart ) Resume();
++  }
++  else m_status = T_FREE;
+ }
+ int btTracker:: _IPsin(char *h, int p, struct sockaddr_in *psin)
+@@ -74,8 +83,8 @@
+     if(psin->sin_addr.s_addr == INADDR_NONE){
+       struct hostent *ph = gethostbyname(h);
+       if( !ph  || ph->h_addrtype != AF_INET){
+-      memset(psin,0,sizeof(struct sockaddr_in));
+-      return -1;
++        memset(psin,0,sizeof(struct sockaddr_in));
++        return -1;
+       }
+       memcpy(&psin->sin_addr,ph->h_addr_list[0],sizeof(struct in_addr));
+     }
+@@ -93,7 +102,7 @@
+   struct sockaddr_in addr;
+-  if( decode_query(buf,bufsiz,"failure reason",&ps,&i,QUERY_STR) ){
++  if( decode_query(buf,bufsiz,"failure reason",&ps,&i,(int64_t*) 0,QUERY_STR) ){
+     char failreason[1024];
+     if( i < 1024 ){
+       memcpy(failreason, ps, i);
+@@ -104,14 +113,55 @@
+       strcat(failreason,"...");
+     }
+     fprintf(stderr,"TRACKER FAILURE REASON: %s\n",failreason);
++    if(arg_ctcs){
++      char ctcsinfo[1048];
++      snprintf(ctcsinfo,1048,"TRACKER FAILURE REASON: %s",failreason);
++      CTCS.Send_Info(ctcsinfo);
++    }
+     return -1;
+   }
++  if( decode_query(buf,bufsiz,"warning message",&ps,&i,(int64_t*) 0,QUERY_STR) ){
++    char warnmsg[1024];
++    if( i < 1024 ){
++      memcpy(warnmsg, ps, i);
++      warnmsg[i] = '\0';
++    }else{
++      memcpy(warnmsg, ps, 1000);
++      warnmsg[1000] = '\0';
++      strcat(warnmsg,"...");
++    }
++    fprintf(stderr,"TRACKER WARNING: %s\n",warnmsg);
++    if(arg_ctcs){
++      char ctcsinfo[1048];
++      snprintf(ctcsinfo,1048,"TRACKER WARNING: %s",warnmsg);
++      CTCS.Send_Info(ctcsinfo);
++    }
++  }
+-  if(!decode_query(buf,bufsiz,"interval",(const char**) 0,&i,QUERY_INT)){return -1;}
++  m_peers_count = 0;
++
++  if( decode_query(buf,bufsiz,"tracker id",&ps,&i,(int64_t*) 0,QUERY_STR) ){
++    if( i <= PEER_ID_LEN ){
++      memcpy(m_trackerid, ps, i);
++      m_trackerid[i] = '\0';
++    }else{
++      memcpy(m_trackerid, ps, PEER_ID_LEN);
++      m_trackerid[PEER_ID_LEN] = '\0';
++    }
++  }
++
++  if(!decode_query(buf,bufsiz,"interval",(const char**) 0,&i,(int64_t*) 0,QUERY_INT)){return -1;}
+   if(m_interval != (time_t)i) m_interval = (time_t)i;
+-  pos = decode_query(buf,bufsiz,"peers",(const char**) 0,(size_t *) 0,QUERY_POS);
++  if(decode_query(buf,bufsiz,"complete",(const char**) 0,&i,(int64_t*) 0,QUERY_INT)) {
++    m_peers_count += i;
++  }
++  if(decode_query(buf,bufsiz,"incomplete",(const char**) 0,&i,(int64_t*) 0,QUERY_INT)) {
++    m_peers_count += i;
++  }
++
++  pos = decode_query(buf,bufsiz,"peers",(const char**) 0,(size_t *) 0,(int64_t*) 0,QUERY_POS);
+   if( !pos ){
+     return -1;
+@@ -123,32 +173,32 @@
+   ps = buf-1;
+   if (*ps != 'l') {           // binary peers section if not 'l'
+-      addr.sin_family = AF_INET;
+-      i = 0;
+-      while (*ps != ':' ) i = i * 10 + (*ps++ - '0');
+-      i /= 6;
+-      ps++;
+-      while (i-- > 0) {
+-              // if peer is not us
+-              if(memcmp(&Self.m_sin.sin_addr,ps,sizeof(struct in_addr))) {
+-                      memcpy(&addr.sin_addr,ps,sizeof(struct in_addr));
+-                      memcpy(&addr.sin_port,ps+sizeof(struct in_addr),sizeof(unsigned short));
+-                      cnt++;
+-                      IPQUEUE.Add(&addr);
+-              }
+-              ps += 6;
+-      }
++    addr.sin_family = AF_INET;
++    i = 0;
++    while (*ps != ':' ) i = i * 10 + (*ps++ - '0');
++    i /= 6;
++    ps++;
++    while (i-- > 0) {
++      // if peer is not us
++      if(memcmp(&Self.m_sin.sin_addr,ps,sizeof(struct in_addr))) {
++        memcpy(&addr.sin_addr,ps,sizeof(struct in_addr));
++        memcpy(&addr.sin_port,ps+sizeof(struct in_addr),sizeof(unsigned short));
++        cnt++;
++        IPQUEUE.Add(&addr);
++      }
++    ps += 6;
++    }
+   }
+   else
+   for( ;bufsiz && *buf!='e'; buf += pos, bufsiz -= pos ){
+     pos = decode_dict(buf,bufsiz,(char*) 0);
+     if(!pos) break;
+-    if(!decode_query(buf,pos,"ip",&ps,&i,QUERY_STR) || MAXHOSTNAMELEN < i) continue;
++    if(!decode_query(buf,pos,"ip",&ps,&i,(int64_t*) 0,QUERY_STR) || MAXHOSTNAMELEN < i) continue;
+     memcpy(tmphost,ps,i); tmphost[i] = '\0';
+-    if(!decode_query(buf,pos,"port",(const char**) 0,&tmpport,QUERY_INT)) continue;
++    if(!decode_query(buf,pos,"port",(const char**) 0,&tmpport,(int64_t*) 0,QUERY_INT)) continue;
+-    if(!decode_query(buf,pos,"peer id",&ps,&i,QUERY_STR) && i != 20 ) continue;
++    if(!decode_query(buf,pos,"peer id",&ps,&i,(int64_t*) 0,QUERY_STR) && i != 20 ) continue;
+     if(_IPsin(tmphost,tmpport,&addr) < 0){
+       fprintf(stderr,"warn, detected invalid ip address %s.\n",tmphost);
+@@ -161,14 +211,17 @@
+     }
+   }
+   
+-  if( !cnt ) fprintf(stderr,"warn, peers list received from tracker is empty.\n");
++  if(arg_verbose)
++    fprintf(stderr, "\nnew peers=%u; next check in %u sec\n", cnt, m_interval);
++// moved to CheckResponse--this function isn't called if no peer data.
++//  if( !cnt ) fprintf(stderr,"warn, peers list received from tracker is empty.\n");
+   return 0;
+ }
+ int btTracker::CheckReponse()
+ {
+ #define MAX_LINE_SIZ 32
+-  char *pdata;
++  char *pdata, *format;
+   ssize_t r;
+   size_t q, hlen, dlen;
+@@ -186,6 +239,12 @@
+     if(getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n) < 0 ||
+        error != 0 ){
+       fprintf(stderr,"warn, received nothing from tracker! %s\n",strerror(error));
++      if(arg_ctcs){
++        char ctcsinfo[256];
++        snprintf(ctcsinfo,256,
++          "warn, received nothing from tracker! %s",strerror(error));
++        CTCS.Send_Info(ctcsinfo);
++      }
+     }
+     return -1;
+   }
+@@ -194,6 +253,8 @@
+   if( !hlen ){
+     fprintf(stderr,"warn, tracker reponse invalid. No html header found.\n");
++    if(arg_ctcs)
++      CTCS.Send_Info("warn, tracker reponse invalid. No html header found.");
+     return -1;
+   }
+@@ -202,21 +263,32 @@
+     if( r == 301 || r == 302 ){
+       char redirect[MAXPATHLEN],ih_buf[20 * 3 + 1],pi_buf[20 * 3 + 1],tmppath[MAXPATHLEN];
+       if( Http_get_header(m_reponse_buffer.BasePointer(), hlen, "Location", redirect) < 0 )
+-      return -1;
++        return -1;
+       if( Http_url_analyse(redirect,m_host,&m_port,m_path) < 0){
+-      fprintf(stderr,"warn, tracker redirect to an invalid url %s!\n", redirect);
+-      return -1;
++        fprintf(stderr,"warn, tracker redirect to an invalid url %s!\n", redirect);
++        if(arg_ctcs){
++          char ctcsinfo[256];
++          snprintf(ctcsinfo,256,
++            "warn, tracker redirect to an invalid url %s!", redirect);
++          CTCS.Send_Info(ctcsinfo);
++        }
++        return -1;
+       }
+       strcpy(tmppath,m_path);
++
++      if(strchr(m_path, '?'))
++        format=REQ_URL_P1A_FMT;
++      else format=REQ_URL_P1_FMT;
+       
+-      if(MAXPATHLEN < snprintf(m_path,MAXPATHLEN,REQ_URL_P1_FMT,
+-                             tmppath,
+-                             Http_url_encode(ih_buf, (char*)BTCONTENT.GetInfoHash(), 20),
+-                             Http_url_encode(pi_buf, (char*)BTCONTENT.GetPeerId(), 20),
+-                             cfg_listen_port)){
+-      return -1;
++      if(MAXPATHLEN < snprintf(m_path,MAXPATHLEN,format,
++                               tmppath,
++                               Http_url_encode(ih_buf, (char*)BTCONTENT.GetInfoHash(), 20),
++                               Http_url_encode(pi_buf, (char*)BTCONTENT.GetPeerId(), 20),
++                               cfg_listen_port,
++                               m_key)){
++        return -1;
+       }
+       return Connect();
+@@ -230,10 +302,14 @@
+       return 0;
+   }
+-  if ( !pdata ) return 0;
++  if ( !pdata ){
++    fprintf(stderr,"warn, peers list received from tracker is empty.\n");
++    return 0;
++  }
+   if( !m_f_started ) m_f_started = 1;
+   m_connect_refuse_click = 0;
++  m_ok_click++;
+   return _UpdatePeerList(pdata,dlen);
+ }
+@@ -241,6 +317,7 @@
+ int btTracker::Initial()
+ {
+   char ih_buf[20 * 3 + 1],pi_buf[20 * 3 + 1],tmppath[MAXPATHLEN];
++  char *format;
+   if(Http_url_analyse(BTCONTENT.GetAnnounce(),m_host,&m_port,m_path) < 0){
+     fprintf(stderr,"error, invalid tracker url format!\n");
+@@ -249,40 +326,50 @@
+   strcpy(tmppath,m_path);
+-  if(MAXPATHLEN < snprintf((char*)m_path,MAXPATHLEN,REQ_URL_P1_FMT,
+-                         tmppath,
+-                         Http_url_encode(ih_buf,(char*)BTCONTENT.GetInfoHash(),20),
+-                         Http_url_encode(pi_buf,(char*)BTCONTENT.GetPeerId(),20),
+-                         cfg_listen_port)){
++  if(strchr(m_path, '?'))
++    format=REQ_URL_P1A_FMT;
++  else format=REQ_URL_P1_FMT;
++
++  char chars[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
++  for(int i=0; i<8; i++)
++    m_key[i] = chars[random()%36];
++  m_key[8] = 0;
++
++  if(MAXPATHLEN < snprintf((char*)m_path,MAXPATHLEN,format,
++                           tmppath,
++                           Http_url_encode(ih_buf,(char*)BTCONTENT.GetInfoHash(),20),
++                           Http_url_encode(pi_buf,(char*)BTCONTENT.GetPeerId(),20),
++                           cfg_listen_port,
++                           m_key)){
+     return -1;
+   }
+-      
++        
+   /* get local ip address */
+   // 1st: if behind firewall, this only gets local side
+   {
+   struct sockaddr_in addr;
+   socklen_t addrlen = sizeof(struct sockaddr_in);
+   if(getsockname(m_sock,(struct sockaddr*)&addr,&addrlen) == 0)
+-      Self.SetIp(addr);
++        Self.SetIp(addr);
+   }
+   // 2nd: better to use addr of our domain
+   {
+-        struct hostent *h;
+-        char hostname[128];
+-        char *hostdots[2]={0,0}, *hdptr=hostname;
+-
+-        if (gethostname(hostname, 128) == -1) return -1;
+-//      printf("%s\n", hostname);
+-        while(*hdptr) if(*hdptr++ == '.') {
+-                hostdots[0] = hostdots[1];
+-                hostdots[1] = hdptr;
+-        }
+-        if (hostdots[0] == 0) return -1;
+-//      printf("%s\n", hostdots[0]);
+-        if ((h = gethostbyname(hostdots[0])) == NULL) return -1;
+-        //printf("Host domain  : %s\n", h->h_name);
+-        //printf("IP Address : %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));
+-        memcpy(&Self.m_sin.sin_addr,h->h_addr,sizeof(struct in_addr));
++          struct hostent *h;
++          char hostname[128];
++          char *hostdots[2]={0,0}, *hdptr=hostname;
++
++          if (gethostname(hostname, 128) == -1) return -1;
++//        printf("%s\n", hostname);
++          while(*hdptr) if(*hdptr++ == '.') {
++            hostdots[0] = hostdots[1];
++            hostdots[1] = hdptr;
++          }
++          if (hostdots[0] == 0) return -1;
++//        printf("%s\n", hostdots[0]);
++          if ((h = gethostbyname(hostdots[0])) == NULL) return -1;
++          //printf("Host domain  : %s\n", h->h_name);
++          //printf("IP Address : %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));
++          memcpy(&Self.m_sin.sin_addr,h->h_addr,sizeof(struct in_addr));
+   }
+   return 0;
+ }
+@@ -294,12 +381,33 @@
+   if(_s2sin(m_host,m_port,&m_sin) < 0) {
+     fprintf(stderr,"warn, get tracker's ip address failed.");
++    if(arg_ctcs) CTCS.Send_Info("warn, get tracker's ip address failed.");
+     return -1;
+   }
+   m_sock = socket(AF_INET,SOCK_STREAM,0);
+   if(INVALID_SOCKET == m_sock) return -1;
++  // we only need to bind if we have specified an ip
++  // we need it to bind here before the connect!!!!
++  if ( cfg_listen_ip != 0 ) {
++    struct sockaddr_in addr;
++    // clear the struct as requested in the manpages
++    memset(&addr,0, sizeof(sockaddr_in));
++    // set the type
++    addr.sin_family = AF_INET;
++    // we want the system to choose port
++    addr.sin_port = 0;
++    // set the defined ip from the commandline
++    addr.sin_addr.s_addr = cfg_listen_ip;
++    // bind it or return...
++    if(bind(m_sock,(struct sockaddr*)&addr,sizeof(struct sockaddr_in)) != 0){
++      fprintf(stderr, "warn, can't set up tracker connection: %s\n",
++        strerror(errno));
++      return -1;
++    }
++  }
++
+   if(setfd_nonblock(m_sock) < 0) {CLOSE_SOCKET(m_sock); return -1; }
+   r = connect_nonb(m_sock,(struct sockaddr*)&m_sin);
+@@ -329,34 +437,42 @@
+ //  fprintf(stdout,"Old Set Self:");
+ //  fprintf(stdout,"%s\n", inet_ntoa(Self.m_sin.sin_addr));
+-  if( m_f_stoped )    /* stopped */
+-    event = str_event[1];
+-  else if( BTCONTENT.pBF->IsFull())   /* download complete */
+-    event = str_event[2];
+-  else if( m_f_started )      /* interval */
+-    event = (char*) 0;
+-  else
++  if( m_f_stoped )
++    event = str_event[1];     /* stopped */
++  else if( m_f_started == 0 ) {
++    if( BTCONTENT.pBF->IsFull() ) m_f_completed = 1;
+     event = str_event[0];     /* started */
++  } else if( BTCONTENT.pBF->IsFull() && !m_f_completed){
++    event = str_event[2];     /* download complete */
++    m_f_completed = 1;                /* only send download complete once */
++  } else
++    event = (char*) 0;  /* interval */
+   if(event){
+     if(MAXPATHLEN < snprintf(REQ_BUFFER,MAXPATHLEN,REQ_URL_P2_FMT,
+-                           m_path,
+-                           (size_t)Self.TotalUL(),
+-                           (size_t)Self.TotalDL(),
+-                           (size_t)BTCONTENT.GetLeftBytes(),
+-                           event)){
++                             m_path,
++                             Self.TotalUL(),
++                             Self.TotalDL(),
++                             BTCONTENT.GetLeftBytes(),
++                             event,
++                             cfg_max_peers,
++                             m_key)){
+       return -1;
+     }
+   }else{
+     if(MAXPATHLEN < snprintf(REQ_BUFFER,MAXPATHLEN,REQ_URL_P3_FMT,
+-                           m_path,
+-                           (size_t)Self.TotalUL(),
+-                           (size_t)Self.TotalDL(),
+-                           (size_t)BTCONTENT.GetLeftBytes()
+-                           )){
++                             m_path,
++                             Self.TotalUL(),
++                             Self.TotalDL(),
++                             BTCONTENT.GetLeftBytes(),
++                             cfg_max_peers,
++                             m_key)){
+       return -1;
+     }
+   }
++  if( *m_trackerid &&
++      MAXPATHLEN - strlen(m_path) > 11 + strlen(m_trackerid) )
++    strcat(strcat(m_path, "&trackerid="), m_trackerid);
+   if(_IPsin(m_host, m_port, &addr) < 0){
+     char REQ_HOST[MAXHOSTNAMELEN];
+@@ -370,6 +486,12 @@
+   if( 0 != m_reponse_buffer.PutFlush(m_sock,REQ_BUFFER,strlen((char*)REQ_BUFFER))){
+     fprintf(stderr,"warn, send request to tracker failed. %s\n",strerror(errno));
++    if(arg_ctcs){
++      char ctcsinfo[256];
++      snprintf(ctcsinfo,256,
++        "warn, send request to tracker failed. %s",strerror(errno));
++      CTCS.Send_Info(ctcsinfo);
++    }
+     return -1;
+   }
+@@ -380,23 +502,29 @@
+ {
+   /* tracker communication */
+   if( T_FREE == m_status ){
+-    if((*pnow - m_last_timestamp >= m_interval) &&
+-       (cfg_min_peers > WORLD.TotalPeers())){
++    if( *pnow - m_last_timestamp >= m_interval ||
++        // Connect to tracker early if we run low on peers.
++        (WORLD.TotalPeers() < cfg_min_peers && m_prevpeers >= cfg_min_peers &&
++          *pnow - m_last_timestamp >= 15) ||
++        (m_f_pause && !WORLD.TotalPeers()) ){
++      m_prevpeers = WORLD.TotalPeers();
+    
+       if(Connect() < 0){ Reset(15); return -1; }
+     
+       if( m_status == T_CONNECTING ){
+-      FD_SET(m_sock, rfdp);
+-      FD_SET(m_sock, wfdp);
++        FD_SET(m_sock, rfdp);
++        FD_SET(m_sock, wfdp);
+       }else{
+-      FD_SET(m_sock, rfdp);
++        FD_SET(m_sock, rfdp);
+       }
++
++      if( m_f_pause && !WORLD.TotalPeers() ) m_f_stoped = 1;
+     }
+   }else{
+     if( m_status == T_CONNECTING ){
+       FD_SET(m_sock, rfdp);
+       FD_SET(m_sock, wfdp);
+-    }else{
++    }else if (INVALID_SOCKET != m_sock){
+       FD_SET(m_sock, rfdp);
+     }
+   }
+@@ -407,28 +535,60 @@
+ {
+   if( T_FREE == m_status ) return 0;
+-  if( T_CONNECTING == m_status && 
+-      (FD_ISSET(m_sock, wfdp) || FD_ISSET(m_sock,wfdp)) ){
++  if( T_CONNECTING == m_status && FD_ISSET(m_sock,wfdp) ){
+     int error = 0;
+     socklen_t n = sizeof(error);
+     (*nfds)--;
+     FD_CLR(m_sock, wfdp); 
+     if(getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n) < 0 ||
+        error != 0 ){
+-      if( ECONNREFUSED != error )
+-      fprintf(stderr,"warn, connect to tracker failed. %s\n",strerror(error));
+-      else
+-      m_connect_refuse_click++;
++      if( ECONNREFUSED != error ){
++        fprintf(stderr,"warn, connect to tracker failed. %s\n",strerror(error));
++        if(arg_ctcs){
++          char ctcsinfo[256];
++          snprintf(ctcsinfo,256,
++            "warn, connect to tracker failed. %s\n",strerror(error));
++          CTCS.Send_Info(ctcsinfo);
++        }
++      }else
++        m_connect_refuse_click++;
+       Reset(15);
+       return -1;
+     }else{
+       if( SendRequest() == 0 ) m_status = T_READY; 
+       else { Reset(15); return -1; }
+     }
+-  }else if(FD_ISSET(m_sock, rfdp) ){
++  }else if( T_CONNECTING == m_status && FD_ISSET(m_sock,rfdp) ){
++    int error = 0;
++    socklen_t n = sizeof(error);
++    (*nfds)--;
++    FD_CLR(m_sock, rfdp); 
++    getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n);
++    fprintf(stderr,"warn, connect to tracker failed. %s\n",strerror(error));
++    if(arg_ctcs){
++      char ctcsinfo[256];
++      snprintf(ctcsinfo,256,
++        "warn, connect to tracker failed. %s\n",strerror(error));
++      CTCS.Send_Info(ctcsinfo);
++    }
++    Reset(15);
++    return -1;
++  }else if(INVALID_SOCKET != m_sock && FD_ISSET(m_sock, rfdp) ){
+     (*nfds)--;
+     FD_CLR(m_sock,rfdp);
+     CheckReponse();
+   }
+   return 0;
+ }
++
++void btTracker::Resume()
++{
++  m_f_pause = m_f_stoped = 0;
++
++  if( T_FINISHED == m_status ){
++    m_status = T_FREE;
++    m_f_started = 0;
++    m_interval = 15;
++  }
++}
++
+--- tracker.h.orig     Wed Sep  8 16:10:51 2004
++++ tracker.h  Sat Dec 17 09:38:03 2005
+@@ -1,9 +1,9 @@
+ #ifndef TRACKER_H
+ #define TRACKER_H
++#include "./def.h"
+ #include <sys/types.h>
+-#include "./def.h"
+ #include "./bufio.h"
+ #ifdef WINDOWS
+@@ -18,9 +18,12 @@
+ #include <sys/param.h>
+ #endif
++#include "btconfig.h"
++
+ #define T_FREE                0
+ #define T_CONNECTING  1
+ #define T_READY               2
++#define T_FINISHED    3
+ class btTracker
+ {
+@@ -28,21 +31,29 @@
+   char m_host[MAXHOSTNAMELEN];
+   char m_path[MAXPATHLEN];
+   int m_port;
++  char m_key[9];
++  char m_trackerid[PEER_ID_LEN+1];
+   struct sockaddr_in m_sin;
+   unsigned char m_status:2;
+   unsigned char m_f_started:1;
+   unsigned char m_f_stoped:1;
++  unsigned char m_f_completed:1;
+   unsigned char m_f_pause:1;
+-  unsigned char m_f_reserved:3;
++  unsigned char m_f_softquit:1;
++  unsigned char m_f_restart:1;
+   time_t m_interval;          // ÓëTrackerͨÐŵÄʱ¼ä¼ä¸ô
+   time_t m_last_timestamp;    // ×îºóÒ»´Î³É¹¦ÓëTrackerͨÐŵÄʱ¼ä
+   size_t m_connect_refuse_click;
++  size_t m_ok_click;  // tracker ok response counter
++  size_t m_peers_count;       // total number of peers
++  size_t m_prevpeers; // number of peers previously seen
++
+   SOCKET m_sock;
+   BufIo m_reponse_buffer;
+   
+@@ -65,6 +76,14 @@
+   void SetPause() { m_f_pause = 1; }
+   void ClearPause() { m_f_pause = 0; }
++  int IsPaused() const { return m_f_pause; }
++  void Resume();
++  void SoftQuit() { m_f_softquit = 1; }
++  void DontQuit() { m_f_softquit = 0; }
++  int IsQuitting() const { return m_f_softquit; }
++  void SetRestart() { m_f_restart = 1; }
++
++  void SetStoped() { Reset(15); m_f_stoped = 1; m_last_timestamp -= 15;}
+   int Connect();
+   int SendRequest();
+@@ -73,6 +92,8 @@
+   int SocketReady(fd_set *rfdp, fd_set *wfdp, int *nfds);
+   size_t GetRefuseClick() const { return m_connect_refuse_click; }
++  size_t GetOkClick() const { return m_ok_click; }
++  size_t GetPeersCount() const { return m_peers_count; }
+ };
+ extern btTracker Tracker;
This page took 0.786711 seconds and 4 git commands to generate.