diff --git a/libtransmission/Makefile.am b/libtransmission/Makefile.am index 1cbf5e964..d38216db8 100644 --- a/libtransmission/Makefile.am +++ b/libtransmission/Makefile.am @@ -28,6 +28,7 @@ libtransmission_a_SOURCES = \ ptrarray.c \ publish.c \ ratecontrol.c \ + resume.c \ session.c \ stats.c \ torrent.c \ @@ -64,6 +65,7 @@ noinst_HEADERS = \ ptrarray.h \ publish.h \ ratecontrol.h \ + resume.h \ session.h \ stats.h \ torrent.h \ diff --git a/libtransmission/completion.c b/libtransmission/completion.c index bf254e8f8..68d479724 100644 --- a/libtransmission/completion.c +++ b/libtransmission/completion.c @@ -237,19 +237,20 @@ const tr_bitfield * tr_cpBlockBitfield( const tr_completion * cp ) return cp->blockBitfield; } -void +tr_errno tr_cpBlockBitfieldSet( tr_completion * cp, tr_bitfield * bitfield ) { tr_block_index_t i; - assert( cp != NULL ); - assert( bitfield != NULL ); + if( !cp || !bitfield || ( bitfield->len != cp->blockBitfield->len ) ) + return TR_ERROR_ASSERT; tr_cpReset( cp ); - for( i=0; i < cp->tor->blockCount; ++i ) if( tr_bitfieldHas( bitfield, i ) ) tr_cpBlockAdd( cp, i ); + + return 0; } float diff --git a/libtransmission/completion.h b/libtransmission/completion.h index b3a36417a..0194ef37e 100644 --- a/libtransmission/completion.h +++ b/libtransmission/completion.h @@ -53,7 +53,7 @@ void tr_cpPieceRem( tr_completion *, tr_piece_index_t piece ); /* Blocks */ int tr_cpBlockIsComplete( const tr_completion *, tr_block_index_t block ); void tr_cpBlockAdd( tr_completion *, tr_block_index_t block ); -void tr_cpBlockBitfieldSet( tr_completion *, struct tr_bitfield * ); +tr_errno tr_cpBlockBitfieldSet( tr_completion *, struct tr_bitfield * ); float tr_cpPercentBlocksInPiece( const tr_completion * cp, tr_piece_index_t piece ); int tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t piece ); diff --git a/libtransmission/fastresume.c b/libtransmission/fastresume.c index 7c3494106..3ec23417a 100644 --- a/libtransmission/fastresume.c +++ b/libtransmission/fastresume.c @@ -56,6 +56,7 @@ #include "fastresume.h" #include "peer-mgr.h" #include "platform.h" +#include "resume.h" /* TR_FR_ bitwise enum */ #include "torrent.h" #include "utils.h" @@ -115,7 +116,7 @@ enum #define FR_MTIME_LEN( t ) \ ( sizeof(tr_time_t) * (t)->info.fileCount ) #define FR_BLOCK_BITFIELD_LEN( t ) \ - ( ( (t)->blockCount + 7 ) / 8 ) + ( ( (t)->blockCount + 7u ) / 8u ) #define FR_PROGRESS_LEN( t ) \ ( FR_MTIME_LEN( t ) + FR_BLOCK_BITFIELD_LEN( t ) ) #define FR_SPEED_LEN (2 * (sizeof(uint16_t) + sizeof(uint8_t) ) ) @@ -426,9 +427,12 @@ parseProgress( tr_torrent * tor, memset( &bitfield, 0, sizeof bitfield ); bitfield.len = FR_BLOCK_BITFIELD_LEN( tor ); bitfield.bits = (uint8_t*) walk; - tr_cpBlockBitfieldSet( tor->completion, &bitfield ); - - ret = TR_FR_PROGRESS; + if( !tr_cpBlockBitfieldSet( tor->completion, &bitfield ) ) + ret = TR_FR_PROGRESS; + else { + tr_torrentUncheck( tor ); + tr_tordbg( tor, "Torrent needs to be verified" ); + } } /* the files whose mtimes are wrong, diff --git a/libtransmission/fastresume.h b/libtransmission/fastresume.h index 717701517..b62cf231b 100644 --- a/libtransmission/fastresume.h +++ b/libtransmission/fastresume.h @@ -27,20 +27,6 @@ void tr_fastResumeSave( const tr_torrent * tor ); -enum -{ - TR_FR_DOWNLOADED = (1<<0), - TR_FR_UPLOADED = (1<<1), - TR_FR_CORRUPT = (1<<2), - TR_FR_PEERS = (1<<3), - TR_FR_PROGRESS = (1<<4), - TR_FR_PRIORITY = (1<<5), - TR_FR_SPEEDLIMIT = (1<<6), - TR_FR_RUN = (1<<7), - TR_FR_DESTINATION = (1<<8), - TR_FR_MAX_PEERS = (1<<9) -}; - /** * Returns a bitwise-or'ed set of the data loaded from fastresume */ diff --git a/libtransmission/resume.c b/libtransmission/resume.c new file mode 100644 index 000000000..4e0f064cd --- /dev/null +++ b/libtransmission/resume.c @@ -0,0 +1,74 @@ +/* + * This file Copyright (C) 2008 Charles Kerr + * + * This file is licensed by the GPL version 2. Works owned by the + * Transmission project are granted a special exemption to clause 2(b) + * so that the bulk of its code can remain under the MIT license. + * This exemption does not extend to derived works not owned by + * the Transmission project. + * + * $Id:$ + */ + +#include +#include /* unlink */ + +#include "transmission.h" +#include "fastresume.h" +#include "platform.h" /* tr_getResumeDir */ +#include "resume.h" +#include "torrent.h" +#include "utils.h" /* tr_buildPath */ + +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 ); + tr_buildPath( buf, buflen, dir, base, NULL ); +fprintf( stderr, "filename is [%s]\n", buf ); +} + +uint64_t +tr_torrentLoadResume( tr_torrent * tor, + uint64_t fieldsToLoad, + const tr_ctor * ctor ) +{ + uint64_t fieldsLoaded = 0; + uint8_t * content; + size_t contentLen; + char filename[MAX_PATH_LENGTH]; + + getResumeFilename( filename, sizeof( filename ), tor ); + content = tr_loadFile( filename, &contentLen ); + if( content ) + { + tr_free( content ); + } + else + { + fieldsLoaded = tr_fastResumeLoad( tor, fieldsToLoad, ctor ); + } + + return fieldsLoaded; +} + +void +tr_torrentSaveResume( const tr_torrent * tor ) +{ + char filename[MAX_PATH_LENGTH]; + getResumeFilename( filename, sizeof( filename ), tor ); + + /* (temporary) */ + tr_fastResumeSave( tor ); +} + +void +tr_torrentRemoveResume( const tr_torrent * tor ) +{ + char filename[MAX_PATH_LENGTH]; + getResumeFilename( filename, sizeof( filename ), tor ); + unlink( filename ); + tr_fastResumeRemove( tor ); +} diff --git a/libtransmission/resume.h b/libtransmission/resume.h new file mode 100644 index 000000000..b5a11558e --- /dev/null +++ b/libtransmission/resume.h @@ -0,0 +1,41 @@ +/* + * This file Copyright (C) 2008 Charles Kerr + * + * This file is licensed by the GPL version 2. Works owned by the + * Transmission project are granted a special exemption to clause 2(b) + * so that the bulk of its code can remain under the MIT license. + * This exemption does not extend to derived works not owned by + * the Transmission project. + * + * $Id:$ + */ + +#ifndef TR_RESUME_H +#define TR_RESUME_H + +enum +{ + TR_FR_DOWNLOADED = (1<<0), + TR_FR_UPLOADED = (1<<1), + TR_FR_CORRUPT = (1<<2), + TR_FR_PEERS = (1<<3), + TR_FR_PROGRESS = (1<<4), + TR_FR_PRIORITY = (1<<5), + TR_FR_SPEEDLIMIT = (1<<6), + TR_FR_RUN = (1<<7), + TR_FR_DESTINATION = (1<<8), + TR_FR_MAX_PEERS = (1<<9) +}; + +/** + * Returns a bitwise-or'ed set of the loaded resume data + */ +uint64_t tr_torrentLoadResume( tr_torrent * tor, + uint64_t fieldsToLoad, + const tr_ctor * ctor ); + +void tr_torrentSaveResume( const tr_torrent * tor ); + +void tr_torrentRemoveResume( const tr_torrent * tor ); + +#endif diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index 6687d5acf..17f95a3ee 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -29,7 +29,7 @@ #include "bencode.h" #include "completion.h" #include "crypto.h" /* for tr_sha1 */ -#include "fastresume.h" +#include "resume.h" #include "fdlimit.h" /* tr_fdFileClose */ #include "metainfo.h" #include "peer-mgr.h" @@ -353,7 +353,7 @@ torrentRealInit( tr_handle * h, tor->checkedPieces = tr_bitfieldNew( tor->info.pieceCount ); tr_torrentUncheck( tor ); - loaded = tr_fastResumeLoad( tor, ~0, ctor ); + loaded = tr_torrentLoadResume( tor, ~0, ctor ); doStart = tor->isRunning; tor->isRunning = 0; @@ -457,16 +457,6 @@ tr_torrentNew( tr_handle * handle, return tor; } -/*** -**** -***/ - -static void -saveFastResumeNow( tr_torrent * tor ) -{ - tr_fastResumeSave( tor ); -} - /** *** **/ @@ -476,7 +466,7 @@ tr_torrentSetFolder( tr_torrent * tor, const char * path ) { tr_free( tor->destination ); tor->destination = tr_strdup( path ); - saveFastResumeNow( tor ); + tr_torrentSaveResume( tor ); } const char* @@ -824,7 +814,7 @@ tr_torrentRemoveSaved( tr_torrent * tor ) { tr_metainfoRemoveSaved( tor->handle, tor->info.hashString ); - tr_fastResumeRemove( tor ); + tr_torrentRemoveResume( tor ); } /*** @@ -921,7 +911,7 @@ checkAndStartImpl( void * vtor ) *tor->errorString = '\0'; tr_torrentResetTransferStats( tor ); tor->cpStatus = tr_cpGetStatus( tor->completion ); - saveFastResumeNow( tor ); + tr_torrentSaveResume( tor ); tor->startDate = tr_date( ); tr_trackerStart( tor->tracker ); tr_peerMgrStartTorrent( tor->handle->peerMgr, tor->info.hash ); @@ -942,7 +932,7 @@ tr_torrentStart( tr_torrent * tor ) if( !tor->isRunning ) { - tr_fastResumeLoad( tor, TR_FR_PROGRESS, NULL ); + tr_torrentLoadResume( tor, TR_FR_PROGRESS, NULL ); tor->isRunning = 1; tr_verifyAdd( tor, checkAndStartCB ); } @@ -999,7 +989,7 @@ tr_torrentStop( tr_torrent * tor ) tr_globalLock( tor->handle ); if( !tor->isDeleting ) - saveFastResumeNow( tor ); + tr_torrentSaveResume( tor ); tor->isRunning = 0; tr_runInEventThread( tor->handle, stopTorrent, tor ); @@ -1010,7 +1000,7 @@ static void closeTorrent( void * vtor ) { tr_torrent * tor = vtor; - saveFastResumeNow( tor ); + tr_torrentSaveResume( tor ); tor->isRunning = 0; stopTorrent( tor ); if( tor->isDeleting ) @@ -1112,7 +1102,7 @@ tr_torrentRecheckCompleteness( tr_torrent * tor ) if( recentChange && ( cpStatus == TR_CP_COMPLETE ) ) tr_trackerCompleted( tor->tracker ); - saveFastResumeNow( tor ); + tr_torrentSaveResume( tor ); } tr_torrentUnlock( tor ); @@ -1158,7 +1148,7 @@ tr_torrentSetFilePriorities( tr_torrent * tor, for( i=0; i