~ubuntu-branches/ubuntu/jaunty/transmission/jaunty-security

« back to all changes in this revision

Viewing changes to libtransmission/utils.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2008-11-28 15:33:48 UTC
  • mfrom: (1.1.19 upstream)
  • Revision ID: james.westby@ubuntu.com-20081128153348-it70trfnxiroblmc
Tags: 1.40-0ubuntu1
* New upstream release (LP: #302672)
  - Tracker communication uses fewer resources
  - More accurate bandwidth limits
  - Reduce disk fragmentation by preallocating files (LP: #287726)
  - Stability, security and performance improvements to the RPC /
    Web UI server (closes LP: #290423)
  - Support compression when serving Web UI and RPC responses
  - Simplify the RPC whitelist
  - Fix bug that prevented handshakes with encrypted BitComet peers
  - Fix 1.3x bug that could re-download some data unnecessarily
    (LP: #295040)
  - Option to automatically update the blocklist weekly
  - Added off-hour bandwidth scheduling
  - Simplify file/priority selection in the details dialog
  - Fix a couple of crashes
  - New / updated translations
  - Don't inhibit hibernation by default (LP: #292929)
  - Use "close" animation when sending to notification area (LP: #130811)
  - Fix resize problems (LP: #269872)
  - Support "--version" option when launching from command line
    (LP: #292011)
  - Correctly parse announce URLs that have leading or trailing
    spaces (LP: #262411)
  - Display an error when "Open Torrent" fails (LP: #281463)
* Dropped 10_fix_crasher_from_upstream.dpatch: Fix is in this
  upstream release.
* debian/control: Don't just build-depend on libcurl-dev, which is
  a virtual package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: utils.c 6768 2008-09-16 17:50:16Z charles $
 
2
 * $Id: utils.c 6993 2008-10-30 19:47:00Z charles $
3
3
 *
4
4
 * Copyright (c) 2005-2008 Transmission authors and contributors
5
5
 *
28
28
#include <stdarg.h>
29
29
#include <stdio.h>
30
30
#include <stdlib.h>
31
 
#include <string.h> /* strerror */
 
31
#include <string.h> /* strerror, memset */
32
32
 
33
33
#include <libgen.h> /* basename */
34
34
#include <sys/time.h>
35
35
#include <sys/types.h>
36
36
#include <sys/stat.h>
37
 
#include <unistd.h> /* usleep, stat */
 
37
#include <unistd.h> /* usleep, stat, getcwd */
38
38
 
39
39
#include "event.h"
40
40
 
41
41
#ifdef WIN32
42
 
    #include <windows.h> /* for Sleep */
43
 
#elif defined(__BEOS__)
44
 
    #include <kernel/OS.h>
 
42
 #include <direct.h> /* _getcwd */
 
43
 #include <windows.h> /* Sleep */
 
44
#elif defined( __BEOS__ )
 
45
 #include <kernel/OS.h>
45
46
#endif
46
47
 
47
48
#include "transmission.h"
48
49
#include "utils.h"
49
50
#include "platform.h"
50
51
 
51
 
static tr_lock      * messageLock = NULL;
 
52
static tr_lock *      messageLock = NULL;
52
53
static int            messageLevel = 0;
53
54
static int            messageQueuing = FALSE;
54
55
static tr_msg_list *  messageQueue = NULL;
55
56
static tr_msg_list ** messageQueueTail = &messageQueue;
56
57
 
57
 
void tr_msgInit( void )
 
58
#ifndef WIN32
 
59
    /* make null versions of these win32 functions */
 
60
    static int IsDebuggerPresent( void ) { return FALSE; }
 
61
    static void OutputDebugString( const void * unused UNUSED ) { }
 
62
#endif
 
63
 
 
64
void
 
65
tr_msgInit( void )
58
66
{
59
67
    if( !messageLock )
60
 
         messageLock = tr_lockNew( );
 
68
        messageLock = tr_lockNew( );
61
69
}
62
70
 
63
71
FILE*
64
72
tr_getLog( void )
65
73
{
66
 
    static int initialized = FALSE;
67
 
    static FILE * file= NULL;
 
74
    static int    initialized = FALSE;
 
75
    static FILE * file = NULL;
68
76
 
69
77
    if( !initialized )
70
78
    {
71
79
        const char * str = getenv( "TR_DEBUG_FD" );
72
 
        int fd = 0;
 
80
        int          fd = 0;
73
81
        if( str && *str )
74
82
            fd = atoi( str );
75
 
        switch( fd ) {
76
 
            case 1: file = stdout; break;
77
 
            case 2: file = stderr; break;
78
 
            default: file = NULL; break;
 
83
        switch( fd )
 
84
        {
 
85
            case 1:
 
86
                file = stdout; break;
 
87
 
 
88
            case 2:
 
89
                file = stderr; break;
 
90
 
 
91
            default:
 
92
                file = NULL; break;
79
93
        }
80
94
        initialized = TRUE;
81
95
    }
86
100
void
87
101
tr_setMessageLevel( int level )
88
102
{
89
 
    tr_msgInit();
 
103
    tr_msgInit( );
90
104
    tr_lockLock( messageLock );
91
105
    messageLevel = MAX( 0, level );
92
106
    tr_lockUnlock( messageLock );
97
111
{
98
112
    int ret;
99
113
 
100
 
    tr_msgInit();
 
114
    tr_msgInit( );
101
115
    tr_lockLock( messageLock );
102
116
    ret = messageLevel;
103
117
    tr_lockUnlock( messageLock );
108
122
void
109
123
tr_setMessageQueuing( int enabled )
110
124
{
111
 
    tr_msgInit();
 
125
    tr_msgInit( );
112
126
    tr_lockLock( messageLock );
113
127
    messageQueuing = enabled;
114
128
    tr_lockUnlock( messageLock );
115
129
}
116
130
 
 
131
int
 
132
tr_getMessageQueuing( void )
 
133
{
 
134
    int ret;
 
135
 
 
136
    tr_msgInit( );
 
137
    tr_lockLock( messageLock );
 
138
    ret = messageQueuing;
 
139
    tr_lockUnlock( messageLock );
 
140
 
 
141
    return ret;
 
142
}
 
143
 
117
144
tr_msg_list *
118
145
tr_getQueuedMessages( void )
119
146
{
148
175
***
149
176
**/
150
177
 
 
178
static struct tm *
 
179
tr_localtime_r( time_t *_clock, struct tm *_result )
 
180
{
 
181
#ifdef HAVE_LOCALTIME_R
 
182
    return localtime_r( _clock, _result );
 
183
#else
 
184
    struct tm *p = localtime( _clock );
 
185
    if( p )
 
186
        *(_result) = *p;
 
187
    return p;
 
188
#endif
 
189
}
 
190
 
151
191
char*
152
 
tr_getLogTimeStr( char * buf, int buflen )
 
192
tr_getLogTimeStr( char * buf,
 
193
                  int    buflen )
153
194
{
154
 
    char tmp[64];
155
 
    time_t now;
156
 
    struct tm now_tm;
 
195
    char           tmp[64];
 
196
    time_t         now;
 
197
    struct tm      now_tm;
157
198
    struct timeval tv;
158
 
    int milliseconds;
 
199
    int            milliseconds;
159
200
 
160
201
    now = time( NULL );
161
202
    gettimeofday( &tv, NULL );
162
203
 
163
 
#ifdef WIN32
164
 
    now_tm = *localtime( &now );
165
 
#else
166
 
    localtime_r( &now, &now_tm );
167
 
#endif
168
 
    strftime( tmp, sizeof(tmp), "%H:%M:%S", &now_tm );
169
 
    milliseconds = (int)(tv.tv_usec / 1000);
 
204
    tr_localtime_r( &now, &now_tm );
 
205
    strftime( tmp, sizeof( tmp ), "%H:%M:%S", &now_tm );
 
206
    milliseconds = (int)( tv.tv_usec / 1000 );
170
207
    tr_snprintf( buf, buflen, "%s.%03d", tmp, milliseconds );
171
208
 
172
209
    return buf;
173
210
}
174
211
 
 
212
int
 
213
tr_deepLoggingIsActive( void )
 
214
{
 
215
    return IsDebuggerPresent() || (tr_getLog()!=NULL);
 
216
}
 
217
 
175
218
void
176
 
tr_deepLog( const char * file, int line, const char * name, const char * fmt, ... )
 
219
tr_deepLog( const char  * file,
 
220
            int           line,
 
221
            const char  * name,
 
222
            const char  * fmt,
 
223
            ... )
177
224
{
178
225
    FILE * fp = tr_getLog( );
179
 
    if( fp )
 
226
    if( fp || IsDebuggerPresent( ) )
180
227
    {
181
 
        va_list args;
182
 
        char timestr[64];
 
228
        va_list           args;
 
229
        char              timestr[64];
183
230
        struct evbuffer * buf = evbuffer_new( );
184
 
        char * myfile = tr_strdup( file );
 
231
        char *            base = tr_basename( file );
185
232
 
186
 
        evbuffer_add_printf( buf, "[%s] ", tr_getLogTimeStr( timestr, sizeof(timestr) ) );
 
233
        evbuffer_add_printf( buf, "[%s] ",
 
234
                            tr_getLogTimeStr( timestr, sizeof( timestr ) ) );
187
235
        if( name )
188
236
            evbuffer_add_printf( buf, "%s ", name );
189
237
        va_start( args, fmt );
190
238
        evbuffer_add_vprintf( buf, fmt, args );
191
239
        va_end( args );
192
 
        evbuffer_add_printf( buf, " (%s:%d)\n", basename(myfile), line );
193
 
        fwrite( EVBUFFER_DATA(buf), 1, EVBUFFER_LENGTH(buf), fp );
 
240
        evbuffer_add_printf( buf, " (%s:%d)\n", base, line );
 
241
        OutputDebugString( EVBUFFER_DATA( buf ) );
 
242
        if(fp)
 
243
            (void) fwrite( EVBUFFER_DATA( buf ), 1, EVBUFFER_LENGTH( buf ), fp );
194
244
 
195
 
        tr_free( myfile );
 
245
        tr_free( base );
196
246
        evbuffer_free( buf );
197
247
    }
198
248
}
202
252
***/
203
253
 
204
254
void
205
 
tr_msg( const char * file, int line, int level,
 
255
tr_msg( const char * file,
 
256
        int          line,
 
257
        int          level,
206
258
        const char * name,
207
 
        const char * fmt, ... )
 
259
        const char * fmt,
 
260
        ... )
208
261
{
209
262
    FILE * fp;
210
263
 
222
275
 
223
276
    if( messageLevel >= level )
224
277
    {
225
 
        va_list ap;
 
278
        va_list           ap;
226
279
        struct evbuffer * buf = evbuffer_new( );
227
280
 
228
281
        /* build the text message */
230
283
        evbuffer_add_vprintf( buf, fmt, ap );
231
284
        va_end( ap );
232
285
 
 
286
        OutputDebugString( EVBUFFER_DATA( buf ) );
 
287
 
233
288
        if( EVBUFFER_LENGTH( buf ) )
234
289
        {
235
290
            if( messageQueuing )
251
306
                if( fp == NULL )
252
307
                    fp = stderr;
253
308
                if( name )
254
 
                    fprintf( fp, "%s: %s\n", name, (char*)EVBUFFER_DATA(buf) );
 
309
                    fprintf( fp, "%s: %s\n", name,
 
310
                            (char*)EVBUFFER_DATA( buf ) );
255
311
                else
256
 
                    fprintf( fp, "%s\n", (char*)EVBUFFER_DATA(buf) );
 
312
                    fprintf( fp, "%s\n", (char*)EVBUFFER_DATA( buf ) );
257
313
                fflush( fp );
258
314
            }
259
315
 
265
321
        tr_lockUnlock( messageLock );
266
322
}
267
323
 
268
 
int tr_rand( int sup )
269
 
{
270
 
    static int init = 0;
271
 
 
272
 
    assert( sup > 0 );
273
 
 
274
 
    if( !init )
275
 
    {
276
 
        srand( tr_date() );
277
 
        init = 1;
278
 
    }
279
 
    return rand() % sup;
280
 
}
281
 
 
282
324
/***
283
325
****
284
326
***/
285
327
 
286
328
void
287
 
tr_set_compare( const void * va, size_t aCount,
288
 
                const void * vb, size_t bCount,
 
329
tr_set_compare( const void * va,
 
330
                size_t aCount,
 
331
                const void * vb,
 
332
                size_t bCount,
289
333
                int compare( const void * a, const void * b ),
290
334
                size_t elementSize,
291
335
                tr_set_func in_a_cb,
295
339
{
296
340
    const uint8_t * a = (const uint8_t *) va;
297
341
    const uint8_t * b = (const uint8_t *) vb;
298
 
    const uint8_t * aend = a + elementSize*aCount;
299
 
    const uint8_t * bend = b + elementSize*bCount;
 
342
    const uint8_t * aend = a + elementSize * aCount;
 
343
    const uint8_t * bend = b + elementSize * bCount;
300
344
 
301
 
    while( a!=aend || b!=bend )
 
345
    while( a != aend || b != bend )
302
346
    {
303
 
        if( a==aend )
 
347
        if( a == aend )
304
348
        {
305
 
            (*in_b_cb)( (void*)b, userData );
 
349
            ( *in_b_cb )( (void*)b, userData );
306
350
            b += elementSize;
307
351
        }
308
 
        else if ( b==bend )
 
352
        else if( b == bend )
309
353
        {
310
 
            (*in_a_cb)( (void*)a, userData );
 
354
            ( *in_a_cb )( (void*)a, userData );
311
355
            a += elementSize;
312
356
        }
313
357
        else
314
358
        {
315
 
            const int val = (*compare)( a, b );
 
359
            const int val = ( *compare )( a, b );
316
360
 
317
361
            if( !val )
318
362
            {
319
 
                (*in_both_cb)( (void*)a, userData );
 
363
                ( *in_both_cb )( (void*)a, userData );
320
364
                a += elementSize;
321
365
                b += elementSize;
322
366
            }
323
367
            else if( val < 0 )
324
368
            {
325
 
                (*in_a_cb)( (void*)a, userData );
 
369
                ( *in_a_cb )( (void*)a, userData );
326
370
                a += elementSize;
327
371
            }
328
372
            else if( val > 0 )
329
373
            {
330
 
                (*in_b_cb)( (void*)b, userData );
 
374
                ( *in_b_cb )( (void*)b, userData );
331
375
                b += elementSize;
332
376
            }
333
377
        }
338
382
****
339
383
***/
340
384
 
341
 
int
342
 
tr_compareUint16( uint16_t a, uint16_t b )
343
 
{
344
 
    if( a < b ) return -1;
345
 
    if( a > b ) return 1;
346
 
    return 0;
347
 
}
348
 
 
349
 
int
350
 
tr_compareUint32( uint32_t a, uint32_t b )
351
 
{
352
 
    if( a < b ) return -1;
353
 
    if( a > b ) return 1;
354
 
    return 0;
355
 
}
356
 
 
357
 
int
358
 
tr_compareUint64( uint64_t a, uint64_t b )
359
 
{
360
 
    if( a < b ) return -1;
361
 
    if( a > b ) return 1;
362
 
    return 0;
363
 
}
364
 
 
365
 
int
366
 
tr_compareDouble( double a, double b )
367
 
{
368
 
    if( a < b ) return -1;
369
 
    if( a > b ) return 1;
370
 
    return 0;
371
 
}
372
 
 
373
 
int
374
 
tr_strcmp( const void * a, const void * b )
375
 
{
376
 
    if( a && b ) return strcmp( a, b );
377
 
    if( a ) return 1;
378
 
    if( b ) return -1;
379
 
    return 0;
380
 
}
381
 
 
382
 
int
383
 
tr_strcasecmp( const char * a, const char * b )
384
 
{
385
 
    if( !a && !b ) return 0;
386
 
    if( !a ) return -1;
387
 
    if( !b ) return 1;
388
 
#ifdef HAVE_STRCASECMP
389
 
    return strcasecmp( a, b );
390
 
#else
391
 
    while( *a && ( tolower( *(uint8_t*)a ) == tolower( *(uint8_t*)b ) ) )
392
 
        ++a, ++b;
393
 
    return tolower( *(uint8_t*)a) - tolower(*(uint8_t*)b );
 
385
#ifdef DISABLE_GETTEXT
 
386
 
 
387
const char*
 
388
tr_strip_positional_args( const char* str )
 
389
{
 
390
    static size_t bufsize = 0;
 
391
    static char * buf = NULL;
 
392
    const size_t  len = strlen( str );
 
393
    char *        out;
 
394
 
 
395
    if( bufsize < len )
 
396
    {
 
397
        bufsize = len * 2;
 
398
        buf = tr_renew( char, buf, bufsize );
 
399
    }
 
400
 
 
401
    for( out = buf; *str; ++str )
 
402
    {
 
403
        *out++ = *str;
 
404
        if( ( *str == '%' ) && isdigit( str[1] ) )
 
405
        {
 
406
            const char * tmp = str + 1;
 
407
            while( isdigit( *tmp ) )
 
408
                ++tmp;
 
409
 
 
410
            if( *tmp == '$' )
 
411
                str = tmp;
 
412
        }
 
413
    }
 
414
    *out = '\0';
 
415
 
 
416
    return buf;
 
417
}
 
418
 
394
419
#endif
395
 
}
396
 
 
397
420
 
398
421
/**
399
422
***
400
423
**/
401
424
 
402
 
struct timeval
403
 
tr_timevalMsec( uint64_t milliseconds )
 
425
void
 
426
tr_timevalMsec( uint64_t milliseconds, struct timeval * setme )
404
427
{
405
 
    struct timeval ret;
406
428
    const uint64_t microseconds = milliseconds * 1000;
407
 
    ret.tv_sec  = microseconds / 1000000;
408
 
    ret.tv_usec = microseconds % 1000000;
409
 
    return ret;
 
429
    assert( setme != NULL );
 
430
    setme->tv_sec  = microseconds / 1000000;
 
431
    setme->tv_usec = microseconds % 1000000;
410
432
}
411
433
 
412
434
uint8_t *
413
 
tr_loadFile( const char * path, size_t * size )
 
435
tr_loadFile( const char * path,
 
436
             size_t *     size )
414
437
{
415
 
    uint8_t    * buf;
 
438
    uint8_t *    buf;
416
439
    struct stat  sb;
417
 
    FILE       * file;
 
440
    FILE *       file;
418
441
    const char * err_fmt = _( "Couldn't read \"%1$s\": %2$s" );
419
442
 
420
443
    /* try to stat the file */
421
444
    errno = 0;
422
445
    if( stat( path, &sb ) )
423
446
    {
424
 
        tr_dbg( err_fmt, path, tr_strerror(errno) );
 
447
        const int err = errno;
 
448
        tr_dbg( err_fmt, path, tr_strerror( errno ) );
 
449
        errno = err;
425
450
        return NULL;
426
451
    }
427
452
 
428
453
    if( ( sb.st_mode & S_IFMT ) != S_IFREG )
429
454
    {
430
455
        tr_err( err_fmt, path, _( "Not a regular file" ) );
 
456
        errno = EISDIR;
431
457
        return NULL;
432
458
    }
433
459
 
435
461
    file = fopen( path, "rb" );
436
462
    if( !file )
437
463
    {
438
 
        tr_err( err_fmt, path, tr_strerror(errno) );
 
464
        const int err = errno;
 
465
        tr_err( err_fmt, path, tr_strerror( errno ) );
 
466
        errno = err;
439
467
        return NULL;
440
468
    }
441
469
    buf = malloc( sb.st_size );
442
 
    if( NULL == buf )
 
470
    if( !buf )
443
471
    {
 
472
        const int err = errno;
444
473
        tr_err( err_fmt, path, _( "Memory allocation failed" ) );
445
474
        fclose( file );
 
475
        errno = err;
446
476
        return NULL;
447
477
    }
448
 
    fseek( file, 0, SEEK_SET );
449
478
    if( fread( buf, sb.st_size, 1, file ) != 1 )
450
479
    {
451
 
        tr_err( err_fmt, path, tr_strerror(errno) );
 
480
        const int err = errno;
 
481
        tr_err( err_fmt, path, tr_strerror( errno ) );
 
482
        fclose( file );
452
483
        free( buf );
453
 
        fclose( file );
 
484
        errno = err;
454
485
        return NULL;
455
486
    }
 
487
 
456
488
    fclose( file );
457
 
 
458
489
    *size = sb.st_size;
459
 
 
460
490
    return buf;
461
491
}
462
492
 
 
493
char*
 
494
tr_getcwd( void )
 
495
{
 
496
    char buf[2048];
 
497
    *buf = '\0';
 
498
#ifdef WIN32
 
499
    _getcwd( buf, sizeof( buf ) );
 
500
#else
 
501
    getcwd( buf, sizeof( buf ) );
 
502
#endif
 
503
    return tr_strdup( buf );
 
504
}
 
505
 
 
506
char*
 
507
tr_basename( const char * path )
 
508
{
 
509
    char * tmp = tr_strdup( path );
 
510
    char * ret = tr_strdup( basename( tmp ) );
 
511
    tr_free( tmp );
 
512
    return ret;
 
513
}
 
514
 
 
515
char*
 
516
tr_dirname( const char * path )
 
517
{
 
518
    char * tmp = tr_strdup( path );
 
519
    char * ret = tr_strdup( dirname( tmp ) );
 
520
    tr_free( tmp );
 
521
    return ret;
 
522
}
 
523
 
463
524
int
464
 
tr_mkdir( const char * path, int permissions 
 
525
tr_mkdir( const char * path,
 
526
          int permissions
465
527
#ifdef WIN32
466
 
                                             UNUSED
 
528
                       UNUSED
467
529
#endif
468
 
                                                    )
 
530
        )
469
531
{
470
532
#ifdef WIN32
471
 
    if( path && isalpha(path[0]) && path[1]==':' && !path[2] )
 
533
    if( path && isalpha( path[0] ) && path[1] == ':' && !path[2] )
472
534
        return 0;
473
535
    return mkdir( path );
474
536
#else
477
539
}
478
540
 
479
541
int
480
 
tr_mkdirp( const char * path_in, int permissions )
 
542
tr_mkdirp( const char * path_in,
 
543
           int          permissions )
481
544
{
482
 
    char * path = tr_strdup( path_in );
483
 
    char * p, * pp;
 
545
    char *      path = tr_strdup( path_in );
 
546
    char *      p, * pp;
484
547
    struct stat sb;
485
 
    int done;
 
548
    int         done;
486
549
 
487
550
    /* walk past the root */
488
551
    p = path;
491
554
 
492
555
    pp = p;
493
556
    done = 0;
494
 
    while( ( p = strchr( pp, TR_PATH_DELIMITER ) ) || ( p = strchr( pp, '\0' ) ) )
 
557
    while( ( p =
 
558
                strchr( pp, TR_PATH_DELIMITER ) ) || ( p = strchr( pp, '\0' ) ) )
495
559
    {
496
560
        if( !*p )
497
561
            done = 1;
501
565
        if( stat( path, &sb ) )
502
566
        {
503
567
            /* Folder doesn't exist yet */
504
 
            if( tr_mkdir( path, permissions ) ) {
 
568
            if( tr_mkdir( path, permissions ) )
 
569
            {
505
570
                const int err = errno;
506
 
                tr_err( _( "Couldn't create \"%1$s\": %2$s" ), path, tr_strerror( err ) );
 
571
                tr_err( _(
 
572
                           "Couldn't create \"%1$s\": %2$s" ), path,
 
573
                       tr_strerror( err ) );
507
574
                tr_free( path );
508
575
                errno = err;
509
576
                return -1;
512
579
        else if( ( sb.st_mode & S_IFMT ) != S_IFDIR )
513
580
        {
514
581
            /* Node exists but isn't a folder */
515
 
            char buf[MAX_PATH_LENGTH];
516
 
            tr_snprintf( buf, sizeof( buf ), _( "File \"%s\" is in the way" ), path );
 
582
            char * buf = tr_strdup_printf( _( "File \"%s\" is in the way" ), path );
517
583
            tr_err( _( "Couldn't create \"%1$s\": %2$s" ), path_in, buf );
 
584
            tr_free( buf );
518
585
            tr_free( path );
519
586
            errno = ENOTDIR;
520
587
            return -1;
532
599
    return 0;
533
600
}
534
601
 
535
 
void
536
 
tr_buildPath ( char *buf, size_t buflen, const char *first_element, ... )
 
602
char*
 
603
tr_buildPath( const char *first_element, ... )
537
604
{
538
 
    struct evbuffer * evbuf;
539
 
    const char * element = first_element;
 
605
    size_t bufLen = 0;
 
606
    const char * element;
 
607
    char * buf;
 
608
    char * pch;
540
609
    va_list vl;
541
610
 
542
 
    evbuf = evbuffer_new( );
543
 
    va_start( vl, first_element );
544
 
 
545
 
    while( element ) {
546
 
        if( EVBUFFER_LENGTH(evbuf) )
547
 
            evbuffer_add_printf( evbuf, "%c", TR_PATH_DELIMITER );
548
 
        evbuffer_add_printf( evbuf, "%s", element );
549
 
        element = (const char*) va_arg( vl, const char* );
550
 
    }
551
 
    if( EVBUFFER_LENGTH(evbuf) )
552
 
        tr_strlcpy( buf, (char*)EVBUFFER_DATA(evbuf), buflen );
553
 
    else
554
 
        *buf = '\0';
555
 
 
556
 
    va_end( vl );
557
 
    evbuffer_free( evbuf );
558
 
}
559
 
 
560
 
int
561
 
tr_ioErrorFromErrno( int err )
562
 
{
563
 
    switch( err )
564
 
    {
565
 
        case 0:
566
 
            return TR_OK;
567
 
        case EACCES:
568
 
        case EROFS:
569
 
            return TR_ERROR_IO_PERMISSIONS;
570
 
        case ENOSPC:
571
 
            return TR_ERROR_IO_SPACE;
572
 
        case EMFILE:
573
 
            return TR_ERROR_IO_OPEN_FILES;
574
 
        case EFBIG:
575
 
            return TR_ERROR_IO_FILE_TOO_BIG;
576
 
        default:
577
 
            tr_err( "generic i/o errno from errno: %s", tr_strerror( errno ) );
578
 
            return TR_ERROR_IO_OTHER;
579
 
    }
580
 
}
581
 
 
582
 
const char *
583
 
tr_errorString( int code )
584
 
{
585
 
    switch( code )
586
 
    {
587
 
        case TR_OK:
588
 
            return _( "No error" );
589
 
 
590
 
        case TR_ERROR:
591
 
            return _( "Unspecified error" );
592
 
        case TR_ERROR_ASSERT:
593
 
            return _( "Assert error" );
594
 
 
595
 
        case TR_ERROR_IO_PARENT:
596
 
            return _( "Destination folder doesn't exist" );
597
 
        case TR_ERROR_IO_PERMISSIONS:
598
 
            return tr_strerror( EACCES );
599
 
        case TR_ERROR_IO_SPACE:
600
 
            return tr_strerror( ENOSPC );
601
 
        case TR_ERROR_IO_FILE_TOO_BIG:
602
 
            return tr_strerror( EFBIG );
603
 
        case TR_ERROR_IO_OPEN_FILES:
604
 
            return tr_strerror( EMFILE );
605
 
        case TR_ERROR_IO_DUP_DOWNLOAD:
606
 
            return _( "A torrent with this name and destination folder already exists." );
607
 
        case TR_ERROR_IO_CHECKSUM:
608
 
            return _( "Checksum failed" );
609
 
        case TR_ERROR_IO_OTHER:
610
 
            return _( "Unspecified I/O error" );
611
 
 
612
 
        case TR_ERROR_TC_ERROR:
613
 
            return _( "Tracker error" );
614
 
        case TR_ERROR_TC_WARNING:
615
 
            return _( "Tracker warning" );
616
 
 
617
 
        case TR_ERROR_PEER_MESSAGE:
618
 
            return _( "Peer sent a bad message" );
619
 
 
620
 
        default:
621
 
            return _( "Unknown error" );
622
 
    }
 
611
    /* pass 1: allocate enough space for the string */
 
612
    va_start( vl, first_element );
 
613
    element = first_element;
 
614
    while( element ) {
 
615
        bufLen += strlen( element ) + 1;
 
616
        element = (const char*) va_arg( vl, const char* );
 
617
    }
 
618
    pch = buf = tr_new( char, bufLen );
 
619
    va_end( vl );
 
620
 
 
621
    /* pass 2: build the string piece by piece */
 
622
    va_start( vl, first_element );
 
623
    element = first_element;
 
624
    while( element ) {
 
625
        const size_t elementLen = strlen( element );
 
626
        memcpy( pch, element, elementLen );
 
627
        pch += elementLen;
 
628
        *pch++ = TR_PATH_DELIMITER;
 
629
        element = (const char*) va_arg( vl, const char* );
 
630
    }
 
631
    va_end( vl );
 
632
 
 
633
    /* terminate the string.  if nonempty, eat the unwanted trailing slash */
 
634
    if( pch != buf )
 
635
        --pch;
 
636
    *pch++ = '\0';
 
637
 
 
638
    /* sanity checks & return */
 
639
    assert( pch - buf == (off_t)bufLen );
 
640
    return buf;
623
641
}
624
642
 
625
643
/****
627
645
****/
628
646
 
629
647
void*
630
 
tr_memdup( const void * in, int byteCount )
 
648
tr_memdup( const void * in,
 
649
           int          byteCount )
631
650
{
632
651
    void * out = tr_new( uint8_t, byteCount );
 
652
 
633
653
    memcpy( out, in, byteCount );
634
654
    return out;
635
655
}
636
 
    
 
656
 
637
657
char*
638
658
tr_strdup( const void * in )
639
659
{
640
 
    return tr_strndup( in, in ? strlen((const char*)in) : 0 );
 
660
    return tr_strndup( in, in ? strlen( (const char*)in ) : 0 );
641
661
}
642
662
 
643
663
char*
644
 
tr_strndup( const void * in, int len )
 
664
tr_strndup( const void * in,
 
665
            int          len )
645
666
{
646
667
    char * out = NULL;
647
668
 
651
672
    }
652
673
    else if( in )
653
674
    {
654
 
        out = tr_malloc( len+1 );
 
675
        out = tr_malloc( len + 1 );
655
676
        memcpy( out, in, len );
656
677
        out[len] = '\0';
657
678
    }
660
681
}
661
682
 
662
683
char*
663
 
tr_strdup_printf( const char * fmt, ... )
 
684
tr_strdup_printf( const char * fmt,
 
685
                  ... )
664
686
{
665
 
    char * ret = NULL;
 
687
    char *            ret = NULL;
666
688
    struct evbuffer * buf;
667
 
    va_list ap;
 
689
    va_list           ap;
668
690
 
669
691
    buf = evbuffer_new( );
670
692
    va_start( ap, fmt );
671
693
 
672
694
    if( evbuffer_add_vprintf( buf, fmt, ap ) != -1 )
673
 
        ret = tr_strdup( (char*)EVBUFFER_DATA( buf ) );
 
695
        ret = tr_strdup( EVBUFFER_DATA( buf ) );
674
696
 
675
697
    va_end( ap );
676
698
    evbuffer_free( buf );
678
700
}
679
701
 
680
702
void*
681
 
tr_calloc( size_t nmemb, size_t size )
682
 
{
683
 
    return nmemb && size ? calloc( nmemb, size ) : NULL;
684
 
}
685
 
 
686
 
void*
687
703
tr_malloc( size_t size )
688
704
{
689
705
    return size ? malloc( size ) : NULL;
692
708
void*
693
709
tr_malloc0( size_t size )
694
710
{
695
 
    void * ret = tr_malloc( size );
696
 
    memset( ret, 0, size );
697
 
    return ret;
 
711
    return size ? calloc( 1, size ) : NULL;
698
712
}
699
713
 
700
714
void
708
722
tr_strerror( int i )
709
723
{
710
724
    const char * ret = strerror( i );
 
725
 
711
726
    if( ret == NULL )
712
727
        ret = "Unknown Error";
713
728
    return ret;
717
732
*****
718
733
****/
719
734
 
 
735
char*
 
736
tr_strstrip( char * str )
 
737
{
 
738
    if( str != NULL )
 
739
    {
 
740
        size_t pos;
 
741
        size_t len = strlen( str );
 
742
 
 
743
        while( len && isspace( str[len - 1] ) )
 
744
            --len;
 
745
 
 
746
        str[len] = '\0';
 
747
 
 
748
        for( pos = 0; pos < len && isspace( str[pos] ); )
 
749
            ++pos;
 
750
 
 
751
        len -= pos;
 
752
        memmove( str, str + pos, len );
 
753
        str[len] = '\0';
 
754
    }
 
755
 
 
756
    return str;
 
757
}
 
758
 
 
759
/****
 
760
*****
 
761
****/
 
762
 
720
763
tr_bitfield*
721
764
tr_bitfieldNew( size_t bitCount )
722
765
{
723
766
    tr_bitfield * ret = tr_new0( tr_bitfield, 1 );
 
767
 
724
768
    ret->bitCount = bitCount;
725
 
    ret->byteCount = (bitCount+7u) / 8u;
 
769
    ret->byteCount = ( bitCount + 7u ) / 8u;
726
770
    ret->bits = tr_new0( uint8_t, ret->byteCount );
727
771
    return ret;
728
772
}
730
774
tr_bitfield*
731
775
tr_bitfieldDup( const tr_bitfield * in )
732
776
{
733
 
    tr_bitfield * ret = calloc( 1, sizeof(tr_bitfield) );
 
777
    tr_bitfield * ret = tr_new0( tr_bitfield, 1 );
 
778
 
734
779
    ret->bitCount = in->bitCount;
735
780
    ret->byteCount = in->byteCount;
736
781
    ret->bits = tr_memdup( in->bits, in->byteCount );
758
803
{
759
804
    size_t i;
760
805
 
761
 
    for( i=0; i<bitfield->byteCount; ++i )
 
806
    for( i = 0; i < bitfield->byteCount; ++i )
762
807
        if( bitfield->bits[i] )
763
808
            return 0;
764
809
 
766
811
}
767
812
 
768
813
int
769
 
tr_bitfieldHas( const tr_bitfield * bitfield, size_t nth )
770
 
{
771
 
    return ( tr_bitfieldTestFast( bitfield, nth ) )
772
 
        && ( tr_bitfieldHasFast( bitfield, nth ) );
773
 
}
774
 
 
775
 
#if 0
776
 
static int
777
 
find_top_bit( uint8_t val )
778
 
{
779
 
    int pos = 0;
780
 
    if ( val & 0xF0U ) pos |= 4, val >>= 4;
781
 
    if ( val & 0xCU )  pos |= 2, val >>= 2;
782
 
    if ( val & 0x2 )   pos |= 1;
783
 
    return 7 - pos;
784
 
}
785
 
 
786
 
int
787
 
tr_bitfieldFindTrue( const tr_bitfield  * bitfield,
788
 
                     size_t               startBit,
789
 
                     size_t             * setmePos )
790
 
{
791
 
    if( bitfield && bitfield->bits && startBit < bitfield->bitCount )
792
 
    {
793
 
        const uint8_t * b   = bitfield->bits + startBit/8;
794
 
        const uint8_t * end = bitfield->bits + bitfield->byteCount;
795
 
 
796
 
        /* If first byte already contains a set bit after startBit*/
797
 
        if( *b & ( 0xff >> (startBit&7) ) ) {
798
 
            *setmePos  = 8 * ( b - bitfield->bits );
799
 
            *setmePos += find_top_bit( *b & ( 0xff >> (startBit&7) ) );
800
 
            return 1;
801
 
        }
802
 
 
803
 
        /* Test bitfield for first non zero byte */
804
 
        ++b;
805
 
        while( (b < end) && !*b )
806
 
            ++b;
807
 
 
808
 
        /* If we hit the end of our bitfield, no set bit was found */
809
 
        if( b == end )
810
 
            return 0;
811
 
 
812
 
        /* New bitposition is byteoff*8 */
813
 
        *setmePos = 8 * ( b - bitfield->bits ) + find_top_bit( *b );
814
 
 
815
 
        return 1;
816
 
    }
817
 
 
818
 
    return 0;
819
 
}
820
 
#endif
821
 
 
822
 
int
823
 
tr_bitfieldAdd( tr_bitfield  * bitfield, size_t nth )
824
 
{
825
 
    assert( bitfield );
826
 
    assert( bitfield->bits );
827
 
 
828
 
    if( nth >= bitfield->bitCount )
829
 
        return -1;
830
 
 
831
 
    bitfield->bits[nth>>3u] |= (0x80 >> (nth&7u));
832
 
    return 0;
833
 
}
834
 
 
835
 
int
836
 
tr_bitfieldAddRange( tr_bitfield  * bitfield,
837
 
                     size_t         begin,
838
 
                     size_t         end )
839
 
{
840
 
    int err = 0;
841
 
    size_t i;
842
 
    for( i=begin; i<end; ++i )
843
 
        if(( err = tr_bitfieldAdd( bitfield, i )))
844
 
            break;
845
 
    return err;
846
 
}
847
 
 
848
 
int
849
 
tr_bitfieldRem( tr_bitfield   * bitfield,
850
 
                size_t          nth )
851
 
{
852
 
    assert( bitfield );
853
 
    assert( bitfield->bits );
854
 
 
855
 
    if( nth >= bitfield->bitCount )
856
 
        return -1;
857
 
 
858
 
    bitfield->bits[nth>>3u] &= (0xff7f >> (nth&7u));
859
 
    return 0;
860
 
}
861
 
 
862
 
int
863
 
tr_bitfieldRemRange ( tr_bitfield  * b,
864
 
                      size_t         begin,
865
 
                      size_t         end )
866
 
{
867
 
    int err = 0;
868
 
    size_t i;
869
 
    for( i=begin; i<end; ++i )
870
 
        if(( err = tr_bitfieldRem( b, i )))
871
 
            break;
872
 
    return err;
 
814
tr_bitfieldAdd( tr_bitfield * bitfield,
 
815
                size_t        nth )
 
816
{
 
817
    assert( bitfield );
 
818
    assert( bitfield->bits );
 
819
 
 
820
    if( nth >= bitfield->bitCount )
 
821
        return -1;
 
822
 
 
823
    bitfield->bits[nth >> 3u] |= ( 0x80 >> ( nth & 7u ) );
 
824
    return 0;
 
825
}
 
826
 
 
827
/* Sets bit range [begin, end) to 1 */
 
828
int
 
829
tr_bitfieldAddRange( tr_bitfield * b,
 
830
                     size_t        begin,
 
831
                     size_t        end )
 
832
{
 
833
    size_t        sb, eb;
 
834
    unsigned char sm, em;
 
835
 
 
836
    end--;
 
837
 
 
838
    if( ( end >= b->bitCount ) || ( begin > end ) )
 
839
        return -1;
 
840
 
 
841
    sb = begin >> 3;
 
842
    sm = ~( 0xff << ( 8 - ( begin & 7 ) ) );
 
843
    eb = end >> 3;
 
844
    em = 0xff << ( 7 - ( end & 7 ) );
 
845
 
 
846
    if( sb == eb )
 
847
    {
 
848
        b->bits[sb] |= ( sm & em );
 
849
    }
 
850
    else
 
851
    {
 
852
        b->bits[sb] |= sm;
 
853
        b->bits[eb] |= em;
 
854
        if( ++sb < eb )
 
855
            memset ( b->bits + sb, 0xff, eb - sb );
 
856
    }
 
857
 
 
858
    return 0;
 
859
}
 
860
 
 
861
int
 
862
tr_bitfieldRem( tr_bitfield * bitfield,
 
863
                size_t        nth )
 
864
{
 
865
    assert( bitfield );
 
866
    assert( bitfield->bits );
 
867
 
 
868
    if( nth >= bitfield->bitCount )
 
869
        return -1;
 
870
 
 
871
    bitfield->bits[nth >> 3u] &= ( 0xff7f >> ( nth & 7u ) );
 
872
    return 0;
 
873
}
 
874
 
 
875
/* Clears bit range [begin, end) to 0 */
 
876
int
 
877
tr_bitfieldRemRange( tr_bitfield * b,
 
878
                     size_t        begin,
 
879
                     size_t        end )
 
880
{
 
881
    size_t        sb, eb;
 
882
    unsigned char sm, em;
 
883
 
 
884
    end--;
 
885
 
 
886
    if( ( end >= b->bitCount ) || ( begin > end ) )
 
887
        return -1;
 
888
 
 
889
    sb = begin >> 3;
 
890
    sm = 0xff << ( 8 - ( begin & 7 ) );
 
891
    eb = end >> 3;
 
892
    em = ~( 0xff << ( 7 - ( end & 7 ) ) );
 
893
 
 
894
    if( sb == eb )
 
895
    {
 
896
        b->bits[sb] &= ( sm | em );
 
897
    }
 
898
    else
 
899
    {
 
900
        b->bits[sb] &= sm;
 
901
        b->bits[eb] &= em;
 
902
        if( ++sb < eb )
 
903
            memset ( b->bits + sb, 0, eb - sb );
 
904
    }
 
905
 
 
906
    return 0;
873
907
}
874
908
 
875
909
tr_bitfield*
876
 
tr_bitfieldOr( tr_bitfield * a, const tr_bitfield * b )
 
910
tr_bitfieldOr( tr_bitfield *       a,
 
911
               const tr_bitfield * b )
877
912
{
878
 
    uint8_t *ait;
 
913
    uint8_t *      ait;
879
914
    const uint8_t *aend, *bit;
880
915
 
881
916
    assert( a->bitCount == b->bitCount );
882
917
 
883
 
    for( ait=a->bits, bit=b->bits, aend=ait+a->byteCount; ait!=aend; )
 
918
    for( ait = a->bits, bit = b->bits, aend = ait + a->byteCount;
 
919
         ait != aend; )
884
920
        *ait++ |= *bit++;
885
921
 
886
922
    return a;
888
924
 
889
925
/* set 'a' to all the flags that were in 'a' but not 'b' */
890
926
void
891
 
tr_bitfieldDifference( tr_bitfield * a, const tr_bitfield * b )
 
927
tr_bitfieldDifference( tr_bitfield *       a,
 
928
                       const tr_bitfield * b )
892
929
{
893
 
    uint8_t *ait;
 
930
    uint8_t *      ait;
894
931
    const uint8_t *aend, *bit;
895
932
 
896
933
    assert( a->bitCount == b->bitCount );
897
934
 
898
 
    for( ait=a->bits, bit=b->bits, aend=ait+a->byteCount; ait!=aend; )
899
 
        *ait++ &= ~(*bit++);
 
935
    for( ait = a->bits, bit = b->bits, aend = ait + a->byteCount;
 
936
         ait != aend; )
 
937
        *ait++ &= ~( *bit++ );
900
938
}
901
939
 
902
 
 
903
940
size_t
904
941
tr_bitfieldCountTrueBits( const tr_bitfield* b )
905
942
{
906
 
    size_t ret = 0;
907
 
    const uint8_t *it, *end;
 
943
    size_t           ret = 0;
 
944
    const uint8_t *  it, *end;
908
945
    static const int trueBitCount[512] = {
909
 
        0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
910
 
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
911
 
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
912
 
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
913
 
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
914
 
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
915
 
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
916
 
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
917
 
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
918
 
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
919
 
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
920
 
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
921
 
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
922
 
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
923
 
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
924
 
        4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9
 
946
        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3,
 
947
        4, 2, 3, 3, 4, 3, 4, 4, 5,
 
948
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4,
 
949
        5, 3, 4, 4, 5, 4, 5, 5, 6,
 
950
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4,
 
951
        5, 3, 4, 4, 5, 4, 5, 5, 6,
 
952
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5,
 
953
        6, 4, 5, 5, 6, 5, 6, 6, 7,
 
954
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4,
 
955
        5, 3, 4, 4, 5, 4, 5, 5, 6,
 
956
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5,
 
957
        6, 4, 5, 5, 6, 5, 6, 6, 7,
 
958
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5,
 
959
        6, 4, 5, 5, 6, 5, 6, 6, 7,
 
960
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6,
 
961
        7, 5, 6, 6, 7, 6, 7, 7, 8,
 
962
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4,
 
963
        5, 3, 4, 4, 5, 4, 5, 5, 6,
 
964
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5,
 
965
        6, 4, 5, 5, 6, 5, 6, 6, 7,
 
966
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5,
 
967
        6, 4, 5, 5, 6, 5, 6, 6, 7,
 
968
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6,
 
969
        7, 5, 6, 6, 7, 6, 7, 7, 8,
 
970
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5,
 
971
        6, 4, 5, 5, 6, 5, 6, 6, 7,
 
972
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6,
 
973
        7, 5, 6, 6, 7, 6, 7, 7, 8,
 
974
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6,
 
975
        7, 5, 6, 6, 7, 6, 7, 7, 8,
 
976
        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, 5, 6, 6, 7, 6, 7, 7,
 
977
        8, 6, 7, 7, 8, 7, 8, 8, 9
925
978
    };
926
979
 
927
980
    if( !b )
928
981
        return 0;
929
982
 
930
 
    for( it=b->bits, end=it+b->byteCount; it!=end; ++it )
 
983
    for( it = b->bits, end = it + b->byteCount; it != end; ++it )
931
984
        ret += trueBitCount[*it];
932
985
 
933
986
    return ret;
941
994
tr_date( void )
942
995
{
943
996
    struct timeval tv;
 
997
 
944
998
    gettimeofday( &tv, NULL );
945
999
    return (uint64_t) tv.tv_sec * 1000 + ( tv.tv_usec / 1000 );
946
1000
}
950
1004
{
951
1005
#ifdef __BEOS__
952
1006
    snooze( 1000 * delay_milliseconds );
953
 
#elif defined(WIN32)
 
1007
#elif defined( WIN32 )
954
1008
    Sleep( (DWORD)delay_milliseconds );
955
1009
#else
956
1010
    usleep( 1000 * delay_milliseconds );
962
1016
***/
963
1017
 
964
1018
int
965
 
tr_stringEndsWith( const char * str, const char * end )
966
 
{
967
 
    const size_t slen = strlen( str );
968
 
    const size_t elen = strlen( end );
969
 
    return slen>=elen && !memcmp( &str[slen-elen], end, elen );
970
 
}
971
 
 
972
 
int
973
 
tr_snprintf( char * buf, size_t buflen, const char * fmt, ... )
974
 
{
975
 
    int len;
 
1019
tr_snprintf( char *       buf,
 
1020
             size_t       buflen,
 
1021
             const char * fmt,
 
1022
             ... )
 
1023
{
 
1024
    int     len;
976
1025
    va_list args;
 
1026
 
977
1027
    va_start( args, fmt );
978
1028
    len = evutil_vsnprintf( buf, buflen, fmt, args );
979
1029
    va_end( args );
980
1030
    return len;
981
1031
}
982
1032
 
983
 
 
984
1033
/*
985
1034
 * Copy src to string dst of size siz.  At most siz-1 characters
986
1035
 * will be copied.  Always NUL terminates (unless siz == 0).
987
1036
 * Returns strlen(src); if retval >= siz, truncation occurred.
988
1037
 */
989
1038
size_t
990
 
tr_strlcpy(char *dst, const char *src, size_t siz)
 
1039
tr_strlcpy( char *       dst,
 
1040
            const void * src,
 
1041
            size_t       siz )
991
1042
{
992
1043
#ifdef HAVE_STRLCPY
993
1044
    return strlcpy( dst, src, siz );
994
1045
#else
995
 
    char *d = dst;
 
1046
    char *      d = dst;
996
1047
    const char *s = src;
997
 
    size_t n = siz;
 
1048
    size_t      n = siz;
998
1049
 
999
1050
    assert( s );
1000
1051
    assert( d );
1001
1052
 
1002
1053
    /* Copy as many bytes as will fit */
1003
 
    if (n != 0) {
1004
 
        while (--n != 0) {
1005
 
            if ((*d++ = *s++) == '\0')
 
1054
    if( n != 0 )
 
1055
    {
 
1056
        while( --n != 0 )
 
1057
        {
 
1058
            if( ( *d++ = *s++ ) == '\0' )
1006
1059
                break;
1007
1060
        }
1008
1061
    }
1009
1062
 
1010
1063
    /* Not enough room in dst, add NUL and traverse rest of src */
1011
 
    if (n == 0) {
1012
 
        if (siz != 0)
 
1064
    if( n == 0 )
 
1065
    {
 
1066
        if( siz != 0 )
1013
1067
            *d = '\0'; /* NUL-terminate dst */
1014
 
        while (*s++)
 
1068
        while( *s++ )
1015
1069
            ;
1016
1070
    }
1017
1071
 
1018
 
    return(s - src - 1); /* count does not include NUL */
 
1072
    return s - (char*)src - 1;  /* count does not include NUL */
1019
1073
#endif
1020
1074
}
1021
1075
 
1024
1078
***/
1025
1079
 
1026
1080
double
1027
 
tr_getRatio( double numerator, double denominator )
 
1081
tr_getRatio( double numerator,
 
1082
             double denominator )
1028
1083
{
1029
1084
    double ratio;
1030
1085
 
1039
1094
}
1040
1095
 
1041
1096
void
1042
 
tr_sha1_to_hex( char * out, const uint8_t * sha1 )
 
1097
tr_sha1_to_hex( char *          out,
 
1098
                const uint8_t * sha1 )
1043
1099
{
1044
1100
    static const char hex[] = "0123456789abcdef";
1045
 
    int i;
1046
 
    for (i = 0; i < 20; i++) {
 
1101
    int               i;
 
1102
 
 
1103
    for( i = 0; i < 20; i++ )
 
1104
    {
1047
1105
        unsigned int val = *sha1++;
1048
1106
        *out++ = hex[val >> 4];
1049
1107
        *out++ = hex[val & 0xf];
1058
1116
int
1059
1117
tr_httpIsValidURL( const char * url )
1060
1118
{
1061
 
    const char * c;
 
1119
    const char *        c;
1062
1120
    static const char * rfc2396_valid_chars =
1063
1121
        "abcdefghijklmnopqrstuvwxyz" /* lowalpha */
1064
1122
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* upalpha */
1071
1129
    if( url == NULL )
1072
1130
        return FALSE;
1073
1131
 
1074
 
    for( c=url; c && *c; ++c )
 
1132
    for( c = url; c && *c; ++c )
1075
1133
        if( !strchr( rfc2396_valid_chars, *c ) )
1076
1134
            return FALSE;
1077
1135
 
1079
1137
}
1080
1138
 
1081
1139
int
1082
 
tr_httpParseURL( const char * url_in, int len,
1083
 
                 char ** setme_host,
1084
 
                 int * setme_port,
1085
 
                 char ** setme_path )
 
1140
tr_httpParseURL( const char * url_in,
 
1141
                 int          len,
 
1142
                 char **      setme_host,
 
1143
                 int *        setme_port,
 
1144
                 char **      setme_path )
1086
1145
{
1087
 
    int err;
1088
 
    int port = 0;
1089
 
    int n;
1090
 
    char * tmp;
1091
 
    char * pch;
 
1146
    int          err;
 
1147
    int          port = 0;
 
1148
    int          n;
 
1149
    char *       tmp;
 
1150
    char *       pch;
1092
1151
    const char * protocol = NULL;
1093
1152
    const char * host = NULL;
1094
1153
    const char * path = NULL;
1095
1154
 
1096
1155
    tmp = tr_strndup( url_in, len );
1097
 
    if(( pch = strstr( tmp, "://" )))
 
1156
    if( ( pch = strstr( tmp, "://" ) ) )
1098
1157
    {
1099
 
       *pch = '\0';
1100
 
       protocol = tmp;
1101
 
       pch += 3;
1102
 
/*fprintf( stderr, "protocol is [%s]... what's left is [%s]\n", protocol, pch );*/
1103
 
       if(( n = strcspn( pch, ":/" )))
1104
 
       {
1105
 
           const int havePort = pch[n] == ':';
1106
 
           host = pch;
1107
 
           pch += n;
1108
 
           *pch++ = '\0';
 
1158
        *pch = '\0';
 
1159
        protocol = tmp;
 
1160
        pch += 3;
 
1161
/*fprintf( stderr, "protocol is [%s]... what's left is [%s]\n", protocol, pch
 
1162
  );*/
 
1163
        if( ( n = strcspn( pch, ":/" ) ) )
 
1164
        {
 
1165
            const int havePort = pch[n] == ':';
 
1166
            host = pch;
 
1167
            pch += n;
 
1168
            *pch++ = '\0';
1109
1169
/*fprintf( stderr, "host is [%s]... what's left is [%s]\n", host, pch );*/
1110
 
           if( havePort )
1111
 
           {
1112
 
               char * end;
1113
 
               port = strtol( pch, &end, 10 );
1114
 
               pch = end;
 
1170
            if( havePort )
 
1171
            {
 
1172
                char * end;
 
1173
                port = strtol( pch, &end, 10 );
 
1174
                pch = end;
1115
1175
/*fprintf( stderr, "port is [%d]... what's left is [%s]\n", port, pch );*/
1116
 
           }
1117
 
           path = pch;
 
1176
            }
 
1177
            path = pch;
1118
1178
/*fprintf( stderr, "path is [%s]\n", path );*/
1119
 
       }
1120
 
    }
1121
 
 
1122
 
    err = !host || !path || !protocol || ( strcmp(protocol,"http") && strcmp(protocol,"https") );
1123
 
 
1124
 
    if( !err && !port ) {
1125
 
        if( !strcmp(protocol,"http") ) port = 80;
1126
 
        if( !strcmp(protocol,"https") ) port = 443;
1127
 
    }
1128
 
 
1129
 
    if( !err ) {
1130
 
        if( setme_host) { ((char*)host)[-3]=':'; *setme_host = tr_strdup( protocol ); }
1131
 
        if( setme_path) { ((char*)path)[-1]='/'; *setme_path = tr_strdup( path-1 ); }
1132
 
        if( setme_port) *setme_port = port;
 
1179
        }
 
1180
    }
 
1181
 
 
1182
    err = !host || !path || !protocol
 
1183
          || ( strcmp( protocol, "http" ) && strcmp( protocol, "https" ) );
 
1184
 
 
1185
    if( !err && !port )
 
1186
    {
 
1187
        if( !strcmp( protocol, "http" ) ) port = 80;
 
1188
        if( !strcmp( protocol, "https" ) ) port = 443;
 
1189
    }
 
1190
 
 
1191
    if( !err )
 
1192
    {
 
1193
        if( setme_host ){ ( (char*)host )[-3] = ':'; *setme_host =
 
1194
                              tr_strdup( protocol ); }
 
1195
        if( setme_path ){ ( (char*)path )[-1] = '/'; *setme_path =
 
1196
                              tr_strdup( path - 1 ); }
 
1197
        if( setme_port ) *setme_port = port;
1133
1198
    }
1134
1199
 
1135
1200
 
1145
1210
#include <openssl/buffer.h>
1146
1211
 
1147
1212
char *
1148
 
tr_base64_encode( const void * input, int length, int * setme_len )
 
1213
tr_base64_encode( const void * input,
 
1214
                  int          length,
 
1215
                  int *        setme_len )
1149
1216
{
1150
 
    char * ret;
1151
 
    BIO * b64;
1152
 
    BIO * bmem;
 
1217
    char *    ret;
 
1218
    BIO *     b64;
 
1219
    BIO *     bmem;
1153
1220
    BUF_MEM * bptr;
1154
1221
 
1155
1222
    if( length < 1 )
1156
 
       length = strlen( input );
 
1223
        length = strlen( input );
1157
1224
 
1158
1225
    bmem = BIO_new( BIO_s_mem( ) );
1159
1226
    b64 = BIO_new( BIO_f_base64( ) );
1170
1237
}
1171
1238
 
1172
1239
char *
1173
 
tr_base64_decode( const void * input, int length, int * setme_len )
 
1240
tr_base64_decode( const void * input,
 
1241
                  int          length,
 
1242
                  int *        setme_len )
1174
1243
{
1175
1244
    char * ret;
1176
 
    BIO * b64;
1177
 
    BIO * bmem;
1178
 
    int retlen;
 
1245
    BIO *  b64;
 
1246
    BIO *  bmem;
 
1247
    int    retlen;
1179
1248
 
1180
1249
    if( length < 1 )
1181
 
       length = strlen( input );
 
1250
        length = strlen( input );
1182
1251
 
1183
1252
    ret = tr_new0( char, length );
1184
1253
    b64 = BIO_new( BIO_f_base64( ) );
1202
1271
    BIO_free_all( bmem );
1203
1272
    return ret;
1204
1273
}
 
1274