Ignore:
Timestamp:
Dec 5, 2006, 12:14:52 AM (15 years ago)
Author:
livings124
Message:

initial support for announce-list (currently crashes when a tracker fails)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/multitracker/libtransmission/metainfo.c

    r1124 r1154  
    3131 **********************************************************************/
    3232#define strcatUTF8( dst, src) _strcatUTF8( (dst), sizeof( dst ) - 1, (src) )
     33
    3334static void _strcatUTF8( char *, int, char * );
     35static int parseAnnounce( char * original, char * address, int * port, char * announce );
     36
     37static int parseAnnounce( char * original, char * address, int * port, char * announce )
     38{
     39    char * colon, * slash;
     40   
     41    /* Skip spaces */
     42    while( *original && *original == ' ' )
     43    {
     44        original++;
     45    }
     46
     47    /* Parse announce URL */
     48    if( strncmp( original, "http://", 7 ) )
     49    {
     50        return 0;
     51    }
     52   
     53    colon = strchr( original + 7, ':' );
     54    slash = strchr( original + 7, '/' );
     55    if( colon && colon < slash )
     56    {
     57        memcpy( address, original + 7, (long) colon - (long) original - 7 );
     58        *port = atoi( colon + 1 );
     59        snprintf( announce, MAX_PATH_LENGTH, "%s", slash );
     60       
     61        return 1;
     62    }
     63    else if( slash )
     64    {
     65        memcpy( address, original + 7, (long) slash - (long) original - 7 );
     66        *port = 80;
     67        snprintf( announce, MAX_PATH_LENGTH, "%s", slash );   
     68       
     69        return 1;
     70    }
     71    else
     72    {
     73        return 0;
     74    }
     75}
    3476
    3577/***********************************************************************
     
    4385    FILE       * file;
    4486    char       * buf;
    45     benc_val_t   meta, * beInfo, * list, * val;
    46     char * s, * s2, * s3;
    47     int          i;
     87    benc_val_t   meta, * beInfo, * list, * val, * sublist;
     88    char       * address, * announce;
     89    int          i, j, k, tiers, inTier, port, random;
    4890    struct stat sb;
     91    tr_announce_list_item_t * announceItem, * lastAnnounceItem;
    4992
    5093    assert( NULL == path || NULL == savedHash );
     
    148191    /* We won't need this anymore */
    149192    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    
     193   
     194    address = calloc( sizeof( char ), 256 );
     195    announce = calloc( sizeof( char ), MAX_PATH_LENGTH );
     196   
     197    if( ( val = tr_bencDictFind( &meta, "announce-list" ) ) )
     198    {
     199        list = val->val.l.vals;
     200       
     201        inf->trackerAnnounceList = calloc( sizeof( tr_announce_list_item_t ), val->val.l.count );
     202       
     203        tiers = 0;
     204        for( i = 0; i < val->val.l.count; i++ )
     205        {
     206            sublist = list[i].val.l.vals;
     207           
     208            inTier = 0;
     209            for( j = 0; j < list[i].val.l.count; j++ )
     210            {
     211                if( !parseAnnounce( sublist[j].val.s.s, address, &port, announce ) )
     212                {
     213                    continue;
     214                }
     215               
     216                if( inTier == 0 )
     217                {
     218                    announceItem = & inf->trackerAnnounceList[tiers];
     219                }
     220                else
     221                {
     222                    announceItem = calloc( sizeof( tr_announce_list_item_t ), 1 );
     223                   
     224                    /* Shuffle order of tier addresses */
     225                    random = tr_rand( inTier + 1 );
     226                    if( random == 0 )
     227                    {
     228                        *announceItem = inf->trackerAnnounceList[tiers];
     229                        inf->trackerAnnounceList[tiers].nextItem = announceItem;
     230                        announceItem = & inf->trackerAnnounceList[tiers];
     231                    }
     232                    else
     233                    {
     234                        lastAnnounceItem = & inf->trackerAnnounceList[tiers];
     235                        for( k = 0; k < random - 1; k++ )
     236                        {
     237                            lastAnnounceItem = lastAnnounceItem->nextItem;
     238                        }
     239                       
     240                        announceItem->nextItem = lastAnnounceItem->nextItem;
     241                        lastAnnounceItem->nextItem = announceItem;
     242                    }
     243                }
     244               
     245                snprintf( announceItem->address, 256, "%s", address );
     246                announceItem->port = port;
     247                snprintf( announceItem->announce, MAX_PATH_LENGTH, "%s", announce );
     248               
     249                inTier++;
     250            }
     251           
     252            /* Only use tier if there are useable addresses */
     253            if (inTier)
     254            {
     255                tiers++;
     256            }
     257        }
     258       
     259        inf->trackerAnnounceTiers = tiers;
     260    }
     261
     262    tr_err( "announce-list:" );
     263    for( i = 0; i < inf->trackerAnnounceTiers; i++ )
     264    {
     265        tr_err( "list %d:", i );
     266        for (announceItem = & inf->trackerAnnounceList[i]; announceItem != NULL; announceItem = announceItem->nextItem)
     267        {
     268            tr_err( "%s:%d%s", announceItem->address, announceItem->port, announceItem->announce );
     269        }
     270    }
     271   
     272    /* Regular announce value */
     273    if ( !inf->trackerAnnounceTiers )
     274    {
     275        if( !( val = tr_bencDictFind( &meta, "announce" ) ) )
     276        {
     277            tr_err( "No \"announce\" entry" );
     278            tr_bencFree( &meta );
     279            return 1;
     280        }
     281       
     282        if ( !parseAnnounce( val->val.s.s, address, &port, announce ) )
     283        {
     284            tr_err( "Invalid announce URL (%s)", val->val.s.s );
     285            tr_bencFree( &meta );
     286            return 1;
     287        }
     288       
     289        if ( !inf->trackerAnnounceList )
     290            inf->trackerAnnounceList = calloc( sizeof( tr_announce_list_item_t ), 1 );
     291       
     292        inf->trackerAnnounceTiers = 1;
     293        snprintf( inf->trackerAnnounceList[0].address, 256, "%s", address );
     294        inf->trackerAnnounceList[0].port = port;
     295        snprintf( inf->trackerAnnounceList[0].announce, MAX_PATH_LENGTH, "%s", announce );
     296    }
     297   
     298    free( address );
     299    free( announce );
     300       
    194301    /* Comment info */
    195302    if( ( val = tr_bencDictFind( &meta, "comment.utf-8" ) ) || ( val = tr_bencDictFind( &meta, "comment" ) ) )
Note: See TracChangeset for help on using the changeset viewer.