Merge r1634 to trunk.
This commit is contained in:
parent
5b6ac5744c
commit
7e03349f76
|
@ -29,10 +29,10 @@
|
|||
/***********************************************************************
|
||||
* Local prototypes
|
||||
**********************************************************************/
|
||||
static int realparse( tr_info_t * inf, uint8_t * buf, size_t len );
|
||||
static void savedname( char * name, size_t len, const char * hash,
|
||||
const char * tag );
|
||||
static char * readtorrent( const char * path, const char * hash,
|
||||
const char * tag, size_t * len );
|
||||
static char * readtorrent( const char * path, size_t * len );
|
||||
static int savetorrent( const char * hash, const char * tag,
|
||||
const uint8_t * buf, size_t buflen );
|
||||
static int getfile( char * buf, int size,
|
||||
|
@ -48,30 +48,121 @@ static void strcatUTF8( char *, int, const char *, int );
|
|||
***********************************************************************
|
||||
*
|
||||
**********************************************************************/
|
||||
int tr_metainfoParse( tr_info_t * inf, const char * tag, const char * path,
|
||||
const char * savedHash, int saveCopy )
|
||||
int
|
||||
tr_metainfoParseFile( tr_info_t * inf, const char * tag,
|
||||
const char * path, int save )
|
||||
{
|
||||
char * buf;
|
||||
benc_val_t meta, * beInfo, * val, * val2;
|
||||
int i;
|
||||
size_t len;
|
||||
|
||||
assert( NULL == path || NULL == savedHash );
|
||||
/* if savedHash isn't null, saveCopy should be false */
|
||||
assert( NULL == savedHash || !saveCopy );
|
||||
uint8_t * buf;
|
||||
size_t size;
|
||||
|
||||
/* read the torrent data */
|
||||
buf = readtorrent( path, savedHash, tag, &len );
|
||||
buf = readtorrent( path, &size );
|
||||
if( NULL == buf )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( realparse( inf, buf, size ) )
|
||||
{
|
||||
free( buf );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( save )
|
||||
{
|
||||
if( savetorrent( inf->hashString, tag, buf, size ) )
|
||||
{
|
||||
free( buf );
|
||||
return 1;
|
||||
}
|
||||
savedname( inf->torrent, sizeof inf->torrent, inf->hashString, tag );
|
||||
}
|
||||
|
||||
free( buf );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tr_metainfoParseData( tr_info_t * inf, const char * tag,
|
||||
uint8_t * data, size_t size, int save )
|
||||
{
|
||||
if( realparse( inf, data, size ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( save )
|
||||
{
|
||||
if( savetorrent( inf->hashString, tag, data, size ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
savedname( inf->torrent, sizeof inf->torrent, inf->hashString, tag );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tr_metainfoParseHash( tr_info_t * inf, const char * tag, const char * hash )
|
||||
{
|
||||
struct stat sb;
|
||||
uint8_t * buf;
|
||||
size_t size;
|
||||
int save;
|
||||
|
||||
/* check it we should use an old file without a tag */
|
||||
/* XXX this should go away at some point */
|
||||
save = 0;
|
||||
savedname( inf->torrent, sizeof inf->torrent, hash, tag );
|
||||
if( 0 > stat( inf->torrent, &sb ) && ENOENT == errno )
|
||||
{
|
||||
savedname( inf->torrent, sizeof inf->torrent, hash, NULL );
|
||||
if( 0 == stat( inf->torrent, &sb ))
|
||||
{
|
||||
save = 1;
|
||||
}
|
||||
}
|
||||
|
||||
buf = readtorrent( inf->torrent, &size );
|
||||
if( NULL == buf )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( realparse( inf, buf, size ) )
|
||||
{
|
||||
free( buf );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* save a new tagged copy of the old untagged torrent */
|
||||
if( save )
|
||||
{
|
||||
if( savetorrent( hash, tag, buf, size ) )
|
||||
{
|
||||
free( buf );
|
||||
return 1;
|
||||
}
|
||||
savedname( inf->torrent, sizeof inf->torrent, hash, tag );
|
||||
}
|
||||
|
||||
free( buf );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
realparse( tr_info_t * inf, uint8_t * buf, size_t size )
|
||||
{
|
||||
benc_val_t meta, * beInfo, * val, * val2;
|
||||
int i;
|
||||
|
||||
/* Parse bencoded infos */
|
||||
if( tr_bencLoad( buf, len, &meta, NULL ) )
|
||||
if( tr_bencLoad( buf, size, &meta, NULL ) )
|
||||
{
|
||||
tr_err( "Error while parsing bencoded data" );
|
||||
free( buf );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -81,7 +172,6 @@ int tr_metainfoParse( tr_info_t * inf, const char * tag, const char * path,
|
|||
{
|
||||
tr_err( "%s \"info\" dictionary", ( beInfo ? "Invalid" : "Missing" ) );
|
||||
tr_bencFree( &meta );
|
||||
free( buf );
|
||||
return 1;
|
||||
}
|
||||
SHA1( (uint8_t *) beInfo->begin,
|
||||
|
@ -92,30 +182,6 @@ int tr_metainfoParse( tr_info_t * inf, const char * tag, const char * path,
|
|||
"%02x", inf->hash[i] );
|
||||
}
|
||||
|
||||
/* Save a copy of the torrent file */
|
||||
if( saveCopy )
|
||||
{
|
||||
if( savetorrent( inf->hashString, tag, (uint8_t *) buf, len ) )
|
||||
{
|
||||
tr_bencFree( &meta );
|
||||
free( buf );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* We won't need this anymore */
|
||||
free( buf );
|
||||
|
||||
/* Torrent file name */
|
||||
if( NULL == path || saveCopy )
|
||||
{
|
||||
savedname( inf->torrent, sizeof inf->torrent, inf->hashString, tag );
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( inf->torrent, MAX_PATH_LENGTH, "%s", path );
|
||||
}
|
||||
|
||||
/* Comment info */
|
||||
val = tr_bencDictFindFirst( &meta, "comment.utf-8", "comment", NULL );
|
||||
if( NULL != val && TYPE_STR == val->type )
|
||||
|
@ -468,41 +534,17 @@ void tr_metainfoRemoveSaved( const char * hashString, const char * tag )
|
|||
unlink(file);
|
||||
}
|
||||
|
||||
char * readtorrent( const char * path, const char * hash, const char * tag,
|
||||
size_t * len )
|
||||
char * readtorrent( const char * path, size_t * size )
|
||||
{
|
||||
char hashpath[MAX_PATH_LENGTH], * buf;
|
||||
char * buf;
|
||||
struct stat sb;
|
||||
FILE * file;
|
||||
int lasterr, save;
|
||||
|
||||
if( NULL != hash )
|
||||
{
|
||||
savedname( hashpath, sizeof hashpath, hash, tag );
|
||||
path = hashpath;
|
||||
}
|
||||
|
||||
/* try to stat the file */
|
||||
save = 0;
|
||||
if( stat( path, &sb ) )
|
||||
{
|
||||
if( ENOENT != errno || NULL == hash )
|
||||
{
|
||||
tr_err( "Could not stat file (%s)", path );
|
||||
return NULL;
|
||||
}
|
||||
/* it doesn't exist, check for an old file without a tag */
|
||||
/* XXX this should go away at some point */
|
||||
lasterr = errno;
|
||||
savedname( hashpath, sizeof hashpath, hash, NULL );
|
||||
if( stat( path, &sb ) )
|
||||
{
|
||||
savedname( hashpath, sizeof hashpath, hash, tag );
|
||||
errno = lasterr;
|
||||
tr_err( "Could not stat file (%s)", path );
|
||||
return NULL;
|
||||
}
|
||||
save = 1;
|
||||
tr_err( "Could not stat file (%s)", path );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( ( sb.st_mode & S_IFMT ) != S_IFREG )
|
||||
|
@ -512,7 +554,8 @@ char * readtorrent( const char * path, const char * hash, const char * tag,
|
|||
}
|
||||
if( sb.st_size > TORRENT_MAX_SIZE )
|
||||
{
|
||||
tr_err( "Torrent file is too big (%d bytes)", ( int )sb.st_size );
|
||||
tr_err( "Torrent file is too big (%"PRIu64" bytes)",
|
||||
( uint64_t )sb.st_size );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -526,7 +569,8 @@ char * readtorrent( const char * path, const char * hash, const char * tag,
|
|||
buf = malloc( sb.st_size );
|
||||
if( NULL == buf )
|
||||
{
|
||||
tr_err( "Could not allocate memory (%d bytes)", ( int )sb.st_size );
|
||||
tr_err( "Could not allocate memory (%"PRIu64" bytes)",
|
||||
( uint64_t )sb.st_size );
|
||||
}
|
||||
fseek( file, 0, SEEK_SET );
|
||||
if( fread( buf, sb.st_size, 1, file ) != 1 )
|
||||
|
@ -538,13 +582,7 @@ char * readtorrent( const char * path, const char * hash, const char * tag,
|
|||
}
|
||||
fclose( file );
|
||||
|
||||
/* save a new tagged copy of the old untagged torrent */
|
||||
if( save )
|
||||
{
|
||||
savetorrent( hash, tag, (uint8_t *) buf, sb.st_size );
|
||||
}
|
||||
|
||||
*len = sb.st_size;
|
||||
*size = sb.st_size;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,11 @@
|
|||
|
||||
#include "transmission.h"
|
||||
|
||||
int tr_metainfoParse( tr_info_t *, const char * tag, const char * path,
|
||||
const char * savedHash, int saveCopy );
|
||||
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 );
|
||||
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 );
|
||||
|
||||
|
|
|
@ -53,14 +53,22 @@ void tr_setDownloadLimit( tr_torrent_t * tor, int limit )
|
|||
tr_rcSetLimit( tor->download, limit );
|
||||
}
|
||||
|
||||
tr_torrent_t * tr_torrentInit( tr_handle_t * h, const char * path,
|
||||
uint8_t * hash, int flags, int * error )
|
||||
tr_torrent_t *
|
||||
tr_torrentInit( tr_handle_t * h, const char * path,
|
||||
uint8_t * hash, int flags, int * error )
|
||||
{
|
||||
tr_torrent_t * tor = calloc( sizeof( tr_torrent_t ), 1 );
|
||||
int saveCopy = ( TR_FLAG_SAVE & flags );
|
||||
tr_torrent_t * tor;
|
||||
|
||||
tor = calloc( 1, sizeof *tor );
|
||||
if( NULL == tor )
|
||||
{
|
||||
*error = TR_EOTHER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse torrent file */
|
||||
if( tr_metainfoParse( &tor->info, h->tag, path, NULL, saveCopy ) )
|
||||
if( tr_metainfoParseFile( &tor->info, h->tag, path,
|
||||
TR_FLAG_SAVE & flags ) )
|
||||
{
|
||||
*error = TR_EINVALID;
|
||||
free( tor );
|
||||
|
@ -70,13 +78,46 @@ tr_torrent_t * tr_torrentInit( tr_handle_t * h, const char * path,
|
|||
return torrentRealInit( h, tor, hash, flags, error );
|
||||
}
|
||||
|
||||
tr_torrent_t * tr_torrentInitSaved( tr_handle_t * h, const char * hashStr,
|
||||
int flags, int * error )
|
||||
tr_torrent_t *
|
||||
tr_torrentInitData( tr_handle_t * h, uint8_t * data, size_t size,
|
||||
uint8_t * hash, int flags, int * error )
|
||||
{
|
||||
tr_torrent_t * tor = calloc( sizeof( tr_torrent_t ), 1 );
|
||||
tr_torrent_t * tor;
|
||||
|
||||
tor = calloc( 1, sizeof *tor );
|
||||
if( NULL == tor )
|
||||
{
|
||||
*error = TR_EOTHER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse torrent file */
|
||||
if( tr_metainfoParse( &tor->info, h->tag, NULL, hashStr, 0 ) )
|
||||
if( tr_metainfoParseData( &tor->info, h->tag, data, size,
|
||||
TR_FLAG_SAVE & flags ) )
|
||||
{
|
||||
*error = TR_EINVALID;
|
||||
free( tor );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return torrentRealInit( h, tor, hash, flags, error );
|
||||
}
|
||||
|
||||
tr_torrent_t *
|
||||
tr_torrentInitSaved( tr_handle_t * h, const char * hashStr,
|
||||
int flags, int * error )
|
||||
{
|
||||
tr_torrent_t * tor;
|
||||
|
||||
tor = calloc( 1, sizeof *tor );
|
||||
if( NULL == tor )
|
||||
{
|
||||
*error = TR_EOTHER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse torrent file */
|
||||
if( tr_metainfoParseHash( &tor->info, h->tag, hashStr ) )
|
||||
{
|
||||
*error = TR_EINVALID;
|
||||
free( tor );
|
||||
|
|
|
@ -213,6 +213,16 @@ void tr_close( tr_handle_t * );
|
|||
tr_torrent_t * tr_torrentInit( tr_handle_t *, const char * path,
|
||||
uint8_t * hash, int flags, int * error );
|
||||
|
||||
/***********************************************************************
|
||||
* tr_torrentInitData
|
||||
***********************************************************************
|
||||
* Like tr_torrentInit, except the actual torrent data is passed in
|
||||
* instead of the filename.
|
||||
**********************************************************************/
|
||||
tr_torrent_t * tr_torrentInitData( tr_handle_t *, uint8_t * data,
|
||||
size_t size, uint8_t * hash,
|
||||
int flags, int * error );
|
||||
|
||||
/***********************************************************************
|
||||
* tr_torrentInitSaved
|
||||
***********************************************************************
|
||||
|
|
Loading…
Reference in New Issue