From afde752dc0ebba20d7194d3aa8db325fdf0287ba Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 14 Apr 2008 11:52:50 +0000 Subject: [PATCH] 'resume' cleanup --- libtransmission/bencode.c | 55 +++++++++++++- libtransmission/bencode.h | 5 +- libtransmission/metainfo.c | 97 +++++++++++++++---------- libtransmission/metainfo.h | 8 +- libtransmission/resume.c | 145 +++++++++++++++++-------------------- libtransmission/stats.c | 21 ++---- libtransmission/torrent.c | 41 +++++++++-- libtransmission/torrent.h | 2 + 8 files changed, 227 insertions(+), 147 deletions(-) diff --git a/libtransmission/bencode.c b/libtransmission/bencode.c index cdd0ac9dc..e09b3747d 100644 --- a/libtransmission/bencode.c +++ b/libtransmission/bencode.c @@ -313,7 +313,7 @@ tr_bencParse( const void * buf_in, int tr_bencLoad( const void * buf_in, int buflen, - tr_benc * setme_benc, + tr_benc * setme_benc, char ** setme_end ) { const uint8_t * buf = buf_in; @@ -570,6 +570,14 @@ tr_bencListAdd( tr_benc * list ) return item; } +tr_benc * +tr_bencListAddInt( tr_benc * list, int64_t i ) +{ + tr_benc * node = tr_bencListAdd( list ); + tr_bencInitInt( node, i ); + return node; +} + tr_benc * tr_bencDictAdd( tr_benc * dict, const char * key ) { @@ -1051,3 +1059,48 @@ tr_bencSaveAsSerializedPHP( const tr_benc * top, int * len ) evbuffer_free( data.out ); return ret; } + +/*** +**** +***/ + +int +tr_bencSaveFile( const char * filename, const tr_benc * b ) +{ + int ret = TR_OK; + int len; + char * content = tr_bencSave( b, &len ); + FILE * out = NULL; + + out = fopen( filename, "wb+" ); + if( !out ) + { + tr_err( _( "Couldn't open \"%1$s\": %2$s" ), + filename, tr_strerror( errno ) ); + ret = TR_EINVALID; + } + else if( fwrite( content, sizeof( char ), len, out ) != (size_t)len ) + { + tr_err( _( "Couldn't save file \"%1$s\": %2$s" ), + filename, tr_strerror( errno ) ); + ret = TR_EINVALID; + } + + tr_dbg( "tr_bencSaveFile returned %d when saving \"%s\"", ret, filename ); + tr_free( content ); + if( out ) + fclose( out ); + return ret; +} + +int +tr_bencLoadFile( const char * filename, tr_benc * b ) +{ + int ret = TR_ERROR; + size_t contentLen; + uint8_t * content = tr_loadFile( filename, &contentLen ); + ret = content ? tr_bencLoad( content, contentLen, b, NULL ) + : TR_ERROR_IO_OTHER; + tr_free( content ); + return ret; +} diff --git a/libtransmission/bencode.h b/libtransmission/bencode.h index 4c7cfea96..f542c1c59 100644 --- a/libtransmission/bencode.h +++ b/libtransmission/bencode.h @@ -99,6 +99,7 @@ int tr_bencListReserve( tr_benc * list, int count ); /* note that for one key-value pair, count should be 1, not 2 */ int tr_bencDictReserve( tr_benc * dict, int count ); tr_benc * tr_bencListAdd( tr_benc * list ); +tr_benc * tr_bencListAddInt( tr_benc * list, int64_t val ); /* 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_bencDictAddInt( tr_benc * dict, const char * key, int64_t val ); @@ -107,7 +108,9 @@ tr_benc * tr_bencDictAddList( tr_benc * dict, const char * key, int reserveCo 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 ); +char* tr_bencSaveAsSerializedPHP( const tr_benc * top, int * len ); +int tr_bencSaveFile( const char * filename, const tr_benc * ); +int tr_bencLoadFile( const char * filename, tr_benc * ); int tr_bencGetInt( const tr_benc * val, int64_t * setme ); diff --git a/libtransmission/metainfo.c b/libtransmission/metainfo.c index 26dd5bc6d..e36c3ac90 100644 --- a/libtransmission/metainfo.c +++ b/libtransmission/metainfo.c @@ -125,25 +125,64 @@ strlcat_utf8( void * dest, const void * src, size_t len, char skip ) } static void -savedname( const tr_handle * handle, - char * name, - size_t len, - const char * hash ) +getTorrentFilename( const tr_handle * handle, + const tr_info * inf, + char * buf, + size_t buflen ) +{ + const char * dir = tr_getTorrentDir( handle ); + char base[MAX_PATH_LENGTH]; + snprintf( base, sizeof( base ), "%s.%16.16s.torrent", inf->name, inf->hashString ); + tr_buildPath( buf, buflen, dir, base, NULL ); +} + +static void +getTorrentOldFilename( const tr_handle * handle, + const tr_info * info, + char * name, + size_t len ) { const char * torDir = tr_getTorrentDir( handle ); if( !handle->tag ) { - tr_buildPath( name, len, torDir, hash, NULL ); + tr_buildPath( name, len, torDir, info->hashString, NULL ); } else { char base[1024]; - snprintf( base, sizeof(base), "%s-%s", hash, handle->tag ); + snprintf( base, sizeof(base), "%s-%s", info->hashString, handle->tag ); tr_buildPath( name, len, torDir, base, NULL ); } } +void +tr_metainfoMigrate( const tr_handle * handle, + const tr_info * inf ) +{ + struct stat new_sb; + char new_name[MAX_PATH_LENGTH]; + + getTorrentFilename( handle, inf, new_name, sizeof( new_name ) ); + + if( stat( new_name, &new_sb ) || ( ( new_sb.st_mode & S_IFMT ) != S_IFREG ) ) + { + char old_name[MAX_PATH_LENGTH]; + size_t contentLen; + uint8_t * content; + + getTorrentOldFilename( handle, inf, old_name, sizeof( old_name ) ); + if(( content = tr_loadFile( old_name, &contentLen ))) + { + FILE * out = fopen( new_name, "wb+" ); + if( fwrite( content, sizeof( uint8_t ), contentLen, out ) == contentLen ) + unlink( old_name ); + fclose( out ); + } + + tr_free( content ); + } +} int tr_metainfoParse( const tr_handle * handle, @@ -172,9 +211,6 @@ tr_metainfoParse( const tr_handle * handle, } tr_sha1_to_hex( inf->hashString, inf->hash ); - savedname( handle, buf, sizeof( buf ), inf->hashString ); - tr_free( inf->torrent ); - inf->torrent = tr_strdup( buf ); /* comment */ memset( buf, '\0', sizeof( buf ) ); @@ -274,6 +310,12 @@ tr_metainfoParse( const tr_handle * handle, goto fail; } + /* filename of Transmission's copy */ + getTorrentFilename( handle, inf, buf, sizeof( buf ) ); + tr_free( inf->torrent ); + inf->torrent = tr_strdup( buf ); +fprintf( stderr, "inf->torrent is [%s]\n", inf->torrent ); + return TR_OK; fail: @@ -569,40 +611,15 @@ tr_trackerInfoClear( tr_tracker_info * info ) void tr_metainfoRemoveSaved( const tr_handle * handle, - const char * hashString ) + const tr_info * inf ) { - char file[MAX_PATH_LENGTH]; - savedname( handle, file, sizeof file, hashString ); - unlink( file ); -} + char filename[MAX_PATH_LENGTH]; -/* Save a copy of the torrent file in the saved torrent directory */ -int -tr_metainfoSave( const tr_handle * handle, - const char * hash, - const uint8_t * buf, - size_t buflen ) -{ - char path[MAX_PATH_LENGTH]; - FILE * file; + getTorrentFilename( handle, inf, filename, sizeof( filename ) ); + unlink( filename ); - savedname( handle, path, sizeof path, hash ); - file = fopen( path, "wb+" ); - if( !file ) - { - tr_err( _( "Couldn't open \"%1$s\": %2$s" ), path, tr_strerror( errno ) ); - return TR_EINVALID; - } - fseek( file, 0, SEEK_SET ); - if( fwrite( buf, 1, buflen, file ) != buflen ) - { - tr_err( _( "Couldn't save file \"%1$s\": %2$s" ), path, tr_strerror( errno ) ); - fclose( file ); - return TR_EINVALID; - } - fclose( file ); - - return TR_OK; + getTorrentOldFilename( handle, inf, filename, sizeof( filename ) ); + unlink( filename ); } static int diff --git a/libtransmission/metainfo.h b/libtransmission/metainfo.h index e056d7b57..b7dfd0227 100644 --- a/libtransmission/metainfo.h +++ b/libtransmission/metainfo.h @@ -36,11 +36,9 @@ int tr_metainfoParse( const tr_handle * handle, void tr_metainfoFree( tr_info * inf ); void tr_metainfoRemoveSaved( const tr_handle * handle, - const char * hashString ); + const tr_info * info ); -int tr_metainfoSave( const tr_handle * handle, - const char * hashString, - const uint8_t * metainfo, - size_t len ); +void tr_metainfoMigrate( const tr_handle * handle, + const tr_info * inf ); #endif diff --git a/libtransmission/resume.c b/libtransmission/resume.c index 37d04555b..f3d95503f 100644 --- a/libtransmission/resume.c +++ b/libtransmission/resume.c @@ -10,9 +10,7 @@ * $Id:$ */ -#include /* stat */ -#include /* stat */ -#include /* unlink, stat */ +#include /* unlink */ #include @@ -45,41 +43,14 @@ #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; idestination, 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.%16.16s.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 ); } @@ -91,7 +62,8 @@ 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 ); + 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 ); @@ -114,7 +86,8 @@ loadPeers( tr_benc * dict, tr_torrent * tor ) for( i=0; ihandle->peerMgr, tor->info.hash, TR_PEER_FROM_CACHE, &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; @@ -123,6 +96,10 @@ loadPeers( tr_benc * dict, tr_torrent * tor ) return ret; } +/*** +**** +***/ + static void savePriorities( tr_benc * dict, const tr_torrent * tor ) { @@ -144,7 +121,8 @@ loadPriorities( tr_benc * dict, tr_torrent * tor ) const tr_file_index_t n = inf->fileCount; tr_benc * list; - if( tr_bencDictFindList( dict, KEY_PRIORITY, &list ) && ( list->val.l.count == (int)n ) ) + if( tr_bencDictFindList( dict, KEY_PRIORITY, &list ) + && ( list->val.l.count == (int)n ) ) { int64_t tmp; tr_file_index_t i; @@ -157,6 +135,10 @@ loadPriorities( tr_benc * dict, tr_torrent * tor ) return ret; } +/*** +**** +***/ + static void saveSpeedLimits( tr_benc * dict, const tr_torrent * tor ) { @@ -194,6 +176,10 @@ loadSpeedLimits( tr_benc * dict, tr_torrent * tor ) return ret; } +/*** +**** +***/ + static void saveProgress( tr_benc * dict, const tr_torrent * tor ) { @@ -209,13 +195,12 @@ saveProgress( tr_benc * dict, const tr_torrent * tor ) tr_bencInitDict( p, 2 ); /* add the mtimes */ - m = tr_bencDictAdd( p, KEY_PROGRESS_MTIMES ); - mtimes = getMTimes( tor, &n ); - tr_bencInitList( m, n ); + mtimes = tr_torrentGetMTimes( tor, &n ); + m = tr_bencDictAddList( p, KEY_PROGRESS_MTIMES, n ); for( i=0; ival.l.count == (int64_t)tor->info.fileCount ) && ( m->val.l.count == n ) ) { int i; + const time_t recheck = ~(time_t)0; for( i=0; ival.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 ) + int64_t x; + time_t t = tr_bencGetInt( &m->val.l.vals[i], &x ) ? x : recheck; + if( ( t != recheck ) && ( curMTimes[i] == t ) ) tr_torrentSetFileChecked( tor, i, TRUE ); else { tr_torrentSetFileChecked( tor, i, FALSE ); @@ -287,19 +272,24 @@ loadProgress( tr_benc * dict, tr_torrent * tor ) return ret; } +/*** +**** +***/ + void tr_torrentSaveResume( const tr_torrent * tor ) { tr_benc top; - char * encoded; - int len; + char filename[MAX_PATH_LENGTH]; /* 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_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 ); @@ -307,19 +297,9 @@ tr_torrentSaveResume( const tr_torrent * 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 ); - } + getResumeFilename( filename, sizeof( filename ), tor ); + tr_bencSaveFile( filename, &top ); - /* cleanup */ tr_bencFree( &top ); } @@ -330,21 +310,15 @@ tr_torrentLoadResume( tr_torrent * tor, { int64_t i; const char * str; - int benc_loaded = FALSE; uint64_t fieldsLoaded = 0; - 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 ); - benc_loaded = content && !tr_bencLoad( content, contentLen, &top, NULL ); - if( !benc_loaded ) + if( tr_bencLoadFile( filename, &top ) ) { - tr_free( content ); - tr_tordbg( tor, "Couldn't read \"%s\"; trying old resume file format.", filename ); + tr_tordbg( tor, "Couldn't read \"%s\"; trying old format.", filename ); fieldsLoaded = tr_fastResumeLoad( tor, fieldsToLoad, ctor ); if( ( fieldsLoaded != 0 ) && ( fieldsToLoad == ~(uint64_t)0 ) ) @@ -359,41 +333,54 @@ tr_torrentLoadResume( tr_torrent * tor, tr_tordbg( tor, "Read resume file \"%s\"", filename ); - if( tr_bencDictFindInt( &top, KEY_CORRUPT, &i ) ) { + if( ( fieldsToLoad & TR_FR_CORRUPT ) + && tr_bencDictFindInt( &top, KEY_CORRUPT, &i ) ) { tor->corruptPrev = i; fieldsLoaded |= TR_FR_CORRUPT; } - if( tr_bencDictFindStr( &top, KEY_DESTINATION, &str ) ) { + if( ( fieldsToLoad & TR_FR_DESTINATION ) + && tr_bencDictFindStr( &top, KEY_DESTINATION, &str ) ) { tr_free( tor->destination ); tor->destination = tr_strdup( str ); fieldsLoaded |= TR_FR_DESTINATION; } - if( tr_bencDictFindInt( &top, KEY_DOWNLOADED, &i ) ) { + if( ( fieldsToLoad & TR_FR_DOWNLOADED ) + && tr_bencDictFindInt( &top, KEY_DOWNLOADED, &i ) ) { tor->downloadedPrev = i; fieldsLoaded |= TR_FR_DOWNLOADED; } - if( tr_bencDictFindInt( &top, KEY_UPLOADED, &i ) ) { + if( ( fieldsToLoad & TR_FR_UPLOADED ) + && tr_bencDictFindInt( &top, KEY_UPLOADED, &i ) ) { tor->uploadedPrev = i; fieldsLoaded |= TR_FR_UPLOADED; } - if( tr_bencDictFindInt( &top, KEY_MAX_PEERS, &i ) ) { + if( ( fieldsToLoad & TR_FR_MAX_PEERS ) + && tr_bencDictFindInt( &top, KEY_MAX_PEERS, &i ) ) { tor->maxConnectedPeers = i; fieldsLoaded |= TR_FR_MAX_PEERS; } - if( tr_bencDictFindInt( &top, KEY_PAUSED, &i ) ) { + if( ( fieldsToLoad & TR_FR_RUN ) + && 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 ); + if( fieldsToLoad & TR_FR_PEERS ) + fieldsLoaded |= loadPeers( &top, tor ); + + if( fieldsToLoad & TR_FR_PRIORITY ) + fieldsLoaded |= loadPriorities( &top, tor ); + + if( fieldsToLoad & TR_FR_PROGRESS ) + fieldsLoaded |= loadProgress( &top, tor ); + + if( fieldsToLoad & TR_FR_SPEEDLIMIT ) + fieldsLoaded |= loadSpeedLimits( &top, tor ); tr_bencFree( &top ); return fieldsLoaded; diff --git a/libtransmission/stats.c b/libtransmission/stats.c index 849334e5f..44ba24ab2 100644 --- a/libtransmission/stats.c +++ b/libtransmission/stats.c @@ -81,27 +81,20 @@ loadCumulativeStats( const tr_handle * handle, tr_session_stats * setme ) } static void -saveCumulativeStats( const tr_handle * handle, const tr_session_stats * stats ) +saveCumulativeStats( const tr_handle * handle, const tr_session_stats * s ) { - FILE * fp; - char * str; char filename[MAX_PATH_LENGTH]; - int len; tr_benc top; tr_bencInitDict( &top, 5 ); - tr_bencInitInt( tr_bencDictAdd( &top, "uploaded-bytes" ), stats->uploadedBytes ); - tr_bencInitInt( tr_bencDictAdd( &top, "downloaded-bytes" ), stats->downloadedBytes ); - tr_bencInitInt( tr_bencDictAdd( &top, "files-added" ), stats->filesAdded ); - tr_bencInitInt( tr_bencDictAdd( &top, "session-count" ), stats->sessionCount ); - tr_bencInitInt( tr_bencDictAdd( &top, "seconds-active" ), stats->secondsActive ); + tr_bencInitInt( tr_bencDictAdd( &top, "uploaded-bytes" ), s->uploadedBytes ); + tr_bencInitInt( tr_bencDictAdd( &top, "downloaded-bytes" ), s->downloadedBytes ); + tr_bencInitInt( tr_bencDictAdd( &top, "files-added" ), s->filesAdded ); + tr_bencInitInt( tr_bencDictAdd( &top, "session-count" ), s->sessionCount ); + tr_bencInitInt( tr_bencDictAdd( &top, "seconds-active" ), s->secondsActive ); - str = tr_bencSave( &top, &len ); getFilename( handle, filename, sizeof(filename) ); - fp = fopen( filename, "wb+" ); - fwrite( str, 1, len, fp ); - fclose( fp ); - tr_free( str ); + tr_bencSaveFile( filename, &top ); tr_bencFree( &top ); } diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index 17f95a3ee..4a416f182 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -22,6 +22,10 @@ * DEALINGS IN THE SOFTWARE. *****************************************************************************/ +#include /* stat */ +#include /* stat */ +#include /* stat */ + #include #include /* memcmp */ @@ -381,15 +385,13 @@ torrentRealInit( tr_handle * h, if( tr_ctorGetSave( ctor ) ) { const tr_benc * val; if( !tr_ctorGetMetainfo( ctor, &val ) ) { - int len; - uint8_t * text = (uint8_t*) tr_bencSave( val, &len ); - tr_metainfoSave( tor->handle, - tor->info.hashString, - text, len ); - tr_free( text ); + const char * filename = tor->info.torrent; + tr_bencSaveFile( filename, val ); } } + tr_metainfoMigrate( h, &tor->info ); + if( doStart ) tr_torrentStart( tor ); } @@ -812,7 +814,7 @@ tr_torrentSetHasPiece( tr_torrent * tor, tr_piece_index_t pieceIndex, int has ) void tr_torrentRemoveSaved( tr_torrent * tor ) { - tr_metainfoRemoveSaved( tor->handle, tor->info.hashString ); + tr_metainfoRemoveSaved( tor->handle, &tor->info ); tr_torrentRemoveResume( tor ); } @@ -1419,3 +1421,28 @@ tr_torrentCountUncheckedPieces( const tr_torrent * tor ) { return tor->info.pieceCount - tr_bitfieldCountTrueBits( tor->checkedPieces ); } + +time_t* +tr_torrentGetMTimes( 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; idestination, 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; +} diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index 5d06e3051..931ad83ba 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -101,6 +101,8 @@ void tr_torrentSetPieceChecked ( tr_torrent *, tr_piece_index_t piece, int i void tr_torrentSetFileChecked ( tr_torrent *, tr_file_index_t file, int isChecked ); void tr_torrentUncheck ( tr_torrent * ); +time_t* tr_torrentGetMTimes ( const tr_torrent *, int * setmeCount ); + typedef enum { TR_VERIFY_NONE,