Changeset 10084


Ignore:
Timestamp:
Feb 2, 2010, 10:45:22 PM (12 years ago)
Author:
charles
Message:

(trunk) #2802, #2716, #2717 -- remember magnet links and their settings between sessions, and allow their trackers to be modified

Location:
trunk
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/cli/cli.c

    r10048 r10084  
    382382        tr_ctorSetMetainfo( ctor, fileContents, fileLength );
    383383    } else if( !memcmp( torrentPath, "magnet:?", 8 ) ) {
    384         tr_ctorSetMagnet( ctor, torrentPath );
     384        tr_ctorSetMetainfoFromMagnetLink( ctor, torrentPath );
    385385    } else if( !memcmp( torrentPath, "http", 4 ) ) {
    386386        tr_webRun( h, torrentPath, NULL, onTorrentFileDownloaded, ctor );
  • trunk/gtk/tr-core.c

    r9890 r10084  
    10531053            url = tmp = g_strdup_printf( "magnet:?xt=urn:btih:%s", url );
    10541054
    1055         err = tr_ctorSetMagnet( ctor, url );
     1055        err = tr_ctorSetMetainfoFromMagnetLink( ctor, url );
    10561056
    10571057        if( !err )
  • trunk/libtransmission/bencode.c

    r10070 r10084  
    672672
    673673tr_benc *
    674 tr_bencListAddInt( tr_benc * list,
    675                    int64_t   val )
     674tr_bencListAddInt( tr_benc * list, int64_t val )
    676675{
    677676    tr_benc * node = tr_bencListAdd( list );
     
    682681
    683682tr_benc *
    684 tr_bencListAddStr( tr_benc *    list,
    685                    const char * val )
     683tr_bencListAddReal( tr_benc * list, double val )
    686684{
    687685    tr_benc * node = tr_bencListAdd( list );
    688 
     686    tr_bencInitReal( node, val );
     687    return node;
     688}
     689
     690tr_benc *
     691tr_bencListAddBool( tr_benc * list, tr_bool val )
     692{
     693    tr_benc * node = tr_bencListAdd( list );
     694    tr_bencInitBool( node, val );
     695    return node;
     696}
     697
     698tr_benc *
     699tr_bencListAddStr( tr_benc * list, const char * val )
     700{
     701    tr_benc * node = tr_bencListAdd( list );
    689702    tr_bencInitStr( node, val, -1 );
     703    return node;
     704}
     705
     706tr_benc *
     707tr_bencListAddRaw( tr_benc * list, const uint8_t * val, size_t len )
     708{
     709    tr_benc * node = tr_bencListAdd( list );
     710    tr_bencInitRaw( node, val, len );
    690711    return node;
    691712}
     
    804825
    805826tr_benc*
     827tr_bencDictAddRaw( tr_benc *    dict,
     828                   const char * key,
     829                   const void * src,
     830                   size_t       len )
     831{
     832    tr_benc * child;
     833
     834    /* see if it already exists, and if so, try to reuse it */
     835    if(( child = tr_bencDictFind( dict, key ))) {
     836        if( tr_bencIsString( child ) ) {
     837            if( stringIsAlloced( child ) )
     838                tr_free( child->val.s.str.ptr );
     839        } else {
     840            tr_bencDictRemove( dict, key );
     841            child = NULL;
     842        }
     843    }
     844
     845    /* if it doesn't exist, create it */
     846    if( child == NULL )
     847        child = tr_bencDictAdd( dict, key );
     848
     849    /* set it */
     850    tr_bencInitRaw( child, src, len );
     851
     852    return child;
     853}
     854
     855tr_benc*
    806856tr_bencDictAddList( tr_benc *    dict,
    807857                    const char * key,
     
    822872
    823873    tr_bencInitDict( child, reserveCount );
    824     return child;
    825 }
    826 
    827 tr_benc*
    828 tr_bencDictAddRaw( tr_benc *    dict,
    829                    const char * key,
    830                    const void * src,
    831                    size_t       len )
    832 {
    833     tr_benc * child = tr_bencDictAdd( dict, key );
    834 
    835     tr_bencInitRaw( child, src, len );
    836874    return child;
    837875}
     
    14041442****
    14051443***/
     1444
     1445static void
     1446tr_bencListCopy( tr_benc * target, const tr_benc * src )
     1447{
     1448    int i = 0;
     1449    const tr_benc * val;
     1450
     1451    while(( val = tr_bencListChild( (tr_benc*)src, i++ )))
     1452    {
     1453       if( tr_bencIsBool( val ) )
     1454       {
     1455           tr_bool boolVal = 0;
     1456           tr_bencGetBool( val, &boolVal );
     1457           tr_bencListAddBool( target, boolVal );
     1458       }
     1459       else if( tr_bencIsReal( val ) )
     1460       {
     1461           double realVal = 0;
     1462           tr_bencGetReal( val, &realVal );
     1463           tr_bencListAddReal( target, realVal );
     1464       }
     1465       else if( tr_bencIsInt( val ) )
     1466       {
     1467           int64_t intVal = 0;
     1468           tr_bencGetInt( val, &intVal );
     1469           tr_bencListAddInt( target, intVal );
     1470       }
     1471       else if( tr_bencIsString( val ) )
     1472       {
     1473           tr_bencListAddRaw( target, (const uint8_t*)getStr( val ), val->val.s.len );
     1474       }
     1475       else if( tr_bencIsDict( val ) )
     1476       {
     1477           tr_bencMergeDicts( tr_bencListAddDict( target, 0 ), val );
     1478       }
     1479       else if ( tr_bencIsList( val ) )
     1480       {
     1481           tr_bencListCopy( tr_bencListAddList( target, 0 ), val );
     1482       }
     1483       else
     1484       {
     1485           tr_err( "tr_bencListCopy skipping item" );
     1486       }
     1487   }
     1488}
    14061489
    14071490static size_t
     
    14711554            else if( tr_bencIsString( val ) )
    14721555            {
    1473                 const char * strVal = NULL;
    1474                 tr_bencGetStr( val, &strVal );
    1475                 tr_bencDictAddStr( target, key, strVal );
     1556                tr_bencDictAddRaw( target, key, getStr( val ), val->val.s.len );
    14761557            }
    14771558            else if( tr_bencIsDict( val ) && tr_bencDictFindDict( target, key, &t ) )
    14781559            {
    14791560                tr_bencMergeDicts( t, val );
     1561            }
     1562            else if( tr_bencIsList( val ) )
     1563            {
     1564                if( tr_bencDictFind( target, key ) == NULL )
     1565                {
     1566                    tr_bencListCopy( tr_bencDictAddList( target, key, tr_bencListSize( val ) ), val );
     1567                }
    14801568            }
    14811569            else
  • trunk/libtransmission/bencode.h

    r9965 r10084  
    139139tr_benc * tr_bencListAdd( tr_benc * );
    140140
     141tr_benc * tr_bencListAddBool( tr_benc *, tr_bool val );
     142
    141143tr_benc * tr_bencListAddInt( tr_benc *, int64_t val );
    142144
     145tr_benc * tr_bencListAddReal( tr_benc *, double val );
     146
    143147tr_benc * tr_bencListAddStr( tr_benc *, const char * val );
     148
     149tr_benc * tr_bencListAddRaw( tr_benc *, const uint8_t * val, size_t len );
    144150
    145151tr_benc * tr_bencListAddList( tr_benc *, size_t reserveCount );
  • trunk/libtransmission/magnet.c

    r9979 r10084  
    1515
    1616#include "transmission.h"
     17#include "bencode.h"
    1718#include "magnet.h"
    1819#include "utils.h"
     
    194195    }
    195196}
     197
     198void
     199tr_magnetCreateMetainfo( const tr_magnet_info * info, tr_benc * top )
     200{
     201    int i;
     202    tr_benc * d;
     203    tr_bencInitDict( top, 4 );
     204
     205    /* announce list */
     206    if( info->trackerCount == 1 )
     207        tr_bencDictAddStr( top, "announce", info->trackers[0] );
     208    else {
     209        tr_benc * trackers = tr_bencDictAddList( top, "announce-list", info->trackerCount );
     210        for( i=0; i<info->trackerCount; ++i )
     211            tr_bencListAddStr( tr_bencListAddList( trackers, 1 ), info->trackers[i] );
     212    }
     213
     214    /* webseeds */
     215    if( info->webseedCount > 0 ) {
     216        tr_benc * urls = tr_bencDictAddList( top, "url-list", info->webseedCount );
     217        for( i=0; i<info->webseedCount; ++i )
     218            tr_bencListAddStr( urls, info->webseeds[i] );
     219    }
     220
     221    /* nonstandard keys */
     222    d = tr_bencDictAddDict( top, "magnet-info", 2 );
     223    tr_bencDictAddRaw( d, "info_hash", info->hash, 20 );
     224    if( info->displayName != NULL )
     225        tr_bencDictAddStr( d, "display-name", info->displayName );
     226}
     227
     228
  • trunk/libtransmission/magnet.h

    r9931 r10084  
    3636tr_magnet_info * tr_magnetParse( const char * uri );
    3737
     38struct tr_benc;
     39
     40void tr_magnetCreateMetainfo( const tr_magnet_info *, struct tr_benc * );
     41
    3842void tr_magnetFree( tr_magnet_info * info );
    3943
  • trunk/libtransmission/metainfo.c

    r9927 r10084  
    2727#include "bencode.h"
    2828#include "crypto.h" /* tr_sha1 */
    29 #include "magnet.h"
    3029#include "metainfo.h"
    3130#include "platform.h"
     
    385384
    386385static const char*
    387 tr_metainfoParseImpl( const tr_session * session,
    388                       tr_info          * inf,
    389                       int              * infoDictOffset,
    390                       int              * infoDictLength,
    391                       const tr_benc    * meta_in )
     386tr_metainfoParseImpl( const tr_session  * session,
     387                      tr_info           * inf,
     388                      tr_bool           * hasInfoDict,
     389                      int               * infoDictOffset,
     390                      int               * infoDictLength,
     391                      const tr_benc     * meta_in )
    392392{
    393393    int64_t         i;
     
    395395    const char *    str;
    396396    const uint8_t * raw;
    397     tr_benc *       beInfo;
     397    tr_benc *       d;
     398    tr_benc *       infoDict = NULL;
    398399    tr_benc *       meta = (tr_benc *) meta_in;
    399400    tr_bool         err;
     401    tr_bool         b;
     402    tr_bool         isMagnet = FALSE;
    400403
    401404    /* info_hash: urlencoded 20-byte SHA1 hash of the value of the info key
    402405     * from the Metainfo file. Note that the value will be a bencoded
    403406     * dictionary, given the definition of the info key above. */
    404     if( !tr_bencDictFindDict( meta, "info", &beInfo ) )
    405         return "info";
     407    b = tr_bencDictFindDict( meta, "info", &infoDict );
     408    if( hasInfoDict != NULL )
     409        *hasInfoDict = b;
     410    if( !b )
     411    {
     412        /* no info dictionary... is this a magnet link? */
     413        if( tr_bencDictFindDict( meta, "magnet-info", &d ) )
     414        {
     415            isMagnet = TRUE;
     416
     417            /* get the info-hash */
     418            if( !tr_bencDictFindRaw( d, "info_hash", &raw, &raw_len ) )
     419                return "info_hash";
     420            if( raw_len != SHA_DIGEST_LENGTH )
     421                return "info_hash";
     422            memcpy( inf->hash, raw, raw_len );
     423            tr_sha1_to_hex( inf->hashString, inf->hash );
     424            escape( inf->hashEscaped, inf->hash, SHA_DIGEST_LENGTH );
     425
     426            /* maybe get the display name */
     427            if( tr_bencDictFindStr( d, "display-name", &str ) ) {
     428                tr_free( inf->name );
     429                inf->name = tr_strdup( str );
     430            }
     431        }
     432        else /* not a magnet link and has no info dict... */
     433        {
     434            return "info";
     435        }
     436    }
    406437    else
    407438    {
    408439        int len;
    409         char * bstr = tr_bencToStr( beInfo, TR_FMT_BENC, &len );
     440        char * bstr = tr_bencToStr( infoDict, TR_FMT_BENC, &len );
    410441        tr_sha1( inf->hash, bstr, len, NULL );
    411442        tr_sha1_to_hex( inf->hashString, inf->hash );
     
    431462
    432463    /* name */
    433     if( !tr_bencDictFindStr( beInfo, "name.utf-8", &str ) )
    434         if( !tr_bencDictFindStr( beInfo, "name", &str ) )
    435             str = "";
    436     if( !str || !*str )
    437         return "name";
    438     tr_free( inf->name );
    439     inf->name = tr_utf8clean( str, -1, &err );
     464    if( !isMagnet ) {
     465        if( !tr_bencDictFindStr( infoDict, "name.utf-8", &str ) )
     466            if( !tr_bencDictFindStr( infoDict, "name", &str ) )
     467                str = "";
     468        if( !str || !*str )
     469            return "name";
     470        tr_free( inf->name );
     471        inf->name = tr_utf8clean( str, -1, &err );
     472    }
    440473
    441474    /* comment */
     
    459492
    460493    /* private */
    461     if( !tr_bencDictFindInt( beInfo, "private", &i ) )
     494    if( !tr_bencDictFindInt( infoDict, "private", &i ) )
    462495        if( !tr_bencDictFindInt( meta, "private", &i ) )
    463496            i = 0;
     
    465498
    466499    /* piece length */
    467     if( !tr_bencDictFindInt( beInfo, "piece length", &i ) || ( i < 1 ) )
    468         return "piece length";
    469     inf->pieceSize = i;
     500    if( !isMagnet ) {
     501        if( !tr_bencDictFindInt( infoDict, "piece length", &i ) || ( i < 1 ) )
     502            return "piece length";
     503        inf->pieceSize = i;
     504    }
    470505
    471506    /* pieces */
    472     if( !tr_bencDictFindRaw( beInfo, "pieces", &raw,
    473                              &raw_len ) || ( raw_len % SHA_DIGEST_LENGTH ) )
    474         return "pieces";
    475     inf->pieceCount = raw_len / SHA_DIGEST_LENGTH;
    476     inf->pieces = tr_new0( tr_piece, inf->pieceCount );
    477     for( i = 0; i < inf->pieceCount; ++i )
    478         memcpy( inf->pieces[i].hash, &raw[i * SHA_DIGEST_LENGTH],
    479                 SHA_DIGEST_LENGTH );
     507    if( !isMagnet ) {
     508        if( !tr_bencDictFindRaw( infoDict, "pieces", &raw, &raw_len ) )
     509            return "pieces";
     510        if( raw_len % SHA_DIGEST_LENGTH )
     511            return "pieces";
     512        inf->pieceCount = raw_len / SHA_DIGEST_LENGTH;
     513        inf->pieces = tr_new0( tr_piece, inf->pieceCount );
     514        for( i = 0; i < inf->pieceCount; ++i )
     515            memcpy( inf->pieces[i].hash, &raw[i * SHA_DIGEST_LENGTH],
     516                    SHA_DIGEST_LENGTH );
     517    }
    480518
    481519    /* files */
    482     if( ( str = parseFiles( inf, tr_bencDictFind( beInfo, "files" ),
    483                                  tr_bencDictFind( beInfo, "length" ) ) ) )
    484         return str;
    485     if( !inf->fileCount || !inf->totalSize )
    486         return "files";
    487     if( (uint64_t) inf->pieceCount !=
    488        ( inf->totalSize + inf->pieceSize - 1 ) / inf->pieceSize )
    489         return "files";
     520    if( !isMagnet ) {
     521        if( ( str = parseFiles( inf, tr_bencDictFind( infoDict, "files" ),
     522                                     tr_bencDictFind( infoDict, "length" ) ) ) )
     523            return str;
     524        if( !inf->fileCount || !inf->totalSize )
     525            return "files";
     526        if( (uint64_t) inf->pieceCount !=
     527           ( inf->totalSize + inf->pieceSize - 1 ) / inf->pieceSize )
     528            return "files";
     529    }
    490530
    491531    /* get announce or announce-list */
     
    505545tr_bool
    506546tr_metainfoParse( const tr_session * session,
     547                  const tr_benc    * meta_in,
    507548                  tr_info          * inf,
     549                  tr_bool          * hasInfoDict,
    508550                  int              * infoDictOffset,
    509                   int              * infoDictLength,
    510                   const tr_benc    * meta_in )
     551                  int              * infoDictLength )
    511552{
    512553    const char * badTag = tr_metainfoParseImpl( session,
    513554                                                inf,
     555                                                hasInfoDict,
    514556                                                infoDictOffset,
    515557                                                infoDictLength,
     
    570612    tr_free( filename );
    571613}
    572 
    573 /***
    574 ****
    575 ***/
    576 
    577 void
    578 tr_metainfoSetFromMagnet( tr_info * inf, const tr_magnet_info * m )
    579 {
    580     /* hash */
    581     memcpy( inf->hash, m->hash, 20 );
    582     tr_sha1_to_hex( inf->hashString, inf->hash );
    583     escape( inf->hashEscaped, inf->hash, SHA_DIGEST_LENGTH );
    584 
    585     /* name */
    586     if( m->displayName && *m->displayName )
    587         inf->name = tr_strdup( m->displayName );
    588     else
    589         inf->name = tr_strdup( inf->hashString );
    590 
    591     /* trackers */
    592     if(( inf->trackerCount = m->trackerCount ))
    593     {
    594         int i;
    595         const int n = m->trackerCount;
    596 
    597         inf->trackers = tr_new0( tr_tracker_info, n );
    598         for( i=0; i<n; ++i ) {
    599             const char * url = m->trackers[i];
    600             inf->trackers[i].tier = i;
    601             inf->trackers[i].announce = tr_strdup( url );
    602             inf->trackers[i].scrape = tr_convertAnnounceToScrape( url );
    603             inf->trackers[i].id = i;
    604         }
    605     }
    606 
    607     /* webseeds */
    608     if(( inf->webseedCount = m->webseedCount ))
    609     {
    610         int i;
    611         const int n = m->webseedCount;
    612 
    613         inf->webseeds = tr_new0( char*, n );
    614         for( i=0; i<n; ++i )
    615             inf->webseeds[i] = tr_strdup( m->webseeds[i] );
    616     }
    617 }
  • trunk/libtransmission/metainfo.h

    r9868 r10084  
    2121
    2222struct tr_benc;
    23 struct tr_magnet_info;
    2423
    2524tr_bool  tr_metainfoParse( const tr_session     * session,
     25                           const struct tr_benc * benc,
    2626                           tr_info              * setmeInfo,
     27                           tr_bool              * setmeHasInfoDict,
    2728                           int                  * setmeInfoDictOffset,
    28                            int                  * setmeInfoDictLength,
    29                            const struct tr_benc * benc );
     29                           int                  * setmeInfoDictLength );
    3030
    3131void tr_metainfoRemoveSaved( const tr_session * session,
     
    3535                         tr_info    * inf );
    3636
    37 void tr_metainfoSetFromMagnet( tr_info * inf, const struct tr_magnet_info * m );
    38 
    3937
    4038#endif
  • trunk/libtransmission/resume.c

    r9868 r10084  
    518518    tr_bencDictAddBool( &top, KEY_PAUSED, !tor->isRunning );
    519519    savePeers( &top, tor );
    520     saveFilePriorities( &top, tor );
    521     saveDND( &top, tor );
    522     saveProgress( &top, tor );
     520    if( tr_torrentHasMetadata( tor ) )
     521    {
     522        saveFilePriorities( &top, tor );
     523        saveDND( &top, tor );
     524        saveProgress( &top, tor );
     525    }
    523526    saveSpeedLimits( &top, tor );
    524527    saveRatioLimits( &top, tor );
  • trunk/libtransmission/rpcimpl.c

    r10083 r10084  
    11191119            else if( !strncmp( fname, "magnet:?", 8 ) )
    11201120            {
    1121                 tr_ctorSetMagnet( ctor, fname );
     1121                tr_ctorSetMetainfoFromMagnetLink( ctor, fname );
    11221122            }
    11231123            else
  • trunk/libtransmission/torrent-ctor.c

    r10081 r10084  
    4545    char *                  sourceFile;
    4646
    47     tr_magnet_info        * magnetInfo;
    48 
    4947    struct optional_args    optionalArgs[2];
    5048
     
    107105
    108106int
    109 tr_ctorSetMagnet( tr_ctor * ctor, const char * uri )
     107tr_ctorSetMetainfoFromMagnetLink( tr_ctor * ctor, const char * magnet_link )
    110108{
    111109    int err;
    112 
    113     if( ctor->magnetInfo != NULL )
    114         tr_magnetFree( ctor->magnetInfo );
    115 
    116     ctor->magnetInfo = tr_magnetParse( uri );
    117 
    118     err = ctor->magnetInfo == NULL;
     110    tr_magnet_info * magnet_info = tr_magnetParse( magnet_link );
     111
     112    if( magnet_info == NULL )
     113        err = -1;
     114    else {
     115        int len;
     116        tr_benc tmp;
     117        char * str;
     118
     119        tr_magnetCreateMetainfo( magnet_info, &tmp );
     120        str = tr_bencToStr( &tmp, TR_FMT_BENC, &len );
     121        err = tr_ctorSetMetainfo( ctor, (const uint8_t*)str, len );
     122
     123        tr_free( str );
     124        tr_magnetFree( magnet_info );
     125    }
     126
    119127    return err;
    120128}
     
    391399
    392400int
    393 tr_ctorGetMagnet( const tr_ctor * ctor, const tr_magnet_info ** setme )
    394 {
    395     int err = 0;
    396 
    397     if( ctor->magnetInfo == NULL )
    398         err = 1;
    399     else
    400         *setme = ctor->magnetInfo;
    401 
    402     return err;
    403 }
    404 
    405 int
    406401tr_ctorGetMetainfo( const tr_ctor *  ctor,
    407402                    const tr_benc ** setme )
  • trunk/libtransmission/torrent-magnet.c

    r9868 r10084  
    139139
    140140void
    141 tr_torrentSetMetadataPiece( tr_torrent  * tor,
    142                             int           piece,
    143                             const void  * data,
    144                             int           len )
     141tr_torrentSetMetadataPiece( tr_torrent  * tor, int piece, const void  * data, int len )
    145142{
    146143    int i;
     
    180177    {
    181178        tr_bool success = FALSE;
     179        tr_bool checksumPassed = FALSE;
     180        tr_bool metainfoParsed = FALSE;
    182181        uint8_t sha1[SHA_DIGEST_LENGTH];
     182
     183        /* we've got a complete set of metainfo... see if it passes the checksum test */
    183184        dbgmsg( tor, "metainfo piece %d was the last one", piece );
    184185        tr_sha1( sha1, m->metadata, m->metadata_size, NULL );
    185         if( !memcmp( sha1, tor->info.hash, SHA_DIGEST_LENGTH ) )
    186         {
    187             int err;
    188             tr_benc dict;
    189             struct evbuffer * buf = evbuffer_new( );
    190             dbgmsg( tor, "metadata checksum passed!  (length: %d)", (int)m->metadata_size );
    191 
    192             /* add a wrapper dictionary to the benc.
    193              * include the announce-list too,
    194              * so we can save it in the .torrent for future sessions */
    195             evbuffer_add_printf( buf, "d" );
    196             evbuffer_add_printf( buf, "13:announce-list" );
    197             evbuffer_add_printf( buf, "l" );
    198             for( i=0; i<tor->info.trackerCount; ++i ) {
    199                 const char * url = tor->info.trackers[i].announce;
    200                 evbuffer_add_printf( buf, "l%zu:%se", strlen( url ), url );
     186        if(( checksumPassed = !memcmp( sha1, tor->info.hash, SHA_DIGEST_LENGTH )))
     187        {
     188            /* checksum passed; now try to parse it as benc */
     189            tr_benc infoDict;
     190            const int err = tr_bencLoad( m->metadata, m->metadata_size, &infoDict, NULL );
     191            dbgmsg( tor, "err is %d", err );
     192            if(( metainfoParsed = !err ))
     193            {
     194                /* yay we have bencoded metainfo... merge it into our .torrnet file */
     195                tr_benc newMetainfo;
     196                const char * path = tor->info.torrent;
     197                if( !tr_bencLoadFile( &newMetainfo, TR_FMT_BENC, path ) )
     198                {
     199                    tr_bool hasInfo;
     200                    tr_benc * tmp;
     201
     202                    dbgmsg( tor, "Saving completed metadata to \"%s\"", path );
     203                    assert( !tr_bencDictFindDict( &newMetainfo, "info", &tmp ) );
     204                    tr_bencMergeDicts( tr_bencDictAddDict( &newMetainfo, "info", 0 ), &infoDict );
     205                    tr_bencToFile( &newMetainfo, TR_FMT_BENC, path );
     206
     207                    success = tr_metainfoParse( tor->session, &newMetainfo, &tor->info,
     208                                                &hasInfo, &tor->infoDictOffset, &tor->infoDictLength );
     209
     210                    assert( hasInfo );
     211                    assert( success );
     212
     213                    tr_torrentGotNewInfoDict( tor );
     214                    tr_torrentSetDirty( tor );
     215
     216                    tr_bencFree( &newMetainfo );
     217                }
     218       
     219                tr_bencFree( &infoDict );
    201220            }
    202             evbuffer_add_printf( buf, "e" );
    203             evbuffer_add_printf( buf, "4:info" );
    204             evbuffer_add( buf, m->metadata, m->metadata_size );
    205             evbuffer_add_printf( buf, "e" );
    206 
    207             /* does it parse? */
    208             err = tr_bencLoad( EVBUFFER_DATA( buf ), EVBUFFER_LENGTH( buf ), &dict, NULL );
    209             dbgmsg( tor, "err is %d", err );
    210             if( !err )
    211             {
    212                 if( tr_metainfoParse( tor->session,
    213                                       &tor->info,
    214                                       &tor->infoDictOffset,
    215                                       &tor->infoDictLength,
    216                                       &dict ) )
    217                 {
    218                     const char * path = tor->info.torrent;
    219                     dbgmsg( tor, "saving completed metadata to \"%s\"", path );
    220 
    221                     success = TRUE;
    222                     tr_torrentGotNewInfoDict( tor );
    223 
    224                     tr_bencToFile( &dict, TR_FMT_BENC, path );
    225                     tr_sessionSetTorrentFile( tor->session,
    226                                               tor->info.hashString, path );
    227                     tr_torrentSetDirty( tor );
    228                 }
    229 
    230                 tr_bencFree( &dict );
    231             }
    232 
    233             evbuffer_free( buf );
    234221        }
    235222
     
    242229        {
    243230            const int n = m->pieceCount;
    244             for( i=0; i<n; ++i ) {
     231            for( i=0; i<n; ++i )
     232            {
    245233                m->piecesNeeded[i].piece = i;
    246234                m->piecesNeeded[i].requestedAt = 0;
     
    248236            m->piecesNeededCount = n;
    249237            dbgmsg( tor, "metadata error; trying again. %d pieces left", n );
     238
     239            tr_err( "magnet status: checksum passed %d, metainfo parsed %d",
     240                    (int)checksumPassed, (int)metainfoParsed );
    250241        }
    251242    }
  • trunk/libtransmission/torrent.c

    r10078 r10084  
    713713static tr_parse_result
    714714torrentParseImpl( const tr_ctor * ctor, tr_info * setmeInfo,
    715                   int * dictOffset, int * dictLength )
     715                  tr_bool * setmeHasInfo, int * dictOffset, int * dictLength )
    716716{
    717717    int             doFree;
    718718    tr_bool         didParse;
     719    tr_bool         hasInfo = FALSE;
    719720    tr_info         tmp;
    720721    const tr_benc * metainfo;
     
    729730        return TR_PARSE_ERR;
    730731
    731     didParse = tr_metainfoParse( session, setmeInfo, dictOffset, dictLength, metainfo );
     732    didParse = tr_metainfoParse( session, metainfo, setmeInfo,
     733                                 &hasInfo, dictOffset, dictLength );
    732734    doFree = didParse && ( setmeInfo == &tmp );
    733735
     
    735737        result = TR_PARSE_ERR;
    736738
    737     if( didParse && !getBlockSize( setmeInfo->pieceSize ) )
     739    if( didParse && hasInfo && !getBlockSize( setmeInfo->pieceSize ) )
    738740        result = TR_PARSE_ERR;
    739741
     
    744746        tr_metainfoFree( setmeInfo );
    745747
     748    if( setmeHasInfo != NULL )
     749        *setmeHasInfo = hasInfo;
     750
    746751    return result;
    747752}
     
    750755tr_torrentParse( const tr_ctor * ctor, tr_info * setmeInfo )
    751756{
    752     return torrentParseImpl( ctor, setmeInfo, NULL, NULL );
     757    return torrentParseImpl( ctor, setmeInfo, NULL, NULL, NULL );
    753758}
    754759
     
    756761tr_torrentNew( const tr_ctor * ctor, int * setmeError )
    757762{
     763    int off, len;
     764    tr_bool hasInfo;
    758765    tr_info tmpInfo;
     766    tr_parse_result r;
    759767    tr_torrent * tor = NULL;
    760     const tr_magnet_info * magnetInfo;
    761768    tr_session * session = tr_ctorGetSession( ctor );
    762769
     
    764771    assert( tr_isSession( session ) );
    765772
    766     if( !tr_ctorGetMagnet( ctor, &magnetInfo ) )
    767     {
    768         if( tr_torrentFindFromHash( session, magnetInfo->hash ) != NULL )
     773    r = torrentParseImpl( ctor, &tmpInfo, &hasInfo, &off, &len );
     774    if( r == TR_PARSE_OK )
     775    {
     776        tor = tr_new0( tr_torrent, 1 );
     777        tor->info = tmpInfo;
     778        if( hasInfo )
    769779        {
    770             if( setmeError )
    771                 *setmeError = TR_PARSE_DUPLICATE;
    772         }
    773         else
    774         {
    775             tor = tr_new0( tr_torrent, 1 );
    776             tr_metainfoSetFromMagnet( &tor->info, magnetInfo );
    777             torrentInit( tor, ctor );
    778         }
    779     }
    780     else
    781     {
    782         int off, len;
    783         tr_parse_result r = torrentParseImpl( ctor, &tmpInfo, &off, &len );
    784         if( r == TR_PARSE_OK )
    785         {
    786             tor = tr_new0( tr_torrent, 1 );
    787             tor->info = tmpInfo;
    788780            tor->infoDictOffset = off;
    789781            tor->infoDictLength = len;
    790             torrentInit( tor, ctor );
    791782        }
    792         else if( setmeError )
    793         {
    794             *setmeError = r;
    795         }
     783        torrentInit( tor, ctor );
     784    }
     785    else if( setmeError )
     786    {
     787        *setmeError = r;
    796788    }
    797789
     
    14701462    assert( tr_isTorrent( tor ) );
    14711463
    1472     if( tor->isDirty && tr_torrentHasMetadata( tor ) )
     1464    if( tor->isDirty )
    14731465    {
    14741466        tor->isDirty = FALSE;
     
    21322124    if( ok && !tr_bencLoadFile( &metainfo, TR_FMT_BENC, tor->info.torrent ) )
    21332125    {
    2134         tr_info   tmpInfo;
     2126        tr_bool hasInfo;
     2127        tr_info tmpInfo;
    21352128
    21362129        /* remove the old fields */
     
    21612154        /* try to parse it back again, to make sure it's good */
    21622155        memset( &tmpInfo, 0, sizeof( tr_info ) );
    2163         if( tr_metainfoParse( tor->session, &tmpInfo,
    2164                               &tor->infoDictOffset,
    2165                               &tor->infoDictLength,
    2166                               &metainfo ) )
     2156        if( tr_metainfoParse( tor->session, &metainfo, &tmpInfo,
     2157                              &hasInfo, &tor->infoDictOffset, &tor->infoDictLength ) )
    21672158        {
    21682159            /* it's good, so keep these new trackers and free the old ones */
  • trunk/libtransmission/torrent.h

    r9965 r10084  
    3434
    3535int         tr_ctorGetSave( const tr_ctor * ctor );
    36 
    37 int         tr_ctorGetMagnet( const tr_ctor * ctor, const struct tr_magnet_info ** setme );
    3836
    3937void        tr_ctorInitTorrentPriorities( const tr_ctor * ctor, tr_torrent * tor );
  • trunk/libtransmission/transmission.h

    r10078 r10084  
    880880void  tr_ctorSetDeleteSource( tr_ctor * ctor, tr_bool doDelete );
    881881
    882 /** @brief Set the link for creating a tr_torrent from a magnet link */
    883 int tr_ctorSetMagnet( tr_ctor * ctor, const char * magnet_link );
     882/** @brief Set the constructor's metainfo from a magnet link */
     883int tr_ctorSetMetainfoFromMagnetLink( tr_ctor * ctor, const char * magnet_link );
    884884
    885885/** @brief Set the constructor's metainfo from a raw benc already in memory */
  • trunk/macosx/Torrent.m

    r10067 r10084  
    15641564       
    15651565        if (result != TR_PARSE_OK && magnetAddress)
    1566             result = tr_ctorSetMagnet(ctor, [magnetAddress UTF8String]);
     1566            result = tr_ctorSetMetainfoFromMagnetLink(ctor, [magnetAddress UTF8String]);
    15671567       
    15681568        //backup - shouldn't be needed after upgrade to 1.70
Note: See TracChangeset for help on using the changeset viewer.