1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-31 20:16:57 +00:00

* fix error checking large files reported by Gimp_

* portability changes to pathname/filename building
* small gratuitous changes
This commit is contained in:
Charles Kerr 2007-06-18 19:39:52 +00:00
parent f7cd20f58c
commit 06e761d950
15 changed files with 154 additions and 130 deletions

6
README
View file

@ -5,9 +5,9 @@ Transmission is a free, lightweight BitTorrent client. It features a
simple, intuitive interface on top on an efficient, cross-platform
back-end.
Transmission is open source (MIT license) and runs on Mac OS X (Cocoa
interface), Linux/NetBSD/FreeBSD/OpenBSD (GTK+ interface) and BeOS
(native interface).
Transmission runs on Mac OS X (Cocoa interface),
Linux/NetBSD/FreeBSD/OpenBSD (GTK+ interface)
and BeOS (native interface).
For more information (including build instructions), please consult the
website: http://transmission.m0k.org/

View file

@ -59,7 +59,7 @@
enum
{
PROP_PARENT = 1,
PROP_CORE,
PROP_CORE
};
#define PTYPE( id ) \

View file

@ -70,17 +70,20 @@ typedef uint64_t tr_time_t;
( FR_MTIME_LEN( t ) + FR_BLOCK_BITFIELD_LEN( t ) )
static void
fastResumeFileName( char * path, size_t size, const tr_torrent_t * tor, int tag )
fastResumeFileName( char * buf, size_t buflen, const tr_torrent_t * tor, int tag )
{
if( tag )
const char * cacheDir = tr_getCacheDirectory ();
const char * hash = tor->info.hashString;
if( !tag )
{
snprintf( path, size, "%s/resume.%s-%s", tr_getCacheDirectory(),
tor->info.hashString, tor->handle->tag );
tr_buildPath( buf, buflen, cacheDir, hash, NULL );
}
else
{
snprintf( path, size, "%s/resume.%s", tr_getCacheDirectory(),
tor->info.hashString );
char base[1024];
snprintf( base, sizeof(base), "%s-%s", hash, tor->handle->tag );
tr_buildPath( buf, buflen, cacheDir, base, NULL );
}
}
@ -94,8 +97,8 @@ getMTimes( const tr_torrent_t * tor, int * setme_n )
for( i=0; i<n; ++i ) {
char fname[MAX_PATH_LENGTH];
struct stat sb;
snprintf( fname, sizeof(fname), "%s/%s",
tor->destination, tor->info.files[i].name );
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;

View file

@ -425,7 +425,9 @@ static int OpenFile( int i, const char * folder, const char * name, int write )
return TR_ERROR_IO_PARENT;
}
snprintf( path, sizeof(path), "%s/%s", folder, name );
snprintf( path, sizeof(path), "%s" TR_PATH_DELIMITER_STR "%s",
folder,
name );
/* Create subfolders, if any */
if( write )

View file

@ -135,7 +135,7 @@ tr_httpRequestType( const char * data, int len, char ** method, char ** uri )
/* copy the method */
if( 0 <= ret && NULL != method )
{
*method = tr_dupstr( words[0], words[1] - words[0] );
*method = tr_strndup( words[0], words[1] - words[0] );
if( NULL == *method )
{
ret = -1;
@ -144,7 +144,7 @@ tr_httpRequestType( const char * data, int len, char ** method, char ** uri )
/* copy uri */
if( 0 <= ret && NULL != uri )
{
*uri = tr_dupstr( words[2], words[3] - words[2] );
*uri = tr_strndup( words[2], words[3] - words[2] );
if( NULL == *uri )
{
free( *method );
@ -371,7 +371,7 @@ tr_httpParseUrl( const char * url, int len,
if( NULL != host )
{
*host = tr_dupstr( url, hostend - url );
*host = tr_strndup( url, hostend - url );
}
if( NULL != port )
{
@ -381,7 +381,7 @@ tr_httpParseUrl( const char * url, int len,
{
if( 0 < len - ( pathstart - url ) )
{
*path = tr_dupstr( pathstart, len - ( pathstart - url ) );
*path = tr_strndup( pathstart, len - ( pathstart - url ) );
}
else
{
@ -843,7 +843,7 @@ learnlength( tr_http_t * http )
{
http->lengthtype = HTTP_LENGTH_FIXED;
http->chunkoff = body - http->header.buf;
duped = tr_dupstr( hdr[0].data, hdr[0].len );
duped = tr_strndup( hdr[0].data, hdr[0].len );
http->chunklen = strtol( duped, NULL, 10 );
free( duped );
}

View file

@ -30,7 +30,7 @@ static int
readOrWriteBytes ( const tr_torrent_t * tor,
int ioMode,
int fileIndex,
size_t fileOffset,
uint64_t fileOffset,
void * buf,
size_t buflen )
{
@ -48,7 +48,7 @@ readOrWriteBytes ( const tr_torrent_t * tor,
return 0;
else if ((fd = tr_fdFileOpen ( tor->destination, file->name, TRUE )) < 0)
ret = fd;
else if( lseek( fd, fileOffset, SEEK_SET ) == ((off_t)-1) )
else if( lseek( fd, (off_t)fileOffset, SEEK_SET ) == ((off_t)-1) )
ret = TR_ERROR_IO_OTHER;
else if( func( fd, buf, buflen ) != buflen )
ret = tr_ioErrorFromErrno ();
@ -63,8 +63,10 @@ readOrWriteBytes ( const tr_torrent_t * tor,
static void
findFileLocation ( const tr_torrent_t * tor,
int pieceIndex, size_t pieceOffset,
int * fileIndex, size_t * fileOffset )
int pieceIndex,
int pieceOffset,
int * fileIndex,
uint64_t * fileOffset )
{
const tr_info_t * info = &tor->info;
@ -72,7 +74,8 @@ findFileLocation ( const tr_torrent_t * tor,
uint64_t piecePos = ((uint64_t)pieceIndex * info->pieceSize) + pieceOffset;
assert ( 0<=pieceIndex && pieceIndex < info->pieceCount );
assert ( pieceOffset < (size_t)tr_pieceSize(pieceIndex) );
assert ( 0<=tor->info.pieceSize );
assert ( pieceOffset < tr_pieceSize(pieceIndex) );
assert ( piecePos < info->totalSize );
for ( i=0; info->files[i].length<=piecePos; ++i )
@ -88,7 +91,7 @@ findFileLocation ( const tr_torrent_t * tor,
static int
ensureMinimumFileSize ( const tr_torrent_t * tor,
int fileIndex,
size_t minSize ) /* in bytes */
uint64_t minSize ) /* in bytes */
{
int fd;
int ret;
@ -120,13 +123,13 @@ static int
readOrWritePiece ( tr_torrent_t * tor,
int ioMode,
int pieceIndex,
size_t pieceOffset,
int pieceOffset,
uint8_t * buf,
size_t buflen )
{
int ret = 0;
int fileIndex;
size_t fileOffset;
uint64_t fileOffset;
const tr_info_t * info = &tor->info;
assert( 0<=pieceIndex && pieceIndex<tor->info.pieceCount );
@ -141,7 +144,7 @@ readOrWritePiece ( tr_torrent_t * tor,
while( buflen && !ret )
{
const tr_file_t * file = &info->files[fileIndex];
const size_t bytesThisPass = MIN( buflen, file->length - fileOffset );
const uint64_t bytesThisPass = MIN( buflen, file->length - fileOffset );
if( ioMode == TR_IO_WRITE )
ret = ensureMinimumFileSize( tor, fileIndex,

View file

@ -45,7 +45,7 @@ getFiles( const char * dir,
DIR * odir = NULL;
sb.st_size = 0;
snprintf( buf, sizeof(buf), "%s"TR_PATH_DELIMITER_STR"%s", dir, base );
tr_buildPath( buf, sizeof(buf), dir, base, NULL );
i = stat( buf, &sb );
if( i ) {
tr_err("makemeta couldn't stat \"%s\"; skipping. (%s)", buf, strerror(errno));

View file

@ -348,7 +348,7 @@ static int getfile( char * buf, int size,
strcatUTF8( buf, size, prefix, 0 );
for( ii = 0; jj > ii; ii++ )
{
strcatUTF8( buf, size, "/", 0 );
strcatUTF8( buf, size, TR_PATH_DELIMITER_STR, 0 );
strcatUTF8( buf, size, list[ii], 1 );
}
free( list );
@ -523,16 +523,20 @@ static char * announceToScrape( const char * announce )
return scrape;
}
void savedname( char * name, size_t len, const char * hash, const char * tag )
void
savedname( char * name, size_t len, const char * hash, const char * tag )
{
if( NULL == tag )
const char * torDir = tr_getTorrentsDirectory ();
if( tag == NULL )
{
snprintf( name, len, "%s/%s", tr_getTorrentsDirectory(), hash );
tr_buildPath( name, len, torDir, hash, NULL );
}
else
{
snprintf( name, len, "%s/%s-%s",
tr_getTorrentsDirectory(), hash, tag );
char base[1024];
snprintf( base, sizeof(base), "%s-%s", hash, tag );
tr_buildPath( name, len, torDir, base, NULL );
}
}

View file

@ -81,128 +81,120 @@ tr_getHomeDirectory( void )
static void
tr_migrateResume( const char *oldDirectory, const char *newDirectory )
{
DIR * dirh;
struct dirent * dirp;
char oldFile[MAX_PATH_LENGTH];
char newFile[MAX_PATH_LENGTH];
DIR * dirh = opendir( oldDirectory );
if( ( dirh = opendir( oldDirectory ) ) )
if( dirh != NULL )
{
struct dirent * dirp;
while( ( dirp = readdir( dirh ) ) )
{
if( strncmp( "resume.", dirp->d_name, 7 ) )
if( !strncmp( "resume.", dirp->d_name, 7 ) )
{
continue;
char o[MAX_PATH_LENGTH];
char n[MAX_PATH_LENGTH];
tr_buildPath( o, sizeof(o), oldDirectory, dirp->d_name, NULL );
tr_buildPath( n, sizeof(n), newDirectory, dirp->d_name, NULL );
rename( o, n );
}
snprintf( oldFile, MAX_PATH_LENGTH, "%s/%s",
oldDirectory, dirp->d_name );
snprintf( newFile, MAX_PATH_LENGTH, "%s/%s",
newDirectory, dirp->d_name );
rename( oldFile, newFile );
}
closedir( dirh );
}
}
char * tr_getPrefsDirectory()
const char *
tr_getPrefsDirectory( void )
{
static char prefsDirectory[MAX_PATH_LENGTH];
static int init = 0;
static char buf[MAX_PATH_LENGTH];
static int init = 0;
static size_t buflen = sizeof(buf);
const char* h;
if( init )
{
return prefsDirectory;
}
return buf;
h = tr_getHomeDirectory();
#ifdef SYS_BEOS
find_directory( B_USER_SETTINGS_DIRECTORY, dev_for_path("/boot"),
true, prefsDirectory, MAX_PATH_LENGTH );
strcat( prefsDirectory, "/Transmission" );
find_directory( B_USER_SETTINGS_DIRECTORY,
dev_for_path("/boot"), true, buf, buflen );
strcat( buf, "/Transmission" );
#elif defined( SYS_DARWIN )
snprintf( prefsDirectory, MAX_PATH_LENGTH,
"%s/Library/Application Support/Transmission",
tr_getHomeDirectory() );
tr_buildPath ( buf, buflen, h,
"Library", "Application Support", "Transmission", NULL );
#elif defined(__AMIGAOS4__)
snprintf( prefsDirectory, MAX_PATH_LENGTH, "PROGDIR:.transmission" );
snprintf( buf, buflen, "PROGDIR:.transmission" );
#else
snprintf( prefsDirectory, MAX_PATH_LENGTH, "%s/.transmission",
tr_getHomeDirectory() );
tr_buildPath ( buf, buflen, h, ".transmission", NULL );
#endif
tr_mkdir( prefsDirectory );
tr_mkdir( buf );
init = 1;
#ifdef SYS_DARWIN
char oldDirectory[MAX_PATH_LENGTH];
snprintf( oldDirectory, MAX_PATH_LENGTH, "%s/.transmission",
tr_getHomeDirectory() );
tr_migrateResume( oldDirectory, prefsDirectory );
char old[MAX_PATH_LENGTH];
tr_buildPath ( old, sizeof(old), h, ".transmission", NULL );
tr_migrateResume( old, buf );
rmdir( oldDirectory );
#endif
return prefsDirectory;
return buf;
}
char * tr_getCacheDirectory()
const char *
tr_getCacheDirectory( void )
{
static char cacheDirectory[MAX_PATH_LENGTH];
static char buf[MAX_PATH_LENGTH];
static int init = 0;
static const size_t buflen = sizeof(buf);
const char * p;
if( init )
{
return cacheDirectory;
}
return buf;
p = tr_getPrefsDirectory();
#ifdef SYS_BEOS
/* XXX hey Bryan, is this fine with you? */
snprintf( cacheDirectory, MAX_PATH_LENGTH, "%s/Cache",
tr_getPrefsDirectory() );
tr_buildPath( buf, buflen, p, "Cache", NULL );
#elif defined( SYS_DARWIN )
snprintf( cacheDirectory, MAX_PATH_LENGTH, "%s/Library/Caches/Transmission",
tr_getHomeDirectory() );
tr_buildPath( buf, buflen, tr_getHomeDirectory(),
"Library", "Caches", "Transmission", NULL );
#else
snprintf( cacheDirectory, MAX_PATH_LENGTH, "%s/cache",
tr_getPrefsDirectory() );
tr_buildPath( buf, buflen, p, "cache", NULL );
#endif
tr_mkdir( cacheDirectory );
tr_mkdir( buf );
init = 1;
if( strcmp( tr_getPrefsDirectory(), cacheDirectory ) )
{
tr_migrateResume( tr_getPrefsDirectory(), cacheDirectory );
}
if( strcmp( p, buf ) )
tr_migrateResume( p, buf );
return cacheDirectory;
return buf;
}
char * tr_getTorrentsDirectory()
const char *
tr_getTorrentsDirectory( void )
{
static char torrentsDirectory[MAX_PATH_LENGTH];
static char buf[MAX_PATH_LENGTH];
static int init = 0;
static const size_t buflen = sizeof(buf);
const char * p;
if( init )
{
return torrentsDirectory;
}
return buf;
p = tr_getPrefsDirectory ();
#ifdef SYS_BEOS
/* XXX hey Bryan, is this fine with you? */
snprintf( torrentsDirectory, MAX_PATH_LENGTH, "%s/Torrents",
tr_getPrefsDirectory() );
tr_buildPath( buf, buflen, p, "Torrents", NULL );
#elif defined( SYS_DARWIN )
snprintf( torrentsDirectory, MAX_PATH_LENGTH, "%s/Torrents",
tr_getPrefsDirectory() );
tr_buildPath( buf, buflen, p, "Torrents", NULL );
#else
snprintf( torrentsDirectory, MAX_PATH_LENGTH, "%s/torrents",
tr_getPrefsDirectory() );
tr_buildPath( buf, buflen, p, "torrents", NULL );
#endif
tr_mkdir( torrentsDirectory );
tr_mkdir( buf );
init = 1;
return torrentsDirectory;
return buf;
}
static void ThreadFunc( void * _t )

View file

@ -47,8 +47,8 @@ tr_thread_t;
/* only for debugging purposes */
const char * tr_getHomeDirectory( void );
char * tr_getCacheDirectory();
char * tr_getTorrentsDirectory();
const char * tr_getCacheDirectory( void );
const char * tr_getTorrentsDirectory( void );
/**
* When instantiating a thread with a deferred call to tr_threadCreate(),

View file

@ -52,8 +52,13 @@ extern "C" {
#define INET_ADDRSTRLEN 16
#endif
#if defined(__MINGW__)
#define TR_PATH_DELIMITER '\\'
#define TR_PATH_DELIMITER_STR "\\"
#else
#define TR_PATH_DELIMITER '/'
#define TR_PATH_DELIMITER_STR "/"
#endif
#define TR_DEFAULT_PORT 9090
@ -133,7 +138,7 @@ void tr_freeMessageList( tr_msg_list_t * list );
* Returns the full path to a directory which can be used to store
* preferences. The string belongs to libtransmission, do not free it.
**********************************************************************/
char * tr_getPrefsDirectory();
const char * tr_getPrefsDirectory( void );
/***********************************************************************
* tr_setBindPort

View file

@ -588,7 +588,7 @@ deviceAdd( tr_upnp_device_t ** first, const char * id, int idLen,
free( ii );
return;
}
ii->id = tr_dupstr( id, idLen );
ii->id = tr_strndup( id, idLen );
ii->state = UPNPDEV_STATE_ROOT;
actionSetup( &ii->getcmd, "GetSpecificPortMappingEntry", 8 );
actionSetup( &ii->addcmd, "AddPortMapping", 8 );
@ -1089,7 +1089,7 @@ parseRoot( const char * root, const char *buf, int len,
{
basedup = strrchr( root, '/' );
assert( NULL != basedup );
basedup = tr_dupstr( root, basedup - root + 1 );
basedup = tr_strndup( root, basedup - root + 1 );
}
else
{

View file

@ -311,19 +311,24 @@ int tr_concat( char ** buf, int * used, int * max, const char * data, int len )
return 0;
}
char *
tr_dupstr( const char * base, int len )
void
tr_buildPath ( char *buf, size_t buflen, const char *first_element, ... )
{
char * ret;
ret = malloc( len + 1 );
if( NULL != ret )
{
memcpy( ret, base, len );
ret[len] = '\0';
va_list vl;
char* walk = buf;
const char * element = first_element;
va_start( vl, first_element );
for( ;; ) {
const size_t n = strlen( element );
memcpy( walk, element, n );
walk += n;
element = (const char*) va_arg( vl, const char* );
if( element == NULL )
break;
*walk++ = TR_PATH_DELIMITER;
}
return ret;
*walk = '\0';
assert( walk-buf <= (int)buflen );
}
int
@ -376,19 +381,30 @@ tr_errorString( int code )
*****
****/
char* tr_strdup( const char * in )
char*
tr_strdup( const char * in )
{
return tr_strndup( in, in ? strlen(in) : 0 );
}
char*
tr_strndup( const char * in, int len )
{
char * out = NULL;
if( in != NULL )
{
const size_t len = strlen( in );
out = malloc( len + 1 );
out = tr_calloc( len+1, 1 );
memcpy( out, in, len );
out[len] = '\0';
}
return out;
}
void*
tr_calloc( size_t nmemb, size_t size )
{
return nmemb && size ? calloc( nmemb, size ) : NULL;
}
void*
tr_malloc( size_t size )
{

View file

@ -66,12 +66,11 @@ int tr_vsprintf( char **, int *, int *, const char *, va_list, va_list );
int tr_concat( char ** buf, int * used, int * max,
const char * data, int len );
/***********************************************************************
* tr_dupstr
***********************************************************************
* Creates a nul-terminated string
**********************************************************************/
char * tr_dupstr( const char * base, int len );
/* creates a filename from a series of elements using the
correct separator for filenames. */
void tr_buildPath ( char* buf, size_t buflen,
const char * first_element, ... );
int tr_ioErrorFromErrno( void );
@ -177,10 +176,10 @@ static inline int _tr_block( const tr_torrent_t * tor, int index, int begin )
****
***/
char* tr_strdup( const char * pch );
char* tr_strdup( const char * str );
char* tr_strndup( const char * str, int len );
void* tr_malloc( size_t );
void* tr_calloc( size_t nmemb, size_t size );
void tr_free( void* );
/***

View file

@ -229,7 +229,7 @@ catrange( char * str, const char * begin, const char * end )
if( NULL == str )
{
return tr_dupstr( begin, end - begin );
return tr_strndup( begin, end - begin );
}
len = strlen( str );