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:
parent
f7cd20f58c
commit
06e761d950
15 changed files with 154 additions and 130 deletions
6
README
6
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/
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
enum
|
||||
{
|
||||
PROP_PARENT = 1,
|
||||
PROP_CORE,
|
||||
PROP_CORE
|
||||
};
|
||||
|
||||
#define PTYPE( id ) \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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* );
|
||||
|
||||
/***
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in a new issue