From 06e761d9507c7cab9bcddeae5eee9e5d6bd80f39 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 18 Jun 2007 19:39:52 +0000 Subject: [PATCH] * fix error checking large files reported by Gimp_ * portability changes to pathname/filename building * small gratuitous changes --- README | 6 +- gtk/tr_prefs.c | 2 +- libtransmission/fastresume.c | 19 ++--- libtransmission/fdlimit.c | 4 +- libtransmission/http.c | 10 +-- libtransmission/inout.c | 21 +++--- libtransmission/makemeta.c | 2 +- libtransmission/metainfo.c | 16 +++-- libtransmission/platform.c | 124 +++++++++++++++------------------ libtransmission/platform.h | 4 +- libtransmission/transmission.h | 7 +- libtransmission/upnp.c | 4 +- libtransmission/utils.c | 46 ++++++++---- libtransmission/utils.h | 17 +++-- libtransmission/xml.c | 2 +- 15 files changed, 154 insertions(+), 130 deletions(-) diff --git a/README b/README index 2a5fc98ef..fcb2476cd 100644 --- a/README +++ b/README @@ -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/ diff --git a/gtk/tr_prefs.c b/gtk/tr_prefs.c index f409d6e7e..4034ec60a 100644 --- a/gtk/tr_prefs.c +++ b/gtk/tr_prefs.c @@ -59,7 +59,7 @@ enum { PROP_PARENT = 1, - PROP_CORE, + PROP_CORE }; #define PTYPE( id ) \ diff --git a/libtransmission/fastresume.c b/libtransmission/fastresume.c index e5f449ee1..59d288326 100644 --- a/libtransmission/fastresume.c +++ b/libtransmission/fastresume.c @@ -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; idestination, 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; diff --git a/libtransmission/fdlimit.c b/libtransmission/fdlimit.c index c5aeff284..50b2698dd 100644 --- a/libtransmission/fdlimit.c +++ b/libtransmission/fdlimit.c @@ -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 ) diff --git a/libtransmission/http.c b/libtransmission/http.c index 4e31754ce..1435ef181 100644 --- a/libtransmission/http.c +++ b/libtransmission/http.c @@ -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 ); } diff --git a/libtransmission/inout.c b/libtransmission/inout.c index 8bafa3663..184da5d56 100644 --- a/libtransmission/inout.c +++ b/libtransmission/inout.c @@ -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 && pieceIndexinfo.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, diff --git a/libtransmission/makemeta.c b/libtransmission/makemeta.c index d342ea052..9bf916f49 100644 --- a/libtransmission/makemeta.c +++ b/libtransmission/makemeta.c @@ -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)); diff --git a/libtransmission/metainfo.c b/libtransmission/metainfo.c index 6784407b7..4c967bbca 100644 --- a/libtransmission/metainfo.c +++ b/libtransmission/metainfo.c @@ -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 ); } } diff --git a/libtransmission/platform.c b/libtransmission/platform.c index 4f6622807..958ffc3ea 100644 --- a/libtransmission/platform.c +++ b/libtransmission/platform.c @@ -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 ) diff --git a/libtransmission/platform.h b/libtransmission/platform.h index de5e0101e..5b7920c7e 100644 --- a/libtransmission/platform.h +++ b/libtransmission/platform.h @@ -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(), diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index 7fd1f3616..a871d65ff 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -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 diff --git a/libtransmission/upnp.c b/libtransmission/upnp.c index de316ec05..70cc1c863 100644 --- a/libtransmission/upnp.c +++ b/libtransmission/upnp.c @@ -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 { diff --git a/libtransmission/utils.c b/libtransmission/utils.c index 8e48075cc..a048b7655 100644 --- a/libtransmission/utils.c +++ b/libtransmission/utils.c @@ -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 ) { diff --git a/libtransmission/utils.h b/libtransmission/utils.h index 4c2d9afb7..3c1fbeab5 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -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* ); /*** diff --git a/libtransmission/xml.c b/libtransmission/xml.c index 3e55dc3e3..6d4620507 100644 --- a/libtransmission/xml.c +++ b/libtransmission/xml.c @@ -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 );