mirror of
https://github.com/transmission/transmission
synced 2025-02-24 23:12:35 +00:00
get tr_ctorSetMetainfoFromHash() working again.
This commit is contained in:
parent
bc5838e75e
commit
e4f6b9592d
7 changed files with 213 additions and 64 deletions
|
@ -157,8 +157,8 @@ getTorrentOldFilename( const tr_handle * handle,
|
|||
}
|
||||
|
||||
void
|
||||
tr_metainfoMigrate( const tr_handle * handle,
|
||||
const tr_info * inf )
|
||||
tr_metainfoMigrate( tr_handle * handle,
|
||||
tr_info * inf )
|
||||
{
|
||||
struct stat new_sb;
|
||||
char new_name[MAX_PATH_LENGTH];
|
||||
|
@ -176,7 +176,12 @@ tr_metainfoMigrate( const tr_handle * handle,
|
|||
{
|
||||
FILE * out = fopen( new_name, "wb+" );
|
||||
if( fwrite( content, sizeof( uint8_t ), contentLen, out ) == contentLen )
|
||||
{
|
||||
tr_free( inf->torrent );
|
||||
inf->torrent = tr_strdup( new_name );
|
||||
tr_sessionSetTorrentFile( handle, inf->hashString, new_name );
|
||||
unlink( old_name );
|
||||
}
|
||||
fclose( out );
|
||||
}
|
||||
|
||||
|
@ -314,7 +319,6 @@ tr_metainfoParse( const tr_handle * handle,
|
|||
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;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ void tr_metainfoFree( tr_info * inf );
|
|||
void tr_metainfoRemoveSaved( const tr_handle * handle,
|
||||
const tr_info * info );
|
||||
|
||||
void tr_metainfoMigrate( const tr_handle * handle,
|
||||
const tr_info * inf );
|
||||
void tr_metainfoMigrate( tr_handle * handle,
|
||||
tr_info * inf );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#define KEY_SPEEDLIMIT_UP_SPEED "up-speed"
|
||||
#define KEY_SPEEDLIMIT_UP_MODE "up-mode"
|
||||
|
||||
#define KEY_PROGRESS_MTIMES "mtimes"
|
||||
#define KEY_PROGRESS_MTIMES "mtimes"
|
||||
#define KEY_PROGRESS_BITFIELD "bitfield"
|
||||
|
||||
static void
|
||||
|
@ -61,14 +61,13 @@ getResumeFilename( char * buf, size_t buflen, const tr_torrent * tor )
|
|||
static void
|
||||
savePeers( tr_benc * dict, const tr_torrent * tor )
|
||||
{
|
||||
tr_pex * pex;
|
||||
tr_pex * pex = NULL;
|
||||
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 );
|
||||
}
|
||||
if( count > 0 )
|
||||
tr_bencInitStrDupLen( tr_bencDictAdd( dict, KEY_PEERS ),
|
||||
(const char*)pex, sizeof(tr_pex)*count );
|
||||
tr_free( pex );
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
|
@ -180,6 +179,8 @@ loadSpeedLimits( tr_benc * dict, tr_torrent * tor )
|
|||
****
|
||||
***/
|
||||
|
||||
static const time_t verifyNeeded = ~(time_t)0;
|
||||
|
||||
static void
|
||||
saveProgress( tr_benc * dict, const tr_torrent * tor )
|
||||
{
|
||||
|
@ -197,11 +198,9 @@ saveProgress( tr_benc * dict, const tr_torrent * tor )
|
|||
/* add the mtimes */
|
||||
mtimes = tr_torrentGetMTimes( tor, &n );
|
||||
m = tr_bencDictAddList( p, KEY_PROGRESS_MTIMES, n );
|
||||
for( i=0; i<n; ++i ) {
|
||||
if( !tr_torrentIsFileChecked( tor, i ) )
|
||||
mtimes[i] = ~(time_t)0; /* force a recheck next time */
|
||||
tr_bencListAddInt( m, mtimes[i] );
|
||||
}
|
||||
for( i=0; i<n; ++i )
|
||||
tr_bencListAddInt( m, tr_torrentIsFileChecked( tor, i )
|
||||
? mtimes[i] : verifyNeeded );
|
||||
|
||||
/* add the bitfield */
|
||||
bitfield = tr_cpBlockBitfield( tor->completion );
|
||||
|
@ -230,12 +229,12 @@ loadProgress( tr_benc * dict, tr_torrent * tor )
|
|||
&& ( m->val.l.count == n ) )
|
||||
{
|
||||
int i;
|
||||
const time_t recheck = ~(time_t)0;
|
||||
for( i=0; i<m->val.l.count; ++i )
|
||||
{
|
||||
int64_t x;
|
||||
time_t t = tr_bencGetInt( &m->val.l.vals[i], &x ) ? x : recheck;
|
||||
if( ( t != recheck ) && ( curMTimes[i] == t ) )
|
||||
const time_t t = tr_bencGetInt( &m->val.l.vals[i], &x )
|
||||
? x : verifyNeeded;
|
||||
if( ( t != verifyNeeded ) && ( t == curMTimes[i] ) )
|
||||
tr_torrentSetFileChecked( tor, i, TRUE );
|
||||
else {
|
||||
tr_torrentSetFileChecked( tor, i, FALSE );
|
||||
|
@ -282,16 +281,19 @@ tr_torrentSaveResume( const tr_torrent * tor )
|
|||
tr_benc top;
|
||||
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_CORRUPT,
|
||||
tor->corruptPrev + tor->corruptCur );
|
||||
tr_bencDictAddStr( &top, KEY_DESTINATION,
|
||||
tor->destination );
|
||||
tr_bencDictAddInt( &top, KEY_DOWNLOADED,
|
||||
tor->downloadedPrev + tor->downloadedCur );
|
||||
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 );
|
||||
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 );
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "blocklist.h"
|
||||
#include "fdlimit.h"
|
||||
#include "list.h"
|
||||
#include "metainfo.h" /* tr_metainfoFree */
|
||||
#include "net.h"
|
||||
#include "peer-mgr.h"
|
||||
#include "platform.h" /* tr_lock */
|
||||
|
@ -113,6 +114,8 @@ tr_setEncryptionMode( tr_handle * handle, tr_encryption_mode mode )
|
|||
****
|
||||
***/
|
||||
|
||||
static void metainfoLookupRescan( tr_handle * h );
|
||||
|
||||
tr_handle *
|
||||
tr_initFull( const char * configDir,
|
||||
const char * tag,
|
||||
|
@ -194,6 +197,8 @@ tr_initFull( const char * configDir,
|
|||
|
||||
tr_statsInit( h );
|
||||
|
||||
metainfoLookupRescan( h );
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
@ -463,7 +468,7 @@ tr_loadTorrents ( tr_handle * h,
|
|||
tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
|
||||
tr_ctorSetMetainfoFromFile( ctor, filename );
|
||||
tor = tr_torrentNew( h, ctor, NULL );
|
||||
if( tor != NULL ) {
|
||||
if( tor ) {
|
||||
tr_list_append( &list, tor );
|
||||
n++;
|
||||
}
|
||||
|
@ -541,3 +546,130 @@ tr_blocklistHasAddress( tr_handle * handle, const struct in_addr * addr )
|
|||
{
|
||||
return _tr_blocklistHasAddress( handle->blocklist, addr );
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
static int
|
||||
compareLookupEntries( const void * va, const void * vb )
|
||||
{
|
||||
const struct tr_metainfo_lookup * a = va;
|
||||
const struct tr_metainfo_lookup * b = vb;
|
||||
return strcmp( a->hashString, b->hashString );
|
||||
}
|
||||
|
||||
static void
|
||||
metainfoLookupResort( tr_handle * h )
|
||||
{
|
||||
qsort( h->metainfoLookup,
|
||||
h->metainfoLookupCount,
|
||||
sizeof( struct tr_metainfo_lookup ),
|
||||
compareLookupEntries );
|
||||
}
|
||||
|
||||
static int
|
||||
compareHashStringToLookupEntry( const void * va, const void * vb )
|
||||
{
|
||||
const char * a = va;
|
||||
const struct tr_metainfo_lookup * b = vb;
|
||||
return strcmp( a, b->hashString );
|
||||
}
|
||||
|
||||
const char*
|
||||
tr_sessionFindTorrentFile( const tr_handle * h,
|
||||
const char * hashStr )
|
||||
{
|
||||
struct tr_metainfo_lookup * l = bsearch( hashStr,
|
||||
h->metainfoLookup,
|
||||
h->metainfoLookupCount,
|
||||
sizeof( struct tr_metainfo_lookup ),
|
||||
compareHashStringToLookupEntry );
|
||||
return l ? l->filename : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
metainfoLookupRescan( tr_handle * h )
|
||||
{
|
||||
int i;
|
||||
int n;
|
||||
struct stat sb;
|
||||
const char * dirname = tr_getTorrentDir( h );
|
||||
DIR * odir = NULL;
|
||||
tr_ctor * ctor = NULL;
|
||||
tr_list * list = NULL;
|
||||
|
||||
/* walk through the directory and find the mappings */
|
||||
ctor = tr_ctorNew( h );
|
||||
tr_ctorSetSave( ctor, FALSE ); /* since we already have them */
|
||||
if( !stat( dirname, &sb ) && S_ISDIR( sb.st_mode ) && (( odir = opendir( dirname ))))
|
||||
{
|
||||
struct dirent *d;
|
||||
for (d = readdir( odir ); d!=NULL; d=readdir( odir ) )
|
||||
{
|
||||
if( d->d_name && d->d_name[0]!='.' ) /* skip dotfiles, ., and .. */
|
||||
{
|
||||
tr_info inf;
|
||||
char filename[MAX_PATH_LENGTH];
|
||||
tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
|
||||
tr_ctorSetMetainfoFromFile( ctor, filename );
|
||||
if( !tr_torrentParse( h, ctor, &inf ) )
|
||||
{
|
||||
tr_list_append( &list, tr_strdup( inf.hashString ) );
|
||||
tr_list_append( &list, tr_strdup( filename ) );
|
||||
tr_metainfoFree( &inf );
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir( odir );
|
||||
}
|
||||
tr_ctorFree( ctor );
|
||||
|
||||
n = tr_list_size( list ) / 2;
|
||||
h->metainfoLookup = tr_new0( struct tr_metainfo_lookup, n );
|
||||
h->metainfoLookupCount = n;
|
||||
for( i=0; i<n; ++i )
|
||||
{
|
||||
char * hashString = tr_list_pop_front( &list );
|
||||
char * filename = tr_list_pop_front( &list );
|
||||
|
||||
memcpy( h->metainfoLookup[i].hashString, hashString, 2*SHA_DIGEST_LENGTH+1 );
|
||||
tr_free( hashString );
|
||||
h->metainfoLookup[i].filename = filename;
|
||||
}
|
||||
|
||||
metainfoLookupResort( h );
|
||||
tr_dbg( "Found %d torrents in \"%s\"", n, dirname );
|
||||
}
|
||||
|
||||
void
|
||||
tr_sessionSetTorrentFile( tr_handle * h,
|
||||
const char * hashString,
|
||||
const char * filename )
|
||||
{
|
||||
struct tr_metainfo_lookup * l = bsearch( hashString,
|
||||
h->metainfoLookup,
|
||||
h->metainfoLookupCount,
|
||||
sizeof( struct tr_metainfo_lookup ),
|
||||
compareHashStringToLookupEntry );
|
||||
if( l != NULL )
|
||||
{
|
||||
if( l->filename != filename )
|
||||
{
|
||||
tr_free( l->filename );
|
||||
l->filename = tr_strdup( filename );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const int n = h->metainfoLookupCount++;
|
||||
struct tr_metainfo_lookup * node;
|
||||
h->metainfoLookup = tr_renew( struct tr_metainfo_lookup,
|
||||
h->metainfoLookup,
|
||||
h->metainfoLookupCount );
|
||||
node = h->metainfoLookup + n;
|
||||
memcpy( node->hashString, hashString, 2*SHA_DIGEST_LENGTH+1 );
|
||||
node->filename = tr_strdup( filename );
|
||||
metainfoLookupResort( h );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,43 +53,59 @@ uint8_t* tr_peerIdNew( void );
|
|||
|
||||
const uint8_t* tr_getPeerId( void );
|
||||
|
||||
struct tr_metainfo_lookup
|
||||
{
|
||||
char hashString[2*SHA_DIGEST_LENGTH+1];
|
||||
char * filename;
|
||||
};
|
||||
|
||||
const char * tr_sessionFindTorrentFile( const tr_handle * h,
|
||||
const char * hashString );
|
||||
|
||||
void tr_sessionSetTorrentFile( tr_handle * h,
|
||||
const char * hashString,
|
||||
const char * filename );
|
||||
|
||||
struct tr_handle
|
||||
{
|
||||
unsigned int isPortSet : 1;
|
||||
unsigned int isPexEnabled : 1;
|
||||
unsigned int isClosed : 1;
|
||||
unsigned int useUploadLimit : 1;
|
||||
unsigned int useDownloadLimit : 1;
|
||||
unsigned int isPortSet : 1;
|
||||
unsigned int isPexEnabled : 1;
|
||||
unsigned int isClosed : 1;
|
||||
unsigned int useUploadLimit : 1;
|
||||
unsigned int useDownloadLimit : 1;
|
||||
|
||||
tr_encryption_mode encryptionMode;
|
||||
tr_encryption_mode encryptionMode;
|
||||
|
||||
struct tr_event_handle * events;
|
||||
struct tr_event_handle * events;
|
||||
|
||||
int peerSocketTOS;
|
||||
int peerSocketTOS;
|
||||
|
||||
int torrentCount;
|
||||
tr_torrent * torrentList;
|
||||
int torrentCount;
|
||||
tr_torrent * torrentList;
|
||||
|
||||
char * tag;
|
||||
char * tag;
|
||||
|
||||
char * configDir;
|
||||
char * torrentDir;
|
||||
char * resumeDir;
|
||||
char * configDir;
|
||||
char * torrentDir;
|
||||
char * resumeDir;
|
||||
|
||||
struct tr_ratecontrol * upload;
|
||||
struct tr_ratecontrol * download;
|
||||
struct tr_ratecontrol * upload;
|
||||
struct tr_ratecontrol * download;
|
||||
|
||||
struct tr_blocklist * blocklist;
|
||||
struct tr_peerMgr * peerMgr;
|
||||
struct tr_shared * shared;
|
||||
struct tr_blocklist * blocklist;
|
||||
struct tr_peerMgr * peerMgr;
|
||||
struct tr_shared * shared;
|
||||
|
||||
struct tr_lock * lock;
|
||||
struct tr_lock * lock;
|
||||
|
||||
tr_handle_status stats[2];
|
||||
int statCur;
|
||||
tr_handle_status stats[2];
|
||||
int statCur;
|
||||
|
||||
struct tr_stats_handle * sessionStats;
|
||||
struct tr_tracker_handle * tracker;
|
||||
struct tr_stats_handle * sessionStats;
|
||||
struct tr_tracker_handle * tracker;
|
||||
|
||||
struct tr_metainfo_lookup * metainfoLookup;
|
||||
int metainfoLookupCount;
|
||||
};
|
||||
|
||||
void tr_globalLock ( struct tr_handle * );
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "transmission.h"
|
||||
#include "bencode.h"
|
||||
#include "platform.h"
|
||||
#include "session.h" /* tr_sessionFindTorrentFile */
|
||||
#include "trcompat.h" /* strlcpy */
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -125,20 +126,13 @@ int
|
|||
tr_ctorSetMetainfoFromHash( tr_ctor * ctor,
|
||||
const char * hashString )
|
||||
{
|
||||
int err = -1;
|
||||
char basename[2048];
|
||||
char filename[MAX_PATH_LENGTH];
|
||||
int err;
|
||||
const char * filename;
|
||||
|
||||
if( err && ( ctor->handle->tag != NULL ) ) {
|
||||
snprintf( basename, sizeof(basename), "%s-%s", hashString, ctor->handle->tag );
|
||||
tr_buildPath( filename, sizeof(filename), tr_getTorrentDir( ctor->handle ), basename, NULL );
|
||||
err = tr_ctorSetMetainfoFromFile( ctor, filename );
|
||||
}
|
||||
|
||||
if( err ) {
|
||||
tr_buildPath( filename, sizeof(filename), tr_getTorrentDir( ctor->handle ), hashString, NULL );
|
||||
err = tr_ctorSetMetainfoFromFile( ctor, filename );
|
||||
}
|
||||
if(( filename = tr_sessionFindTorrentFile( ctor->handle, hashString )))
|
||||
err = tr_ctorSetMetainfoFromFile( ctor, filename );
|
||||
else
|
||||
err = TR_ERROR;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -387,6 +387,7 @@ torrentRealInit( tr_handle * h,
|
|||
if( !tr_ctorGetMetainfo( ctor, &val ) ) {
|
||||
const char * filename = tor->info.torrent;
|
||||
tr_bencSaveFile( filename, val );
|
||||
tr_sessionSetTorrentFile( tor->handle, tor->info.hashString, filename );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue