From: Charles Kerr <charles@transmissionbt.com> Date: Sun, 13 Apr 2008 22:31:07 +0000 (+0000) Subject: #394: resume files should use original name instead of hash name X-Git-Tag: 1.20~181 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4843187f6cd130593edc4cf28e70351b04add60c;p=transmission #394: resume files should use original name instead of hash name --- diff --git a/libtransmission/bencode-test.c b/libtransmission/bencode-test.c index 2d57b923c..2ffd6b84d 100644 --- a/libtransmission/bencode-test.c +++ b/libtransmission/bencode-test.c @@ -169,12 +169,14 @@ testParse( void ) const uint8_t * end; int err; int len; + int64_t i; char * saved; snprintf( (char*)buf, sizeof( buf ), "i64e" ); err = tr_bencParse( buf, buf + sizeof( buf ), &val, &end ); check( !err ); - check( tr_bencGetInt( &val ) == 64 ); + check( tr_bencGetInt( &val, &i ) ); + check( i == 64 ); check( end == buf + 4 ); tr_bencFree( &val ); @@ -183,9 +185,12 @@ testParse( void ) check( !err ); check( end == buf + strlen( (char*)buf ) ); check( val.val.l.count == 3 ); - check( tr_bencGetInt( &val.val.l.vals[0] ) == 64 ); - check( tr_bencGetInt( &val.val.l.vals[1] ) == 32 ); - check( tr_bencGetInt( &val.val.l.vals[2] ) == 16 ); + check( tr_bencGetInt( &val.val.l.vals[0], &i ) ); + check( i == 64 ); + check( tr_bencGetInt( &val.val.l.vals[1], &i ) ); + check( i == 32 ); + check( tr_bencGetInt( &val.val.l.vals[2], &i ) ); + check( i == 16 ); saved = tr_bencSave( &val, &len ); check( !strcmp( saved, (char*)buf ) ); tr_free( saved ); diff --git a/libtransmission/bencode.c b/libtransmission/bencode.c index e1ca9c7cc..cdd0ac9dc 100644 --- a/libtransmission/bencode.c +++ b/libtransmission/bencode.c @@ -385,11 +385,15 @@ tr_bencListGetNthChild( tr_benc * val, int i ) return ret; } -int64_t -tr_bencGetInt ( const tr_benc * val ) +int +tr_bencGetInt ( const tr_benc * val, int64_t * setme ) { - assert( tr_bencIsInt( val ) ); - return val->val.i; + int success = FALSE; + if( tr_bencIsInt( val )) { + *setme = val->val.i ; + success = TRUE; + } + return success; } char * @@ -400,6 +404,84 @@ tr_bencStealStr( tr_benc * val ) return val->val.s.s; } +int +tr_bencDictFindInt( tr_benc * dict, const char * key, int64_t * setme ) +{ + int found = FALSE; + tr_benc * child = tr_bencDictFindType( dict, key, TYPE_INT ); + if( child ) + found = tr_bencGetInt( child, setme ); + return found; +} + +int +tr_bencDictFindList( tr_benc * dict, const char * key, tr_benc ** setme ) +{ + int found = FALSE; + tr_benc * child = tr_bencDictFindType( dict, key, TYPE_LIST ); + if( child ) { + *setme = child; + found = TRUE; + } + return found; +} + +int +tr_bencDictFindDict( tr_benc * dict, const char * key, tr_benc ** setme ) +{ + int found = FALSE; + tr_benc * child = tr_bencDictFindType( dict, key, TYPE_DICT ); + if( child ) { + *setme = child; + found = TRUE; + } + return found; +} + +int +tr_bencDictFindStr( tr_benc * dict, const char * key, const char ** setme ) +{ + int found = FALSE; + tr_benc * child = tr_bencDictFindType( dict, key, TYPE_STR ); + if( child ) { + *setme = child->val.s.s; + found = TRUE; + } + return found; +} + +tr_benc* +tr_bencDictAddInt( tr_benc * dict, const char * key, int64_t val ) +{ + tr_benc * child = tr_bencDictAdd( dict, key ); + tr_bencInitInt( child, val ); + return child; +} + +tr_benc* +tr_bencDictAddStr( tr_benc * dict, const char * key, const char * val ) +{ + tr_benc * child = tr_bencDictAdd( dict, key ); + tr_bencInitStrDup( child, val ); + return child; +} + +tr_benc* +tr_bencDictAddList( tr_benc * dict, const char * key, int reserveCount ) +{ + tr_benc * child = tr_bencDictAdd( dict, key ); + tr_bencInitList( child, reserveCount ); + return child; +} + +tr_benc* +tr_bencDictAddDict( tr_benc * dict, const char * key, int reserveCount ) +{ + tr_benc * child = tr_bencDictAdd( dict, key ); + tr_bencInitDict( child, reserveCount ); + return child; +} + /*** **** ***/ @@ -418,9 +500,9 @@ _tr_bencInitStr( tr_benc * val, char * str, int len, int nofree ) } int -tr_bencInitStrDup( tr_benc * val, const char * str ) +tr_bencInitStrDupLen( tr_benc * val, const char * str, int len ) { - char * newStr = tr_strdup( str ); + char * newStr = tr_strndup( str, len ); if( newStr == NULL ) return 1; @@ -428,6 +510,12 @@ tr_bencInitStrDup( tr_benc * val, const char * str ) return 0; } +int +tr_bencInitStrDup( tr_benc * val, const char * str ) +{ + return tr_bencInitStrDupLen( val, str, -1 ); +} + void tr_bencInitInt( tr_benc * val, int64_t num ) { @@ -469,6 +557,10 @@ tr_bencListAdd( tr_benc * list ) tr_benc * item; assert( tr_bencIsList( list ) ); + + if( list->val.l.count == list->val.l.alloc ) + tr_bencListReserve( list, LIST_SIZE ); + assert( list->val.l.count < list->val.l.alloc ); item = &list->val.l.vals[list->val.l.count]; @@ -691,7 +783,7 @@ bencWalk( const tr_benc * top, static void saveIntFunc( const tr_benc * val, void * evbuf ) { - evbuffer_add_printf( evbuf, "i%"PRId64"e", tr_bencGetInt(val) ); + evbuffer_add_printf( evbuf, "i%"PRId64"e", val->val.i ); } static void saveStringFunc( const tr_benc * val, void * vevbuf ) @@ -794,7 +886,7 @@ printIntFunc( const tr_benc * val, void * vdata ) { struct WalkPrint * data = vdata; printLeadingSpaces( data ); - fprintf( data->out, "int: %"PRId64"\n", tr_bencGetInt(val) ); + fprintf( data->out, "int: %"PRId64"\n", val->val.i ); } static void printStringFunc( const tr_benc * val, void * vdata ) @@ -903,7 +995,7 @@ phpIntFunc( const tr_benc * val, void * vdata ) { struct phpWalk * data = vdata; phpChildFunc( data ); - evbuffer_add_printf( data->out, "i:%"PRId64";", tr_bencGetInt(val) ); + evbuffer_add_printf( data->out, "i:%"PRId64";", val->val.i ); } static void phpStringFunc( const tr_benc * val, void * vdata ) diff --git a/libtransmission/bencode.h b/libtransmission/bencode.h index fc55612e5..4c7cfea96 100644 --- a/libtransmission/bencode.h +++ b/libtransmission/bencode.h @@ -68,6 +68,10 @@ int tr_bencLoad( const void * buf, void tr_bencPrint( const tr_benc * ); void tr_bencFree( tr_benc * ); +int tr_bencDictFindInt( tr_benc * dict, const char * key, int64_t * setme ); +int tr_bencDictFindStr( tr_benc * dict, const char * key, const char ** setme ); +int tr_bencDictFindList( tr_benc * dict, const char * key, tr_benc ** setme ); +int tr_bencDictFindDict( tr_benc * dict, const char * key, tr_benc ** setme ); tr_benc * tr_bencDictFind( tr_benc * dict, const char * key ); tr_benc * tr_bencDictFindType( tr_benc * dict, const char * key, int type ); tr_benc * tr_bencDictFindFirst( tr_benc * dict, ... ); @@ -87,6 +91,7 @@ static inline void tr_bencInit( tr_benc * val, int type ) _tr_bencInitStr( (a), ( char * )(b), (c), (d) ) void _tr_bencInitStr( tr_benc * val, char * str, int len, int nofree ); int tr_bencInitStrDup( tr_benc * val, const char * str ); +int tr_bencInitStrDupLen( tr_benc * val, const char * str, int len ); void tr_bencInitInt( tr_benc * val, int64_t num ); int tr_bencInitDict( tr_benc * val, int reserveCount ); int tr_bencInitList( tr_benc * val, int reserveCount ); @@ -95,13 +100,16 @@ int tr_bencListReserve( tr_benc * list, int count ); int tr_bencDictReserve( tr_benc * dict, int count ); tr_benc * tr_bencListAdd( tr_benc * list ); /* note: key must not be freed or modified while val is in use */ -tr_benc * tr_bencDictAdd( tr_benc * dict, const char * key ); +tr_benc * tr_bencDictAdd( tr_benc * dict, const char * key ); +tr_benc * tr_bencDictAddInt( tr_benc * dict, const char * key, int64_t val ); +tr_benc * tr_bencDictAddStr( tr_benc * dict, const char * key, const char * val ); +tr_benc * tr_bencDictAddList( tr_benc * dict, const char * key, int reserveCount ); +tr_benc * tr_bencDictAddDict( tr_benc * dict, const char * key, int reserveCount ); char* tr_bencSave( const tr_benc * val, int * len ); char* tr_bencSaveAsSerializedPHP( const tr_benc * top, int * len ); - -int64_t tr_bencGetInt( const tr_benc * val ); +int tr_bencGetInt( const tr_benc * val, int64_t * setme ); int tr_bencIsType( const tr_benc *, int type ); #define tr_bencIsInt(b) (tr_bencIsType(b,TYPE_INT)) diff --git a/libtransmission/resume.c b/libtransmission/resume.c index 4e0f064cd..99b5b97f0 100644 --- a/libtransmission/resume.c +++ b/libtransmission/resume.c @@ -10,24 +10,317 @@ * $Id:$ */ +#include <sys/types.h> /* stat */ +#include <sys/stat.h> /* stat */ +#include <unistd.h> /* unlink, stat */ + #include <string.h> -#include <unistd.h> /* unlink */ #include "transmission.h" +#include "bencode.h" +#include "completion.h" #include "fastresume.h" +#include "peer-mgr.h" /* pex */ #include "platform.h" /* tr_getResumeDir */ #include "resume.h" #include "torrent.h" #include "utils.h" /* tr_buildPath */ +#define KEY_CORRUPT "corrupt" +#define KEY_DESTINATION "destination" +#define KEY_DOWNLOADED "downloaded" +#define KEY_MAX_PEERS "max-peers" +#define KEY_PAUSED "paused" +#define KEY_PEERS "peers" +#define KEY_PRIORITY "priority" +#define KEY_PROGRESS "progress" +#define KEY_SPEEDLIMIT "speed-limit" +#define KEY_UPLOADED "uploaded" + +#define KEY_SPEEDLIMIT_DOWN_SPEED "down-speed" +#define KEY_SPEEDLIMIT_DOWN_MODE "down-mode" +#define KEY_SPEEDLIMIT_UP_SPEED "up-speed" +#define KEY_SPEEDLIMIT_UP_MODE "up-mode" + +#define KEY_PROGRESS_MTIMES "mtimes" +#define KEY_PROGRESS_BITFIELD "bitfield" + +/*** +**** +***/ + +static time_t* +getMTimes( const tr_torrent * tor, int * setme_n ) +{ + int i; + const int n = tor->info.fileCount; + time_t * m = tr_new( time_t, n ); + + for( i=0; i<n; ++i ) { + char fname[MAX_PATH_LENGTH]; + struct stat sb; + tr_buildPath( fname, sizeof(fname), + tor->destination, tor->info.files[i].name, NULL ); + if ( !stat( fname, &sb ) && S_ISREG( sb.st_mode ) ) { +#ifdef SYS_DARWIN + m[i] = sb.st_mtimespec.tv_sec; +#else + m[i] = sb.st_mtime; +#endif + } + } + + *setme_n = n; + return m; +} + static void getResumeFilename( char * buf, size_t buflen, const tr_torrent * tor ) { const char * dir = tr_getResumeDir( tor->handle ); char base[4096]; - snprintf( base, sizeof( base ), "%s.%10.10s.resume", tor->info.name, tor->info.hashString ); + snprintf( base, sizeof( base ), "%s.%16.16s.resume", tor->info.name, tor->info.hashString ); tr_buildPath( buf, buflen, dir, base, NULL ); -fprintf( stderr, "filename is [%s]\n", buf ); +} + +/*** +**** +***/ + +static void +savePeers( tr_benc * dict, const tr_torrent * tor ) +{ + tr_pex * pex; + const int count = tr_peerMgrGetPeers( tor->handle->peerMgr, tor->info.hash, &pex ); + if( count > 0 ) { + tr_benc * child = tr_bencDictAdd( dict, KEY_PEERS ); + tr_bencInitStrDupLen( child, (const char*)pex, sizeof(tr_pex)*count ); + tr_free( pex ); + } +} + +static uint64_t +loadPeers( tr_benc * dict, tr_torrent * tor ) +{ + uint64_t ret = 0; + tr_benc * p; + + if(( p = tr_bencDictFindType( dict, KEY_PEERS, TYPE_STR ))) + { + int i; + const char * str = p->val.s.s; + const size_t len = p->val.s.i; + const int count = len / sizeof( tr_pex ); + for( i=0; i<count; ++i ) { + tr_pex pex; + memcpy( &pex, str + (i*sizeof(tr_pex)), sizeof(tr_pex) ); + tr_peerMgrAddPex( tor->handle->peerMgr, tor->info.hash, TR_PEER_FROM_CACHE, &pex ); + } + tr_tordbg( tor, "Loaded %d peers from resume file", count ); + ret = TR_FR_PEERS; + } + + return ret; +} + +static void +savePriorities( tr_benc * dict, const tr_torrent * tor ) +{ + const tr_info * inf = &tor->info; + const tr_file_index_t n = inf->fileCount; + tr_file_index_t i; + tr_benc * list; + + list = tr_bencDictAddList( dict, KEY_PRIORITY, tor->info.fileCount ); + for( i=0; i<n; ++i ) + tr_bencInitInt( tr_bencListAdd( list ), inf->files[i].priority ); +} + +static uint64_t +loadPriorities( tr_benc * dict, tr_torrent * tor ) +{ + uint64_t ret = 0; + tr_info * inf = &tor->info; + const tr_file_index_t n = inf->fileCount; + tr_benc * list; + + if( tr_bencDictFindList( dict, KEY_PRIORITY, &list ) && ( list->val.l.count == (int)n ) ) + { + int64_t tmp; + tr_file_index_t i; + for( i=0; i<n; ++i ) + if( tr_bencGetInt( &list->val.l.vals[i], &tmp ) ) + inf->files[i].priority = tmp; + ret = TR_FR_PRIORITY; + } + + return ret; +} + +static void +saveSpeedLimits( tr_benc * dict, const tr_torrent * tor ) +{ + tr_benc * d = tr_bencDictAddDict( dict, KEY_SPEEDLIMIT, 4 ); + tr_bencDictAddInt( d, KEY_SPEEDLIMIT_DOWN_SPEED, + tr_torrentGetSpeedLimit( tor, TR_DOWN ) ); + tr_bencDictAddInt( d, KEY_SPEEDLIMIT_DOWN_MODE, + tr_torrentGetSpeedMode( tor, TR_DOWN ) ); + tr_bencDictAddInt( d, KEY_SPEEDLIMIT_UP_SPEED, + tr_torrentGetSpeedLimit( tor, TR_UP ) ); + tr_bencDictAddInt( d, KEY_SPEEDLIMIT_UP_MODE, + tr_torrentGetSpeedMode( tor, TR_UP ) ); +} + +static uint64_t +loadSpeedLimits( tr_benc * dict, tr_torrent * tor ) +{ + uint64_t ret = 0; + tr_benc * d; + + if( tr_bencDictFindDict( dict, KEY_SPEEDLIMIT, &d ) ) + { + int64_t i; + if( tr_bencDictFindInt( d, KEY_SPEEDLIMIT_DOWN_SPEED, &i ) ) + tr_torrentSetSpeedLimit( tor, TR_DOWN, i ); + if( tr_bencDictFindInt( d, KEY_SPEEDLIMIT_DOWN_MODE, &i ) ) + tr_torrentSetSpeedMode( tor, TR_DOWN, i ); + if( tr_bencDictFindInt( d, KEY_SPEEDLIMIT_UP_SPEED, &i ) ) + tr_torrentSetSpeedLimit( tor, TR_UP, i ); + if( tr_bencDictFindInt( d, KEY_SPEEDLIMIT_UP_MODE, &i ) ) + tr_torrentSetSpeedMode( tor, TR_UP, i ); + ret = TR_FR_SPEEDLIMIT; + } + + return ret; +} + +static void +saveProgress( tr_benc * dict, const tr_torrent * tor ) +{ + int i; + int n; + time_t * mtimes; + tr_benc * p; + tr_benc * m; + tr_benc * b; + const tr_bitfield * bitfield; + + p = tr_bencDictAdd( dict, KEY_PROGRESS ); + tr_bencInitDict( p, 2 ); + + /* add the mtimes */ + m = tr_bencDictAdd( p, KEY_PROGRESS_MTIMES ); + mtimes = getMTimes( tor, &n ); + tr_bencInitList( m, n ); + for( i=0; i<n; ++i ) { + if( !tr_torrentIsFileChecked( tor, i ) ) + mtimes[i] = ~(time_t)0; /* force a recheck next time */ + tr_bencInitInt( tr_bencListAdd( m ), mtimes[i] ); + } + + /* add the bitfield */ + bitfield = tr_cpBlockBitfield( tor->completion ); + b = tr_bencDictAdd( p, KEY_PROGRESS_BITFIELD ); + tr_bencInitStrDupLen( b, (const char*)bitfield->bits, bitfield->len ); + + /* cleanup */ + tr_free( mtimes ); +} + +static uint64_t +loadProgress( tr_benc * dict, tr_torrent * tor ) +{ + uint64_t ret = 0; + tr_benc * p; + + if( tr_bencDictFindDict( dict, KEY_PROGRESS, &p ) ) + { + tr_benc * m; + tr_benc * b; + int n; + time_t * curMTimes = getMTimes( tor, &n ); + + if( tr_bencDictFindList( p, KEY_PROGRESS_MTIMES, &m ) + && ( m->val.l.count == (int64_t)tor->info.fileCount ) + && ( m->val.l.count == n ) ) + { + int i; + for( i=0; i<m->val.l.count; ++i ) + { + int64_t tmp; + const time_t t = tr_bencGetInt( &m->val.l.vals[i], &tmp ) + ? tmp : ~(time_t)0; + if( curMTimes[i] == t ) + tr_torrentSetFileChecked( tor, i, TRUE ); + else { + tr_torrentSetFileChecked( tor, i, FALSE ); + tr_tordbg( tor, "File #%d needs to be verified", i ); + } + } + } + else + { + tr_torrentUncheck( tor ); + tr_tordbg( tor, "Torrent needs to be verified - unable to find mtimes" ); + } + + if(( b = tr_bencDictFindType( p, KEY_PROGRESS_BITFIELD, TYPE_STR ))) + { + tr_bitfield tmp; + tmp.len = b->val.s.i; + tmp.bits = (uint8_t*) b->val.s.s; + if( tr_cpBlockBitfieldSet( tor->completion, &tmp ) ) { + tr_torrentUncheck( tor ); + tr_tordbg( tor, "Torrent needs to be verified - error loading bitfield" ); + } + } + else + { + tr_torrentUncheck( tor ); + tr_tordbg( tor, "Torrent needs to be verified - unable to find bitfield" ); + } + + tr_free( curMTimes ); + ret = TR_FR_PROGRESS; + } + + return ret; +} + +void +tr_torrentSaveResume( const tr_torrent * tor ) +{ + tr_benc top; + char * encoded; + int len; + + /* populate the bencoded data */ + tr_bencInitDict( &top, 10 ); + tr_bencDictAddInt( &top, KEY_CORRUPT, tor->corruptPrev + tor->corruptCur ); + tr_bencDictAddStr( &top, KEY_DESTINATION, tor->destination ); + tr_bencDictAddInt( &top, KEY_DOWNLOADED, tor->downloadedPrev + tor->downloadedCur ); + tr_bencDictAddInt( &top, KEY_UPLOADED, tor->uploadedPrev + tor->uploadedCur ); + tr_bencDictAddInt( &top, KEY_MAX_PEERS, tor->maxConnectedPeers ); + tr_bencDictAddInt( &top, KEY_PAUSED, tor->isRunning?0:1 ); + savePeers( &top, tor ); + savePriorities( &top, tor ); + saveProgress( &top, tor ); + saveSpeedLimits( &top, tor ); + + /* save the bencoded data */ + if(( encoded = tr_bencSave( &top, &len ))) + { + char filename[MAX_PATH_LENGTH]; + FILE * fp; + getResumeFilename( filename, sizeof( filename ), tor ); + fp = fopen( filename, "wb+" ); + fwrite( encoded, len, 1, fp ); + fclose( fp ); + tr_free( encoded ); + } + + /* cleanup */ + tr_bencFree( &top ); } uint64_t @@ -35,33 +328,65 @@ tr_torrentLoadResume( tr_torrent * tor, uint64_t fieldsToLoad, const tr_ctor * ctor ) { + int64_t i; + const char * str; + int benc_loaded = FALSE; uint64_t fieldsLoaded = 0; - uint8_t * content; + uint8_t * content = NULL; size_t contentLen; char filename[MAX_PATH_LENGTH]; + tr_benc top; getResumeFilename( filename, sizeof( filename ), tor ); + content = tr_loadFile( filename, &contentLen ); - if( content ) - { + benc_loaded = content && !tr_bencLoad( content, contentLen, &top, NULL ); + if( !benc_loaded ) { tr_free( content ); + tr_tordbg( tor, "Couldn't read \"%s\"; trying old resume file format.", filename ); + return tr_fastResumeLoad( tor, fieldsToLoad, ctor ); } - else - { - fieldsLoaded = tr_fastResumeLoad( tor, fieldsToLoad, ctor ); + + tr_tordbg( tor, "Read resume file \"%s\"", filename ); + + if( tr_bencDictFindInt( &top, KEY_CORRUPT, &i ) ) { + tor->corruptPrev = i; + fieldsLoaded |= TR_FR_CORRUPT; } - return fieldsLoaded; -} + if( tr_bencDictFindStr( &top, KEY_DESTINATION, &str ) ) { + tr_free( tor->destination ); + tor->destination = tr_strdup( str ); + fieldsLoaded |= TR_FR_DESTINATION; + } -void -tr_torrentSaveResume( const tr_torrent * tor ) -{ - char filename[MAX_PATH_LENGTH]; - getResumeFilename( filename, sizeof( filename ), tor ); + if( tr_bencDictFindInt( &top, KEY_DOWNLOADED, &i ) ) { + tor->downloadedPrev = i; + fieldsLoaded |= TR_FR_DOWNLOADED; + } + + if( tr_bencDictFindInt( &top, KEY_UPLOADED, &i ) ) { + tor->uploadedPrev = i; + fieldsLoaded |= TR_FR_UPLOADED; + } - /* (temporary) */ - tr_fastResumeSave( tor ); + if( tr_bencDictFindInt( &top, KEY_MAX_PEERS, &i ) ) { + tor->maxConnectedPeers = i; + fieldsLoaded |= TR_FR_MAX_PEERS; + } + + if( tr_bencDictFindInt( &top, KEY_PAUSED, &i ) ) { + tor->isRunning = i ? 0 : 1; + fieldsLoaded |= TR_FR_RUN; + } + + fieldsLoaded |= loadPeers( &top, tor ); + fieldsLoaded |= loadPriorities( &top, tor ); + fieldsLoaded |= loadProgress( &top, tor ); + fieldsLoaded |= loadSpeedLimits( &top, tor ); + + tr_bencFree( &top ); + return fieldsLoaded; } void diff --git a/libtransmission/stats.c b/libtransmission/stats.c index c4e68709c..849334e5f 100644 --- a/libtransmission/stats.c +++ b/libtransmission/stats.c @@ -37,22 +37,22 @@ parseCumulativeStats( tr_session_stats * setme, if( !tr_bencLoad( content, len, &top, NULL ) ) { - const tr_benc * val; + int64_t i; - if(( val = tr_bencDictFindType( &top, "uploaded-bytes", TYPE_INT ))) - setme->uploadedBytes = (uint64_t) tr_bencGetInt( val ); + if( tr_bencDictFindInt( &top, "uploaded-bytes", &i ) ) + setme->uploadedBytes = (uint64_t) i; - if(( val = tr_bencDictFindType( &top, "downloaded-bytes", TYPE_INT ))) - setme->downloadedBytes = (uint64_t) tr_bencGetInt( val ); + if( tr_bencDictFindInt( &top, "downloaded-bytes", &i ) ) + setme->downloadedBytes = (uint64_t) i; - if(( val = tr_bencDictFindType( &top, "files-added", TYPE_INT ))) - setme->filesAdded = (uint64_t) tr_bencGetInt( val ); + if( tr_bencDictFindInt( &top, "files-added", &i ) ) + setme->filesAdded = (uint64_t) i; - if(( val = tr_bencDictFindType( &top, "session-count", TYPE_INT ))) - setme->sessionCount = (uint64_t) tr_bencGetInt( val ); + if( tr_bencDictFindInt( &top, "session-count", &i ) ) + setme->sessionCount = (uint64_t) i; - if(( val = tr_bencDictFindType( &top, "seconds-active", TYPE_INT ))) - setme->secondsActive = (uint64_t) tr_bencGetInt( val ); + if( tr_bencDictFindInt( &top, "seconds-active", &i ) ) + setme->secondsActive = (uint64_t) i; tr_bencFree( &top ); }