Ignore:
Timestamp:
Nov 24, 2009, 2:16:31 AM (12 years ago)
Author:
charles
Message:

(trunk) #2096: Magnet, BEP #9 support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/torrent.c

    r9549 r9550  
    3333#include "resume.h"
    3434#include "fdlimit.h" /* tr_fdTorrentClose */
     35#include "magnet.h"
    3536#include "metainfo.h"
    3637#include "peer-mgr.h"
     
    4445#include "verify.h"
    4546
    46 #define MAX_BLOCK_SIZE ( 1024 * 16 )
     47enum
     48{
     49    MAX_BLOCK_SIZE = 1024 * 16
     50};
    4751
    4852/***
     
    551555}
    552556
    553 static void refreshCurrentDir( tr_torrent * tor );;
     557static void refreshCurrentDir( tr_torrent * tor );
    554558
    555559static void
    556 torrentRealInit( tr_torrent * tor, const tr_ctor * ctor )
    557 {
    558     int          doStart;
    559     uint64_t     loaded;
    560     uint64_t     t;
    561     const char * dir;
    562     static int   nextUniqueId = 1;
    563     tr_info    * info = &tor->info;
    564     tr_session * session = tr_ctorGetSession( ctor );
    565 
    566     assert( session != NULL );
    567 
    568     tr_globalLock( session );
    569 
    570     tor->session   = session;
    571     tor->uniqueId = nextUniqueId++;
    572     tor->magicNumber = TORRENT_MAGIC_NUMBER;
    573 
    574     randomizeTiers( info );
    575 
    576     tor->bandwidth = tr_bandwidthNew( session, session->bandwidth );
     560torrentInitFromInfo( tr_torrent * tor )
     561{
     562    uint64_t t;
     563    tr_info * info = &tor->info;
    577564
    578565    tor->blockSize = getBlockSize( info->pieceSize );
    579566
    580     if( !tr_ctorGetDownloadDir( ctor, TR_FORCE, &dir ) ||
    581         !tr_ctorGetDownloadDir( ctor, TR_FALLBACK, &dir ) )
    582             tor->downloadDir = tr_strdup( dir );
    583 
    584     if( tr_ctorGetIncompleteDir( ctor, &dir ) )
    585         dir = tr_sessionGetIncompleteDir( session );
    586     if( tr_sessionIsIncompleteDirEnabled( session ) )
    587         tor->incompleteDir = tr_strdup( dir );
    588 
    589     tor->lastPieceSize = info->totalSize % info->pieceSize;
     567    if( info->pieceSize )
     568        tor->lastPieceSize = info->totalSize % info->pieceSize;
    590569
    591570    if( !tor->lastPieceSize )
    592571        tor->lastPieceSize = info->pieceSize;
    593572
    594     tor->lastBlockSize = info->totalSize % tor->blockSize;
     573    if( tor->blockSize )
     574        tor->lastBlockSize = info->totalSize % tor->blockSize;
    595575
    596576    if( !tor->lastBlockSize )
    597577        tor->lastBlockSize = tor->blockSize;
    598578
    599     tor->blockCount =
    600         ( info->totalSize + tor->blockSize - 1 ) / tor->blockSize;
    601 
    602     tor->blockCountInPiece =
    603         info->pieceSize / tor->blockSize;
    604 
    605     tor->blockCountInLastPiece =
    606         ( tor->lastPieceSize + tor->blockSize - 1 ) / tor->blockSize;
     579    tor->blockCount = tor->blockSize
     580        ? ( info->totalSize + tor->blockSize - 1 ) / tor->blockSize
     581        : 0;
     582
     583    tor->blockCountInPiece = tor->blockSize
     584        ? info->pieceSize / tor->blockSize
     585        : 0;
     586
     587    tor->blockCountInLastPiece = tor->blockSize
     588        ? ( tor->lastPieceSize + tor->blockSize - 1 ) / tor->blockSize
     589        : 0;
    607590
    608591    /* check our work */
    609     assert( ( info->pieceSize % tor->blockSize ) == 0 );
     592    if( tor->blockSize != 0 )
     593        assert( ( info->pieceSize % tor->blockSize ) == 0 );
    610594    t = info->pieceCount - 1;
    611595    t *= info->pieceSize;
     
    625609    tr_torrentInitFilePieces( tor );
    626610
     611    tr_bitfieldConstruct( &tor->checkedPieces, tor->info.pieceCount );
     612
     613    tor->completeness = tr_cpGetStatus( &tor->completion );
     614}
     615
     616void
     617tr_torrentGotNewInfoDict( tr_torrent * tor )
     618{
     619    torrentInitFromInfo( tor );
     620}
     621
     622static void
     623torrentInit( tr_torrent * tor, const tr_ctor * ctor )
     624{
     625    int doStart;
     626    uint64_t loaded;
     627    const char * dir;
     628    static int nextUniqueId = 1;
     629    tr_session * session = tr_ctorGetSession( ctor );
     630
     631    assert( session != NULL );
     632
     633    tr_globalLock( session );
     634
     635    tor->session   = session;
     636    tor->uniqueId = nextUniqueId++;
     637    tor->magicNumber = TORRENT_MAGIC_NUMBER;
     638
     639    randomizeTiers( &tor->info );
     640
    627641    tr_sha1( tor->obfuscatedHash, "req2", 4,
    628              info->hash, SHA_DIGEST_LENGTH,
     642             tor->info.hash, SHA_DIGEST_LENGTH,
    629643             NULL );
     644
     645    if( !tr_ctorGetDownloadDir( ctor, TR_FORCE, &dir ) ||
     646        !tr_ctorGetDownloadDir( ctor, TR_FALLBACK, &dir ) )
     647            tor->downloadDir = tr_strdup( dir );
     648
     649    if( tr_ctorGetIncompleteDir( ctor, &dir ) )
     650        dir = tr_sessionGetIncompleteDir( session );
     651    if( tr_sessionIsIncompleteDirEnabled( session ) )
     652        tor->incompleteDir = tr_strdup( dir );
     653
     654    tor->bandwidth = tr_bandwidthNew( session, session->bandwidth );
     655
     656    tor->error = TR_STAT_OK;
    630657
    631658    tr_peerMgrAddTorrent( session->peerMgr, tor );
     
    638665    tr_ctorInitTorrentWanted( ctor, tor );
    639666
    640     tor->error = TR_STAT_OK;
    641 
    642     tr_bitfieldConstruct( &tor->checkedPieces, tor->info.pieceCount );
    643667    tr_torrentUncheck( tor );
    644668
     
    668692    }
    669693
    670     tor->completeness = tr_cpGetStatus( &tor->completion );
    671 
    672694    {
    673695        tr_torrent * it = NULL;
     
    683705    }
    684706
    685     tr_globalUnlock( session );
     707    torrentInitFromInfo( tor );
    686708
    687709    /* maybe save our own copy of the metainfo */
     
    691713        if( !tr_ctorGetMetainfo( ctor, &val ) )
    692714        {
    693             const char * filename = tor->info.torrent;
    694             tr_bencToFile( val, TR_FMT_BENC, filename );
    695             tr_sessionSetTorrentFile( tor->session, tor->info.hashString, filename );
     715            const char * path = tor->info.torrent;
     716            tr_bencToFile( val, TR_FMT_BENC, path );
     717            tr_sessionSetTorrentFile( tor->session, tor->info.hashString, path );
    696718        }
    697719    }
    698720
    699     tor->tiers = tr_announcerAddTorrent( session->announcer, tor );
     721    tor->tiers = tr_announcerAddTorrent( tor->session->announcer, tor );
    700722    tor->tiersSubscription = tr_announcerSubscribe( tor->tiers, onTrackerResponse, tor );
    701 
    702     tr_metainfoMigrate( session, &tor->info );
    703723
    704724    if( doStart )
    705725        torrentStart( tor );
     726
     727    tr_globalUnlock( session );
    706728}
    707729
     
    723745        return TR_PARSE_ERR;
    724746
    725     didParse = tr_metainfoParse( session, setmeInfo, metainfo );
     747    didParse = tr_metainfoParse( session, setmeInfo, NULL, NULL, metainfo );
    726748    doFree = didParse && ( setmeInfo == &tmp );
    727749
     
    745767               int            * setmeError )
    746768{
    747     int          err;
    748     tr_info      tmpInfo;
     769    int err;
     770    tr_info tmpInfo;
    749771    tr_torrent * tor = NULL;
     772    const tr_magnet_info * magnetInfo;
    750773
    751774    assert( ctor != NULL );
    752775    assert( tr_isSession( tr_ctorGetSession( ctor ) ) );
    753776
    754     err = tr_torrentParse( ctor, &tmpInfo );
    755     if( !err )
     777    if( !tr_ctorGetMagnet( ctor, &magnetInfo ) )
    756778    {
    757779        tor = tr_new0( tr_torrent, 1 );
    758         tor->info = tmpInfo;
    759         torrentRealInit( tor, ctor );
    760     }
    761     else if( setmeError )
    762     {
    763         *setmeError = err;
     780        tr_metainfoSetFromMagnet( &tor->info, magnetInfo );
     781        torrentInit( tor, ctor );
     782    }
     783    else
     784    {
     785        err = tr_torrentParse( ctor, &tmpInfo );
     786        if( !err )
     787        {
     788            tor = tr_new0( tr_torrent, 1 );
     789            tor->info = tmpInfo;
     790            torrentInit( tor, ctor );
     791        }
     792        else if( setmeError )
     793        {
     794            *setmeError = err;
     795        }
    764796    }
    765797
     
    9891021                tor->etaDLSpeedCalculatedAt = now;
    9901022            }
    991            
     1023
    9921024            if( s->leftUntilDone > s->desiredAvailable )
    9931025                s->eta = TR_ETA_NOT_AVAIL;
     
    10071039                    tor->etaULSpeedCalculatedAt = now;
    10081040                }
    1009                
     1041
    10101042                if( s->pieceUploadSpeed < 0.1 )
    10111043                    s->eta = TR_ETA_UNKNOWN;
     
    10211053            break;
    10221054    }
    1023    
    1024     if( !checkSeedRatio || s->ratio >= seedRatio || s->ratio == TR_RATIO_INF ) 
    1025         s->percentRatio = 1.0; 
    1026     else if( s->ratio == TR_RATIO_NA ) 
    1027         s->percentRatio = 0.0; 
    1028     else 
    1029         s->percentRatio = s->ratio / seedRatio; 
     1055
     1056    if( !checkSeedRatio || s->ratio >= seedRatio || s->ratio == TR_RATIO_INF )
     1057        s->percentRatio = 1.0;
     1058    else if( s->ratio == TR_RATIO_NA )
     1059        s->percentRatio = 0.0;
     1060    else
     1061        s->percentRatio = s->ratio / seedRatio;
    10301062
    10311063    tr_torrentUnlock( tor );
     
    20972129        /* try to parse it back again, to make sure it's good */
    20982130        memset( &tmpInfo, 0, sizeof( tr_info ) );
    2099         if( tr_metainfoParse( tor->session, &tmpInfo, &metainfo ) )
     2131        if( tr_metainfoParse( tor->session, &tmpInfo,
     2132                              &tor->infoDictOffset,
     2133                              &tor->infoDictLength,
     2134                              &metainfo ) )
    21002135        {
    21012136            /* it's good, so keep these new trackers and free the old ones */
     
    23682403        tr_free( path );
    23692404
    2370        
    23712405        tmp = tr_torrentBuildPartial( tor, 0 );
    23722406        path = tr_buildPath( tor->currentDir, tmp, NULL );
     
    26572691}
    26582692
    2659 
    26602693char*
    26612694tr_torrentFindFile( const tr_torrent * tor, tr_file_index_t fileNum )
Note: See TracChangeset for help on using the changeset viewer.