Ignore:
Timestamp:
Dec 17, 2006, 4:36:27 PM (15 years ago)
Author:
livings124
Message:

merge multitracker branch:

Adds announce list, support for code 301/302 redirect, improvements to mac inspector, better queueing with errors, random extra wait of up to a minute between announces, and other changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/metainfo.c

    r1124 r1242  
    3030 * Local prototypes
    3131 **********************************************************************/
     32static int getannounce( tr_info_t * inf, benc_val_t * meta );
    3233#define strcatUTF8( dst, src) _strcatUTF8( (dst), sizeof( dst ) - 1, (src) )
    3334static void _strcatUTF8( char *, int, char * );
     
    4445    char       * buf;
    4546    benc_val_t   meta, * beInfo, * list, * val;
    46     char * s, * s2, * s3;
    4747    int          i;
    48     struct stat sb;
     48    struct stat  sb;
    4949
    5050    assert( NULL == path || NULL == savedHash );
     
    5252    assert( NULL == savedHash || !saveCopy );
    5353
    54     if ( NULL != savedHash )
     54    if( NULL != savedHash )
    5555    {
    5656        snprintf( inf->torrent, MAX_PATH_LENGTH, "%s/%s",
     
    148148    /* We won't need this anymore */
    149149    free( buf );
    150 
    151     if( !( val = tr_bencDictFind( &meta, "announce" ) ) )
    152     {
    153         tr_err( "No \"announce\" entry" );
    154         tr_bencFree( &meta );
    155         return 1;
    156     }
    157    
    158     /* Skip spaces */
    159     s3 = val->val.s.s;
    160     while( *s3 && *s3 == ' ' )
    161     {
    162         s3++;
    163     }
    164 
    165     /* Parse announce URL */
    166     if( strncmp( s3, "http://", 7 ) )
    167     {
    168         tr_err( "Invalid announce URL (%s)", inf->trackerAddress );
    169         tr_bencFree( &meta );
    170         return 1;
    171     }
    172     s  = strchr( s3 + 7, ':' );
    173     s2 = strchr( s3 + 7, '/' );
    174     if( s && s < s2 )
    175     {
    176         memcpy( inf->trackerAddress, s3 + 7,
    177                 (long) s - (long) s3 - 7 );
    178         inf->trackerPort = atoi( s + 1 );
    179     }
    180     else if( s2 )
    181     {
    182         memcpy( inf->trackerAddress, s3 + 7,
    183                 (long) s2 - (long) s3 - 7 );
    184         inf->trackerPort = 80;
    185     }
    186     else
    187     {
    188         tr_err( "Invalid announce URL (%s)", inf->trackerAddress );
    189         tr_bencFree( &meta );
    190         return 1;
    191     }
    192     snprintf( inf->trackerAnnounce, MAX_PATH_LENGTH, "%s", s2 );
    193    
     150       
    194151    /* Comment info */
    195152    if( ( val = tr_bencDictFind( &meta, "comment.utf-8" ) ) || ( val = tr_bencDictFind( &meta, "comment" ) ) )
     
    213170        inf->dateCreated = 0;
    214171    }
    215 
     172   
     173    /* Private torrent */
     174    if( ( val = tr_bencDictFind( beInfo, "private" ) ) && TYPE_INT == val->type )
     175    {
     176        inf->privateTorrent = val->val.i;
     177    }
     178   
    216179    /* Piece length */
    217180    if( !( val = tr_bencDictFind( beInfo, "piece length" ) ) )
     
    298261    {
    299262        tr_err( "Size of hashes and files don't match" );
    300         free( inf->pieces );
     263        tr_metainfoFree( inf );
    301264        tr_bencFree( &meta );
    302265        return 1;
    303266    }
    304267
     268    /* get announce or announce-list */
     269    if( getannounce( inf, &meta ) )
     270    {
     271        tr_metainfoFree( inf );
     272        tr_bencFree( &meta );
     273        return 1;
     274    }
     275
    305276    tr_bencFree( &meta );
     277    return 0;
     278}
     279
     280void tr_metainfoFree( tr_info_t * inf )
     281{
     282    int ii, jj;
     283
     284    free( inf->pieces );
     285    free( inf->files );
     286   
     287    for( ii = 0; ii < inf->trackerTiers; ii++ )
     288    {
     289        for( jj = 0; jj < inf->trackerList[ii].count; jj++ )
     290        {
     291            free( inf->trackerList[ii].list[jj].address );
     292            free( inf->trackerList[ii].list[jj].announce );
     293        }
     294        free( inf->trackerList[ii].list );
     295    }
     296    free( inf->trackerList );
     297}
     298
     299static int getannounce( tr_info_t * inf, benc_val_t * meta )
     300{
     301    benc_val_t              * val, * subval, * urlval;
     302    char                    * address, * announce;
     303    int                       ii, jj, port, random;
     304    tr_tracker_info_t * sublist;
     305    int subcount;
     306    void * swapping;
     307
     308    /* Announce-list */
     309    val = tr_bencDictFind( meta, "announce-list" );
     310    if( NULL != val && TYPE_LIST == val->type && 0 < val->val.l.count )
     311    {
     312        inf->trackerTiers = 0;
     313        inf->trackerList = calloc( sizeof( inf->trackerList[0] ),
     314                                   val->val.l.count );
     315
     316        /* iterate through the announce-list's tiers */
     317        for( ii = 0; ii < val->val.l.count; ii++ )
     318        {
     319            subval = &val->val.l.vals[ii];
     320            if( TYPE_LIST != subval->type || 0 >= subval->val.l.count )
     321            {
     322                continue;
     323            }
     324            subcount = 0;
     325            sublist = calloc( sizeof( sublist[0] ), subval->val.l.count );
     326
     327            /* iterate through the tier's items */
     328            for( jj = 0; jj < subval->val.l.count; jj++ )
     329            {
     330                urlval = &subval->val.l.vals[jj];
     331                if( TYPE_STR != urlval->type ||
     332                    tr_httpParseUrl( urlval->val.s.s, urlval->val.s.i,
     333                                     &address, &port, &announce ) )
     334                {
     335                    continue;
     336                }
     337
     338                /* place the item info in a random location in the sublist */
     339                random = tr_rand( subcount + 1 );
     340                if( random != subcount )
     341                {
     342                    sublist[subcount] = sublist[random];
     343                }
     344                sublist[random].address  = address;
     345                sublist[random].port     = port;
     346                sublist[random].announce = announce;
     347                subcount++;
     348            }
     349
     350            /* just use sublist as is if it's full */
     351            if( subcount == subval->val.l.count )
     352            {
     353                inf->trackerList[inf->trackerTiers].list = sublist;
     354                inf->trackerList[inf->trackerTiers].count = subcount;
     355                inf->trackerTiers++;
     356            }
     357            /* if we skipped some of the tier's items then trim the sublist */
     358            else if( 0 < subcount )
     359            {
     360                inf->trackerList[inf->trackerTiers].list = calloc( sizeof( sublist[0] ), subcount );
     361                memcpy( inf->trackerList[inf->trackerTiers].list, sublist,
     362                        sizeof( sublist[0] ) * subcount );
     363                inf->trackerList[inf->trackerTiers].count = subcount;
     364                inf->trackerTiers++;
     365                free( sublist );
     366            }
     367            /* drop the whole sublist if we didn't use any items at all */
     368            else
     369            {
     370                free( sublist );
     371            }
     372        }
     373
     374        /* did we use any of the tiers? */
     375        if( 0 == inf->trackerTiers )
     376        {
     377            tr_inf( "No valid entries in \"announce-list\"" );
     378            free( inf->trackerList );
     379            inf->trackerList = NULL;
     380        }
     381        /* trim unused sublist pointers */
     382        else if( inf->trackerTiers < val->val.l.count )
     383        {
     384            swapping = inf->trackerList;
     385            inf->trackerList = calloc( sizeof( inf->trackerList[0] ),
     386                                       inf->trackerTiers );
     387            memcpy( inf->trackerList, swapping,
     388                    sizeof( inf->trackerList[0] ) * inf->trackerTiers );
     389            free( swapping );
     390        }
     391    }
     392
     393    /* Regular announce value */
     394    if( 0 == inf->trackerTiers )
     395    {
     396        val = tr_bencDictFind( meta, "announce" );
     397        if( NULL == val || TYPE_STR != val->type )
     398        {
     399            tr_err( "No \"announce\" entry" );
     400            return 1;
     401        }
     402
     403        if( tr_httpParseUrl( val->val.s.s, val->val.s.i,
     404                             &address, &port, &announce ) )
     405        {
     406            tr_err( "Invalid announce URL (%s)", val->val.s.s );
     407            return 1;
     408        }
     409
     410        sublist                   = calloc( sizeof( sublist[0] ), 1 );
     411        sublist[0].address        = address;
     412        sublist[0].port           = port;
     413        sublist[0].announce       = announce;
     414        inf->trackerList          = calloc( sizeof( inf->trackerList[0] ), 1 );
     415        inf->trackerList[0].list  = sublist;
     416        inf->trackerList[0].count = 1;
     417        inf->trackerTiers         = 1;
     418    }
     419
    306420    return 0;
    307421}
Note: See TracChangeset for help on using the changeset viewer.