Modified tr_torrentCanAdd() to give the new functionality BMW suggests

This commit is contained in:
Charles Kerr 2007-06-27 14:54:31 +00:00
parent 47a5ff4120
commit 8e401729cd
6 changed files with 159 additions and 117 deletions

View File

@ -29,11 +29,6 @@
# define lrintf(a) ((int)(0.5+(a)))
#endif
/* We may try to allocate and free tables of size 0.
Quick and dirty way to handle it... */
#define malloc tr_malloc
#define free tr_free
struct tr_choking_s
{
tr_lock_t lock;
@ -45,7 +40,7 @@ tr_choking_t * tr_chokingInit( tr_handle_t * h )
{
tr_choking_t * c;
c = calloc( 1, sizeof( tr_choking_t ) );
c = tr_new0( tr_choking_t, 1 );
c->h = h;
c->slots = 4242;
tr_lockInit( &c->lock );
@ -92,14 +87,13 @@ static inline void sortPeers( tr_peer_t ** all, int allCount,
/* Randomly shuffle non-uploaders, so they are treated equally */
if( *zeroCount && ( shuffle = tr_rand( *zeroCount ) ) )
{
tr_peer_t ** bak;
bak = malloc( shuffle * sizeof( tr_peer_t * ) );
tr_peer_t ** bak = tr_new( tr_peer_t*, shuffle );;
memcpy( bak, zero, shuffle * sizeof( tr_peer_t * ) );
memmove( zero, &zero[shuffle],
( *zeroCount - shuffle ) * sizeof( tr_peer_t * ) );
memcpy( &zero[*zeroCount - shuffle], bak,
shuffle * sizeof( tr_peer_t * ) );
free( bak );
tr_free( bak );
}
/* Sort uploaders by download rate */
@ -149,8 +143,8 @@ void tr_chokingPulse( tr_choking_t * c )
peersTotalCount += tor->peerCount;
}
canChoke = malloc( peersTotalCount * sizeof( tr_peer_t * ) );
canUnchoke = malloc( peersTotalCount * sizeof( tr_peer_t * ) );
canChoke = tr_new( tr_peer_t*, peersTotalCount );
canUnchoke = tr_new( tr_peer_t*, peersTotalCount );
canChokeCount = 0;
canUnchokeCount = 0;
unchoked = 0;
@ -212,10 +206,10 @@ void tr_chokingPulse( tr_choking_t * c )
}
}
canChokeZero = malloc( canChokeCount * sizeof( tr_peer_t * ) );
canChokeNonZero = malloc( canChokeCount * sizeof( tr_peer_t * ) );
canUnchokeZero = malloc( canUnchokeCount * sizeof( tr_peer_t * ) );
canUnchokeNonZero = malloc( canUnchokeCount * sizeof( tr_peer_t * ) );
canChokeZero = tr_new( tr_peer_t*, canChokeCount );
canChokeNonZero = tr_new( tr_peer_t*, canChokeCount );
canUnchokeZero = tr_new( tr_peer_t*, canUnchokeCount );
canUnchokeNonZero = tr_new( tr_peer_t*, canUnchokeCount );
sortPeersDescending( canChoke, canChokeCount,
canChokeZero, &canChokeZeroCount,
@ -224,8 +218,8 @@ void tr_chokingPulse( tr_choking_t * c )
canUnchokeZero, &canUnchokeZeroCount,
canUnchokeNonZero, &canUnchokeNonZeroCount);
free( canChoke );
free( canUnchoke );
tr_free( canChoke );
tr_free( canUnchoke );
if( mustOptimistic )
{
@ -303,10 +297,10 @@ void tr_chokingPulse( tr_choking_t * c )
tr_peerUnchoke( canUnchokeZero[--canUnchokeZeroCount] );
}
free( canChokeZero );
free( canChokeNonZero );
free( canUnchokeZero );
free( canUnchokeNonZero );
tr_free( canChokeZero );
tr_free( canChokeNonZero );
tr_free( canUnchokeZero );
tr_free( canUnchokeNonZero );
/* Unlock all torrents */
for( tor = c->h->torrentList; tor; tor = tor->next )
@ -318,5 +312,5 @@ void tr_chokingPulse( tr_choking_t * c )
void tr_chokingClose( tr_choking_t * c )
{
tr_lockClose( &c->lock );
free( c );
tr_free( c );
}

View File

@ -51,13 +51,13 @@ tr_completion_t * tr_cpInit( tr_torrent_t * tor )
{
tr_completion_t * cp;
cp = malloc( sizeof( tr_completion_t ) );
cp = tr_new( tr_completion_t, 1 );
cp->tor = tor;
cp->blockBitfield = tr_bitfieldNew( tor->blockCount );
cp->blockDownloaders = malloc( tor->blockCount );
cp->blockDownloaders = tr_new( uint8_t, tor->blockCount );
cp->pieceBitfield = tr_bitfieldNew( tor->info.pieceCount );
cp->missingBlocks = malloc( tor->info.pieceCount * sizeof( int ) );
cp->completeBlocks = malloc( tor->info.pieceCount * sizeof( int ) );
cp->missingBlocks = tr_new( int, tor->info.pieceCount );
cp->completeBlocks = tr_new( int, tor->info.pieceCount );
cp->nBlocksInLastPiece = tr_pieceCountBlocks ( tor->info.pieceCount - 1 );
cp->nBlocksInPiece = tor->info.pieceCount==1 ? cp->nBlocksInLastPiece
@ -70,12 +70,12 @@ tr_completion_t * tr_cpInit( tr_torrent_t * tor )
void tr_cpClose( tr_completion_t * cp )
{
tr_bitfieldFree( cp->blockBitfield );
free( cp->blockDownloaders );
tr_free( cp->completeBlocks );
tr_free( cp->missingBlocks );
tr_bitfieldFree( cp->pieceBitfield );
free( cp->missingBlocks );
free( cp->completeBlocks );
free( cp );
tr_free( cp->blockDownloaders );
tr_bitfieldFree( cp->blockBitfield );
tr_free( cp );
}
void tr_cpReset( tr_completion_t * cp )
@ -263,7 +263,7 @@ int tr_cpMostMissingBlockInPiece( const tr_completion_t * cp,
count = tr_cpCountBlocks( cp, piece );
end = start + count;
pool = malloc( count * sizeof( int ) );
pool = tr_new( int, count );
poolSize = 0;
min = 255;
@ -294,7 +294,7 @@ int tr_cpMostMissingBlockInPiece( const tr_completion_t * cp,
ret = -1;
}
free( pool );
tr_free( pool );
return ret;
}

View File

@ -29,7 +29,7 @@
/***********************************************************************
* Local prototypes
**********************************************************************/
static int realparse( tr_info_t * inf, uint8_t * buf, size_t len );
static int realparse( tr_info_t * inf, const uint8_t * buf, size_t len );
static void savedname( char * name, size_t len, const char * hash,
const char * tag );
static uint8_t * readtorrent( const char * path, size_t * len );
@ -59,13 +59,13 @@ tr_metainfoParseFile( tr_info_t * inf, const char * tag,
buf = readtorrent( path, &size );
if( NULL == buf )
{
return 1;
return TR_EINVALID;
}
if( realparse( inf, buf, size ) )
{
free( buf );
return 1;
return TR_EINVALID;
}
if( save )
@ -73,7 +73,7 @@ tr_metainfoParseFile( tr_info_t * inf, const char * tag,
if( savetorrent( inf->hashString, tag, buf, size ) )
{
free( buf );
return 1;
return TR_EINVALID;
}
savedname( inf->torrent, sizeof inf->torrent, inf->hashString, tag );
}
@ -84,28 +84,28 @@ tr_metainfoParseFile( tr_info_t * inf, const char * tag,
free( buf );
return 0;
return TR_OK;
}
int
tr_metainfoParseData( tr_info_t * inf, const char * tag,
uint8_t * data, size_t size, int save )
const uint8_t * data, size_t size, int save )
{
if( realparse( inf, data, size ) )
{
return 1;
return TR_EINVALID;
}
if( save )
{
if( savetorrent( inf->hashString, tag, data, size ) )
{
return 1;
return TR_EINVALID;
}
savedname( inf->torrent, sizeof inf->torrent, inf->hashString, tag );
}
return 0;
return TR_OK;
}
int
@ -132,13 +132,13 @@ tr_metainfoParseHash( tr_info_t * inf, const char * tag, const char * hash )
buf = readtorrent( inf->torrent, &size );
if( NULL == buf )
{
return 1;
return TR_EINVALID;
}
if( realparse( inf, buf, size ) )
{
free( buf );
return 1;
return TR_EINVALID;
}
/* save a new tagged copy of the old untagged torrent */
@ -147,18 +147,18 @@ tr_metainfoParseHash( tr_info_t * inf, const char * tag, const char * hash )
if( savetorrent( hash, tag, buf, size ) )
{
free( buf );
return 1;
return TR_EINVALID;
}
savedname( inf->torrent, sizeof inf->torrent, hash, tag );
}
free( buf );
return 0;
return TR_OK;
}
int
realparse( tr_info_t * inf, uint8_t * buf, size_t size )
realparse( tr_info_t * inf, const uint8_t * buf, size_t size )
{
benc_val_t meta, * beInfo, * val, * val2;
int i;
@ -167,7 +167,7 @@ realparse( tr_info_t * inf, uint8_t * buf, size_t size )
if( tr_bencLoad( buf, size, &meta, NULL ) )
{
tr_err( "Error while parsing bencoded data" );
return 1;
return TR_EINVALID;
}
/* Get info hash */
@ -176,7 +176,7 @@ realparse( tr_info_t * inf, uint8_t * buf, size_t size )
{
tr_err( "%s \"info\" dictionary", ( beInfo ? "Invalid" : "Missing" ) );
tr_bencFree( &meta );
return 1;
return TR_EINVALID;
}
SHA1( (uint8_t *) beInfo->begin,
(long) beInfo->end - (long) beInfo->begin, inf->hash );
@ -273,12 +273,12 @@ realparse( tr_info_t * inf, uint8_t * buf, size_t size )
}
tr_bencFree( &meta );
return 0;
return TR_OK;
fail:
tr_metainfoFree( inf );
tr_bencFree( &meta );
return 1;
return TR_EINVALID;
}
void tr_metainfoFree( tr_info_t * inf )
@ -310,13 +310,13 @@ static int getfile( char * buf, int size,
if( TYPE_LIST != name->type )
{
return 1;
return TR_EINVALID;
}
list = calloc( name->val.l.count, sizeof( list[0] ) );
if( NULL == list )
{
return 1;
return TR_EINVALID;
}
for( ii = jj = 0; name->val.l.count > ii; ii++ )
@ -342,7 +342,7 @@ static int getfile( char * buf, int size,
if( 0 == jj )
{
return 1;
return TR_EINVALID;
}
strcatUTF8( buf, size, prefix, 0 );
@ -353,7 +353,7 @@ static int getfile( char * buf, int size,
}
free( list );
return 0;
return TR_OK;
}
static int getannounce( tr_info_t * inf, benc_val_t * meta )
@ -457,14 +457,14 @@ static int getannounce( tr_info_t * inf, benc_val_t * meta )
if( NULL == val || TYPE_STR != val->type )
{
tr_err( "No \"announce\" entry" );
return 1;
return TR_EINVALID;
}
if( tr_httpParseUrl( val->val.s.s, val->val.s.i,
&address, &port, &announce ) )
{
tr_err( "Invalid announce URL (%s)", val->val.s.s );
return 1;
return TR_EINVALID;
}
sublist = calloc( 1, sizeof( sublist[0] ) );
@ -478,7 +478,7 @@ static int getannounce( tr_info_t * inf, benc_val_t * meta )
inf->trackerTiers = 1;
}
return 0;
return TR_OK;
}
static char * announceToScrape( const char * announce )
@ -614,18 +614,18 @@ int savetorrent( const char * hash, const char * tag,
if( !file )
{
tr_err( "Could not open file (%s) (%s)", path, strerror( errno ) );
return 1;
return TR_EINVALID;
}
fseek( file, 0, SEEK_SET );
if( fwrite( buf, 1, buflen, file ) != buflen )
{
tr_err( "Could not write file (%s) (%s)", path, strerror( errno ) );
fclose( file );
return 1;
return TR_EINVALID;
}
fclose( file );
return 0;
return TR_OK;
}
int
@ -638,14 +638,14 @@ parseFiles( tr_info_t * inf, benc_val_t * name,
if( NULL == name || TYPE_STR != name->type )
{
tr_err( "%s \"name\" string", ( name ? "Invalid" : "Missing" ) );
return 1;
return TR_EINVALID;
}
strcatUTF8( inf->name, sizeof( inf->name ), name->val.s.s, 1 );
if( '\0' == inf->name[0] )
{
tr_err( "Invalid \"name\" string" );
return 1;
return TR_EINVALID;
}
inf->totalSize = 0;
@ -658,7 +658,7 @@ parseFiles( tr_info_t * inf, benc_val_t * name,
if( NULL == inf->files )
{
return 1;
return TR_EINVALID;
}
for( ii = 0; files->val.l.count > ii; ii++ )
@ -670,14 +670,14 @@ parseFiles( tr_info_t * inf, benc_val_t * name,
{
tr_err( "%s \"path\" entry",
( path ? "Invalid" : "Missing" ) );
return 1;
return TR_EINVALID;
}
length = tr_bencDictFind( item, "length" );
if( NULL == length || TYPE_INT != length->type )
{
tr_err( "%s \"length\" entry",
( length ? "Invalid" : "Missing" ) );
return 1;
return TR_EINVALID;
}
inf->files[ii].length = length->val.i;
inf->totalSize += length->val.i;
@ -692,7 +692,7 @@ parseFiles( tr_info_t * inf, benc_val_t * name,
if( NULL == inf->files )
{
return 1;
return TR_EINVALID;
}
strcatUTF8( inf->files[0].name, sizeof( inf->files[0].name ),
@ -708,7 +708,7 @@ parseFiles( tr_info_t * inf, benc_val_t * name,
( length ? "invalid" : "missing" ) );
}
return 0;
return TR_OK;
}
/***********************************************************************

View File

@ -30,7 +30,7 @@
int tr_metainfoParseFile( tr_info_t *, const char * tag,
const char * path, int save );
int tr_metainfoParseData( tr_info_t *, const char * tag,
uint8_t * data, size_t size, int save );
const uint8_t * data, size_t size, int save );
int tr_metainfoParseHash( tr_info_t *, const char * tag, const char * hash );
void tr_metainfoFree( tr_info_t * inf );
void tr_metainfoRemoveSaved( const char * hashString, const char * tag );

View File

@ -276,16 +276,24 @@ infoCanAdd( const tr_handle_t * h,
}
int
tr_torrentCanAdd( const tr_handle_t * h,
const char * destination,
const char * path )
tr_torrentParse( const tr_handle_t * h,
const char * path,
const char * destination,
tr_info_t * setme_info,
int * setme_canAdd )
{
tr_info_t info;
int ret;
tr_info_t tmp;
if( tr_metainfoParseFile( &info, h->tag, path, FALSE ) )
return TR_EINVALID;
if( setme_info == NULL )
setme_info = &tmp;
return infoCanAdd( h, destination, &info );
ret = tr_metainfoParseFile( setme_info, h->tag, path, FALSE );
if( setme_canAdd )
*setme_canAdd = ret ? ret : infoCanAdd( h, destination, setme_info );
return ret;
}
tr_torrent_t *
@ -296,10 +304,13 @@ tr_torrentInit( tr_handle_t * h,
int * error )
{
int val;
int err = 0;
tr_torrent_t * tor = NULL;
if(( val = tr_torrentCanAdd( h, destination, path ) ))
if(( val = tr_torrentParse( h, destination, path, NULL, &err )))
*error = val;
else if( err )
*error = err;
else if(!(( tor = tr_new0( tr_torrent_t, 1 ))))
*error = TR_EOTHER;
else {
@ -311,30 +322,42 @@ tr_torrentInit( tr_handle_t * h,
}
static int
tr_torrentCanAddHash( tr_handle_t * h,
const char * destination,
const char * hashStr )
tr_torrentParseHash( const tr_handle_t * h,
const char * hashStr,
const char * destination,
tr_info_t * setme_info,
int * setme_canAdd )
{
tr_info_t info;
int ret;
tr_info_t tmp;
if( tr_metainfoParseHash( &info, h->tag, hashStr ) )
return TR_EINVALID;
if( setme_info == NULL )
setme_info = &tmp;
return infoCanAdd( h, destination, &info );
ret = tr_metainfoParseHash( setme_info, h->tag, hashStr );
if( setme_canAdd )
*setme_canAdd = ret ? ret : infoCanAdd( h, destination, setme_info );
return ret;
}
tr_torrent_t *
tr_torrentInitSaved( tr_handle_t * h,
const char * hashStr,
const char * destination,
int flags,
int * error )
tr_torrentInitSaved( tr_handle_t * h,
const char * hashStr,
const char * destination,
int flags,
int * error )
{
int val;
int err = 0;
tr_torrent_t * tor = NULL;
if(( val = tr_torrentCanAddHash( h, destination, hashStr ) ))
if(( val = tr_torrentParseHash( h, hashStr, destination, NULL, &err )))
*error = val;
else if( err )
*error = err;
else if(!(( tor = tr_new0( tr_torrent_t, 1 ))))
*error = TR_EOTHER;
else {
@ -346,32 +369,43 @@ tr_torrentInitSaved( tr_handle_t * h,
}
static int
tr_torrentCanAddData( tr_handle_t * h,
const char * destination,
uint8_t * data,
size_t size )
tr_torrentParseData( const tr_handle_t * h,
const uint8_t * data,
size_t size,
const char * destination,
tr_info_t * setme_info,
int * setme_canAdd )
{
tr_info_t info;
int ret;
tr_info_t tmp;
if( tr_metainfoParseData( &info, h->tag, data, size, FALSE ) )
return TR_EINVALID;
if( setme_info == NULL )
setme_info = &tmp;
return infoCanAdd( h, destination, &info );
ret = tr_metainfoParseData( setme_info, h->tag, data, size, FALSE );
if( setme_canAdd )
*setme_canAdd = ret ? ret : infoCanAdd( h, destination, setme_info );
return ret;
}
tr_torrent_t *
tr_torrentInitData( tr_handle_t * h,
uint8_t * data,
size_t size,
const char * destination,
int flags,
int * error )
tr_torrentInitData( tr_handle_t * h,
const uint8_t * data,
size_t size,
const char * destination,
int flags,
int * error )
{
int val;
int err = 0;
tr_torrent_t * tor = NULL;
if(( val = tr_torrentCanAddData( h, destination, data, size ) ))
if(( val = tr_torrentParseData( h, data, size, destination, NULL, &err ) ))
*error = val;
else if( err )
*error = err;
else if(!(( tor = tr_new0( tr_torrent_t, 1 ))))
*error = TR_EOTHER;
else {

View File

@ -263,19 +263,34 @@ void tr_close( tr_handle_t * );
#define TR_EUNSUPPORTED 2
#define TR_EDUPLICATE 3
#define TR_EOTHER 666
tr_torrent_t * tr_torrentInit( tr_handle_t *,
const char * path,
const char * destination,
int flags, int * error );
tr_torrent_t * tr_torrentInit( tr_handle_t * handle,
const char * metainfo_filename,
const char * destination,
int flags,
int * setme_error );
typedef struct tr_info_s tr_info_t;
/**
* Checks to see if the specified torrent file could be
* successfully added to Transmission.
* returns TR_OK, TR_EDUPLICATE, TR_ERROR_IO_DUP_DOWNLOAD, or TR_EINVALID.
* Parses the specified metainfo file.
*
* Returns TR_OK or TR_INVALID based on whether or not the
* metainfo file is successfully parsed.
*
* If parsing succeeded and "setme_info" is non-NULL,
* it will be populated with the file's information.
*
* If "setme_canAdd" is non-NULL, it will be set to TR_OK,
* TR_EDUPLICATE, TR_ERROR_IO_DUP_DOWNLOAD, or TR_EINVALID.
*
* "destination" is used for the canAdd tests, so it can
* be NULL if "setme_canAdd" is too.
*/
int tr_torrentCanAdd( const tr_handle_t * handle,
const char * destination,
const char * path );
int tr_torrentParse( const tr_handle_t * handle,
const char * metainfo_filename,
const char * destination,
tr_info_t * setme_info,
int * setme_canAdd );
/***********************************************************************
* tr_torrentInitData
@ -284,7 +299,7 @@ int tr_torrentCanAdd( const tr_handle_t * handle,
* instead of the filename.
**********************************************************************/
tr_torrent_t * tr_torrentInitData( tr_handle_t *,
uint8_t * data, size_t size,
const uint8_t * data, size_t size,
const char * destination,
int flags, int * error );
@ -314,7 +329,6 @@ void tr_torrentDisablePex( tr_torrent_t *, int disable );
***********************************************************************
* Return torrent metainfo.
**********************************************************************/
typedef struct tr_info_s tr_info_t;
tr_info_t * tr_torrentInfo( tr_torrent_t * );
/***********************************************************************