~sense/ubuntu/lucid/transmission/fix-497882

« back to all changes in this revision

Viewing changes to libtransmission/session.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:
3
3
 *
4
4
 * This file is licensed by the GPL version 2.  Works owned by the
5
5
 * Transmission project are granted a special exemption to clause 2(b)
6
 
 * so that the bulk of its code can remain under the MIT license. 
 
6
 * so that the bulk of its code can remain under the MIT license.
7
7
 * This exemption does not extend to derived works not owned by
8
8
 * the Transmission project.
9
9
 *
10
 
 * $Id: session.c 6425 2008-08-01 16:43:22Z charles $
 
10
 * $Id: session.c 7069 2008-11-08 02:49:04Z charles $
11
11
 */
12
12
 
13
13
#include <assert.h>
37
37
#include "trevent.h"
38
38
#include "utils.h"
39
39
#include "web.h"
 
40
#include "crypto.h"
40
41
 
41
42
/* Generate a peer id : "-TRxyzb-" + 12 random alphanumeric
42
43
   characters, where x is the major version number, y is the
45
46
uint8_t*
46
47
tr_peerIdNew( void )
47
48
{
48
 
    int i;
49
 
    int val;
50
 
    int total = 0;
51
 
    uint8_t * buf = tr_new( uint8_t, 21 );
 
49
    int          i;
 
50
    int          val;
 
51
    int          total = 0;
 
52
    uint8_t *    buf = tr_new( uint8_t, 21 );
52
53
    const char * pool = "0123456789abcdefghijklmnopqrstuvwxyz";
53
 
    const int base = 36;
 
54
    const int    base = 36;
54
55
 
55
56
    memcpy( buf, PEERID_PREFIX, 8 );
56
57
 
57
 
    for( i=8; i<19; ++i ) {
58
 
        val = tr_rand( base );
 
58
    for( i = 8; i < 19; ++i )
 
59
    {
 
60
        val = tr_cryptoRandInt( base );
59
61
        total += val;
60
62
        buf[i] = pool[val];
61
63
    }
62
64
 
63
 
    val = total % base ? base - (total % base) : 0;
 
65
    val = total % base ? base - ( total % base ) : 0;
64
66
    buf[19] = pool[val];
65
67
    buf[20] = '\0';
66
68
 
71
73
tr_getPeerId( void )
72
74
{
73
75
    static uint8_t * id = NULL;
 
76
 
74
77
    if( id == NULL )
75
78
        id = tr_peerIdNew( );
76
79
    return id;
89
92
}
90
93
 
91
94
void
92
 
tr_sessionSetEncryption( tr_session * session, tr_encryption_mode mode )
 
95
tr_sessionSetEncryption( tr_session *       session,
 
96
                         tr_encryption_mode mode )
93
97
{
94
98
    assert( session );
95
 
    assert( mode==TR_ENCRYPTION_PREFERRED
96
 
         || mode==TR_ENCRYPTION_REQUIRED
97
 
         || mode==TR_PLAINTEXT_PREFERRED );
 
99
    assert( mode == TR_ENCRYPTION_PREFERRED
 
100
          || mode == TR_ENCRYPTION_REQUIRED
 
101
          || mode == TR_CLEAR_PREFERRED );
98
102
 
99
103
    session->encryptionMode = mode;
100
104
}
103
107
****
104
108
***/
105
109
 
 
110
static int
 
111
tr_stringEndsWith( const char * str,
 
112
                   const char * end )
 
113
{
 
114
    const size_t slen = strlen( str );
 
115
    const size_t elen = strlen( end );
 
116
 
 
117
    return slen >= elen && !memcmp( &str[slen - elen], end, elen );
 
118
}
 
119
 
106
120
static void
107
121
loadBlocklists( tr_session * session )
108
122
{
109
 
    int binCount = 0;
110
 
    int newCount = 0;
 
123
    int         binCount = 0;
 
124
    int         newCount = 0;
111
125
    struct stat sb;
112
 
    char dirname[MAX_PATH_LENGTH];
113
 
    DIR * odir = NULL;
114
 
    tr_list * list = NULL;
115
 
    const int isEnabled = session->isBlocklistEnabled;
 
126
    char      * dirname;
 
127
    DIR *       odir = NULL;
 
128
    tr_list *   list = NULL;
 
129
    const int   isEnabled = session->isBlocklistEnabled;
116
130
 
117
131
    /* walk through the directory and find blocklists */
118
 
    tr_buildPath( dirname, sizeof( dirname ), session->configDir, "blocklists", NULL );
119
 
    if( !stat( dirname, &sb ) && S_ISDIR( sb.st_mode ) && (( odir = opendir( dirname ))))
 
132
    dirname = tr_buildPath( session->configDir, "blocklists", NULL );
 
133
    if( !stat( dirname,
 
134
               &sb ) && S_ISDIR( sb.st_mode )
 
135
      && ( ( odir = opendir( dirname ) ) ) )
120
136
    {
121
137
        struct dirent *d;
122
 
        for( d=readdir( odir ); d; d=readdir( odir ) )
 
138
        for( d = readdir( odir ); d; d = readdir( odir ) )
123
139
        {
124
 
            char filename[MAX_PATH_LENGTH];
 
140
            char * filename;
125
141
 
126
 
            if( !d->d_name || d->d_name[0]=='.' ) /* skip dotfiles, ., and .. */
 
142
            if( !d->d_name || d->d_name[0] == '.' ) /* skip dotfiles, ., and ..
 
143
                                                      */
127
144
                continue;
128
145
 
129
 
            tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
 
146
            filename = tr_buildPath( dirname, d->d_name, NULL );
130
147
 
131
148
            if( tr_stringEndsWith( filename, ".bin" ) )
132
149
            {
133
150
                /* if we don't already have this blocklist, add it */
134
 
                if( !tr_list_find( list, filename, (TrListCompareFunc)strcmp ) )
 
151
                if( !tr_list_find( list, filename,
 
152
                                   (TrListCompareFunc)strcmp ) )
135
153
                {
136
 
                    tr_list_append( &list, _tr_blocklistNew( filename, isEnabled ) );
 
154
                    tr_list_append( &list,
 
155
                                   _tr_blocklistNew( filename, isEnabled ) );
137
156
                    ++binCount;
138
157
                }
139
158
            }
140
159
            else
141
160
            {
142
 
                /* strip out the file suffix, if there is one, and add ".bin" instead */
 
161
                /* strip out the file suffix, if there is one, and add ".bin"
 
162
                  instead */
143
163
                tr_blocklist * b;
144
 
                const char * dot = strrchr( d->d_name, '.' );
145
 
                const int len = dot ? dot - d->d_name : (int)strlen( d->d_name );
146
 
                char tmp[MAX_PATH_LENGTH];
147
 
                tr_snprintf( tmp, sizeof( tmp ),
148
 
                             "%s%c%*.*s.bin", dirname, TR_PATH_DELIMITER, len, len, d->d_name );
 
164
                const char *   dot = strrchr( d->d_name, '.' );
 
165
                const int      len = dot ? dot - d->d_name
 
166
                                         : (int)strlen( d->d_name );
 
167
                char         * tmp = tr_strdup_printf(
 
168
                                        "%s" TR_PATH_DELIMITER_STR "%*.*s.bin",
 
169
                                        dirname, len, len, d->d_name );
149
170
                b = _tr_blocklistNew( tmp, isEnabled );
150
171
                _tr_blocklistSetContent( b, filename );
151
172
                tr_list_append( &list, b );
152
173
                ++newCount;
 
174
                tr_free( tmp );
153
175
            }
 
176
 
 
177
            tr_free( filename );
154
178
        }
155
179
 
156
180
        closedir( odir );
162
186
        tr_dbg( "Found %d blocklists in \"%s\"", binCount, dirname );
163
187
    if( newCount )
164
188
        tr_dbg( "Found %d new blocklists in \"%s\"", newCount, dirname );
 
189
 
 
190
    tr_free( dirname );
165
191
}
166
192
 
167
193
/***
171
197
static void metainfoLookupRescan( tr_handle * h );
172
198
 
173
199
tr_handle *
174
 
tr_sessionInitFull( const char    * configDir,
175
 
                    const char    * tag,
176
 
                    const char    * downloadDir,
177
 
                    int             isPexEnabled,
178
 
                    int             isPortForwardingEnabled,
179
 
                    int             publicPort,
180
 
                    int             encryptionMode,
181
 
                    int             isUploadLimitEnabled,
182
 
                    int             uploadLimit,
183
 
                    int             isDownloadLimitEnabled,
184
 
                    int             downloadLimit,
185
 
                    int             globalPeerLimit,
186
 
                    int             messageLevel,
187
 
                    int             isMessageQueueingEnabled,
188
 
                    int             isBlocklistEnabled,
189
 
                    int             peerSocketTOS,
190
 
                    int             rpcIsEnabled,
191
 
                    int             rpcPort,
192
 
                    const char    * rpcACL,
193
 
                    int             rpcAuthIsEnabled,
194
 
                    const char    * rpcUsername,
195
 
                    const char    * rpcPassword,
196
 
                    int             proxyIsEnabled,
197
 
                    const char    * proxy,
198
 
                    int             proxyPort,
199
 
                    tr_proxy_type   proxyType,
200
 
                    int             proxyAuthIsEnabled,
201
 
                    const char    * proxyUsername,
202
 
                    const char    * proxyPassword )
 
200
tr_sessionInitFull( const char *       configDir,
 
201
                    const char *       tag,
 
202
                    const char *       downloadDir,
 
203
                    int                isPexEnabled,
 
204
                    int                isPortForwardingEnabled,
 
205
                    int                publicPort,
 
206
                    tr_encryption_mode encryptionMode,
 
207
                    int                useLazyBitfield,
 
208
                    int                useUploadLimit,
 
209
                    int                uploadLimit,
 
210
                    int                useDownloadLimit,
 
211
                    int                downloadLimit,
 
212
                    int                globalPeerLimit,
 
213
                    int                messageLevel,
 
214
                    int                isMessageQueueingEnabled,
 
215
                    int                isBlocklistEnabled,
 
216
                    int                peerSocketTOS,
 
217
                    int                rpcIsEnabled,
 
218
                    uint16_t           rpcPort,
 
219
                    int                rpcWhitelistIsEnabled,
 
220
                    const char *       rpcWhitelist,
 
221
                    int                rpcAuthIsEnabled,
 
222
                    const char *       rpcUsername,
 
223
                    const char *       rpcPassword,
 
224
                    int                proxyIsEnabled,
 
225
                    const char *       proxy,
 
226
                    int                proxyPort,
 
227
                    tr_proxy_type      proxyType,
 
228
                    int                proxyAuthIsEnabled,
 
229
                    const char *       proxyUsername,
 
230
                    const char *       proxyPassword )
203
231
{
204
232
    tr_handle * h;
205
 
    char filename[MAX_PATH_LENGTH];
 
233
    char      * filename;
206
234
 
207
235
#ifndef WIN32
208
236
    /* Don't exit when writing on a broken socket */
209
237
    signal( SIGPIPE, SIG_IGN );
210
238
#endif
211
239
 
212
 
    if( configDir == NULL )
213
 
        configDir = tr_getDefaultConfigDir( );
214
 
 
215
240
    tr_msgInit( );
216
241
    tr_setMessageLevel( messageLevel );
217
242
    tr_setMessageQueuing( isMessageQueueingEnabled );
226
251
    h->proxy = tr_strdup( proxy );
227
252
    h->proxyPort = proxyPort;
228
253
    h->proxyType = proxyType;
229
 
    h->isProxyAuthEnabled = proxyAuthIsEnabled ? 1 : 0;
 
254
    h->isProxyAuthEnabled = proxyAuthIsEnabled != 0;
230
255
    h->proxyUsername = tr_strdup( proxyUsername );
231
256
    h->proxyPassword = tr_strdup( proxyPassword );
 
257
    h->pieceSpeed[TR_PEER_TO_CLIENT] = tr_rcInit( );
 
258
    h->pieceSpeed[TR_CLIENT_TO_PEER] = tr_rcInit( );
 
259
    h->rawSpeed[TR_PEER_TO_CLIENT] = tr_rcInit( );
 
260
    h->rawSpeed[TR_CLIENT_TO_PEER] = tr_rcInit( );
232
261
 
 
262
    if( configDir == NULL )
 
263
        configDir = tr_getDefaultConfigDir( );
233
264
    tr_setConfigDir( h, configDir );
234
265
 
235
 
    tr_netInit(); /* must go before tr_eventInit */
 
266
    tr_netInit( ); /* must go before tr_eventInit */
236
267
 
237
268
    tr_eventInit( h );
238
269
    while( !h->events )
241
272
    h->tag = tr_strdup( tag );
242
273
    h->peerMgr = tr_peerMgrNew( h );
243
274
 
 
275
    h->useLazyBitfield = useLazyBitfield != 0;
 
276
 
244
277
    /* Initialize rate and file descripts controls */
245
278
 
246
 
    h->upload = tr_rcInit();
247
 
    tr_rcSetLimit( h->upload, uploadLimit );
248
 
    h->useUploadLimit = isUploadLimitEnabled;
249
 
 
250
 
    h->download = tr_rcInit();
251
 
    tr_rcSetLimit( h->download, downloadLimit );
252
 
    h->useDownloadLimit = isDownloadLimitEnabled;
 
279
    h->uploadLimit = uploadLimit;
 
280
    h->useUploadLimit = useUploadLimit;
 
281
    h->downloadLimit = downloadLimit;
 
282
    h->useDownloadLimit = useDownloadLimit;
253
283
 
254
284
    tr_fdInit( globalPeerLimit );
255
285
    h->shared = tr_sharedInit( h, isPortForwardingEnabled, publicPort );
260
290
    tr_inf( _( "%s %s started" ), TR_NAME, LONG_VERSION_STRING );
261
291
 
262
292
    /* initialize the blocklist */
263
 
    tr_buildPath( filename, sizeof( filename ), h->configDir, "blocklists", NULL );
 
293
    filename = tr_buildPath( h->configDir, "blocklists", NULL );
264
294
    tr_mkdirp( filename, 0777 );
 
295
    tr_free( filename );
265
296
    h->isBlocklistEnabled = isBlocklistEnabled;
266
297
    loadBlocklists( h );
267
298
 
268
299
    tr_statsInit( h );
269
300
 
270
301
    h->web = tr_webInit( h );
271
 
    h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort, rpcACL,
272
 
                                  rpcAuthIsEnabled, rpcUsername, rpcPassword );
 
302
    h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort,
 
303
                               rpcWhitelistIsEnabled, rpcWhitelist,
 
304
                               rpcAuthIsEnabled, rpcUsername, rpcPassword );
273
305
 
274
306
    metainfoLookupRescan( h );
275
307
 
287
319
                               TR_DEFAULT_PEX_ENABLED,
288
320
                               TR_DEFAULT_PORT_FORWARDING_ENABLED,
289
321
                               -1, /* public port */
290
 
                               TR_ENCRYPTION_PREFERRED, /* encryption mode */
291
 
                               FALSE, /* use upload speed limit? */ 
 
322
                               TR_DEFAULT_ENCRYPTION, /* encryption mode */
 
323
                               TR_DEFAULT_LAZY_BITFIELD_ENABLED,
 
324
                               FALSE, /* use upload speed limit? */
292
325
                               -1, /* upload speed limit */
293
326
                               FALSE, /* use download speed limit? */
294
327
                               -1, /* download speed limit */
299
332
                               TR_DEFAULT_PEER_SOCKET_TOS,
300
333
                               TR_DEFAULT_RPC_ENABLED,
301
334
                               TR_DEFAULT_RPC_PORT,
302
 
                               TR_DEFAULT_RPC_ACL,
 
335
                               TR_DEFAULT_RPC_WHITELIST_ENABLED,
 
336
                               TR_DEFAULT_RPC_WHITELIST,
303
337
                               FALSE,
304
338
                               "fnord",
305
339
                               "potzrebie",
310
344
                               TR_DEFAULT_PROXY_AUTH_ENABLED,
311
345
                               TR_DEFAULT_PROXY_USERNAME,
312
346
                               TR_DEFAULT_PROXY_PASSWORD );
313
 
 
314
347
}
315
348
 
316
349
/***
318
351
***/
319
352
 
320
353
void
321
 
tr_sessionSetDownloadDir( tr_handle * handle, const char * dir )
 
354
tr_sessionSetDownloadDir( tr_handle *  handle,
 
355
                          const char * dir )
322
356
{
323
357
    if( handle->downloadDir != dir )
324
358
    {
358
392
/***********************************************************************
359
393
 * tr_setBindPort
360
394
 ***********************************************************************
361
 
 * 
 
395
 *
362
396
 **********************************************************************/
363
397
 
364
398
struct bind_port_data
365
399
{
366
 
    tr_handle * handle;
367
 
    int port;
 
400
    tr_handle *  handle;
 
401
    int          port;
368
402
};
369
403
 
370
404
static void
371
405
tr_setBindPortImpl( void * vdata )
372
406
{
373
407
    struct bind_port_data * data = vdata;
374
 
    tr_handle * handle = data->handle;
375
 
    const int port = data->port;
 
408
    tr_handle *             handle = data->handle;
 
409
    const int               port = data->port;
376
410
 
377
411
    handle->isPortSet = 1;
378
412
    tr_sharedSetPort( handle->shared, port );
381
415
}
382
416
 
383
417
void
384
 
tr_sessionSetPeerPort( tr_handle * handle, int port )
 
418
tr_sessionSetPeerPort( tr_handle * handle,
 
419
                       int         port )
385
420
{
386
421
    struct bind_port_data * data = tr_new( struct bind_port_data, 1 );
 
422
 
387
423
    data->handle = handle;
388
424
    data->port = port;
389
425
    tr_runInEventThread( handle, tr_setBindPortImpl, data );
407
443
***/
408
444
 
409
445
void
410
 
tr_sessionSetSpeedLimitEnabled( tr_handle  * h,
411
 
                                int          up_or_down,
 
446
tr_sessionSetSpeedLimitEnabled( tr_handle *  h,
 
447
                                tr_direction direction,
412
448
                                int          use_flag )
413
449
{
414
 
    if( up_or_down == TR_UP )
 
450
    assert( h );
 
451
    assert( direction == TR_UP || direction == TR_DOWN );
 
452
 
 
453
    if( direction == TR_UP )
415
454
        h->useUploadLimit = use_flag ? 1 : 0;
416
455
    else
417
456
        h->useDownloadLimit = use_flag ? 1 : 0;
418
457
}
419
458
 
420
459
int
421
 
tr_sessionIsSpeedLimitEnabled( const tr_handle * h, int up_or_down )
 
460
tr_sessionIsSpeedLimitEnabled( const tr_handle * h,
 
461
                               tr_direction      direction )
422
462
{
423
 
       return up_or_down==TR_UP ? h->useUploadLimit : h->useDownloadLimit;
 
463
    return direction == TR_UP ? h->useUploadLimit : h->useDownloadLimit;
424
464
}
425
465
 
426
466
void
427
 
tr_sessionSetSpeedLimit( tr_handle  * h,
428
 
                         int          up_or_down,
 
467
tr_sessionSetSpeedLimit( tr_handle *  h,
 
468
                         tr_direction direction,
429
469
                         int          KiB_sec )
430
470
{
431
 
    if( up_or_down == TR_DOWN )
432
 
        tr_rcSetLimit( h->download, KiB_sec );
 
471
    if( direction == TR_DOWN )
 
472
        h->downloadLimit = KiB_sec;
433
473
    else
434
 
        tr_rcSetLimit( h->upload, KiB_sec );
 
474
        h->uploadLimit = KiB_sec;
435
475
}
436
476
 
437
477
int
438
 
tr_sessionGetSpeedLimit( const tr_handle * h, int up_or_down )
 
478
tr_sessionGetSpeedLimit( const tr_handle * h,
 
479
                         tr_direction      direction )
439
480
{
440
 
    return tr_rcGetLimit( up_or_down==TR_UP ? h->upload : h->download );
 
481
    return direction == TR_UP ? h->uploadLimit : h->downloadLimit;
441
482
}
442
483
 
443
484
/***
446
487
 
447
488
void
448
489
tr_sessionSetPeerLimit( tr_handle * handle UNUSED,
449
 
                        uint16_t    maxGlobalPeers )
 
490
                        uint16_t           maxGlobalPeers )
450
491
{
451
492
    tr_fdSetPeerLimit( maxGlobalPeers );
452
493
}
461
502
****
462
503
***/
463
504
 
464
 
void
465
 
tr_sessionGetSpeed( const tr_handle  * session,
466
 
                    float            * toClient,
467
 
                    float            * toPeer )
468
 
{
469
 
    if( session && toClient )
470
 
        *toClient = tr_rcRate( session->download );
471
 
    if( session && toPeer )
472
 
        *toPeer = tr_rcRate( session->upload );
 
505
double
 
506
tr_sessionGetPieceSpeed( const tr_session * session, tr_direction dir )
 
507
{
 
508
    assert( dir==TR_UP || dir==TR_DOWN );
 
509
 
 
510
    return session ? tr_rcRate( session->pieceSpeed[dir] ) : 0.0;
 
511
}
 
512
 
 
513
double
 
514
tr_sessionGetRawSpeed( const tr_session * session, tr_direction dir )
 
515
{
 
516
    assert( dir==TR_UP || dir==TR_DOWN );
 
517
 
 
518
    return session ? tr_rcRate( session->rawSpeed[dir] ) : 0.0;
473
519
}
474
520
 
475
521
int
478
524
    return h->torrentCount;
479
525
}
480
526
 
481
 
/* close the biggest torrents first */
482
527
static int
483
 
compareTorrentByCur( const void * va, const void * vb )
 
528
compareTorrentByCur( const void * va,
 
529
                     const void * vb )
484
530
{
485
531
    const tr_torrent * a = *(const tr_torrent**)va;
486
532
    const tr_torrent * b = *(const tr_torrent**)vb;
487
 
    return -tr_compareUint64( a->downloadedCur + a->uploadedCur,
488
 
                              b->downloadedCur + b->uploadedCur );
 
533
    const uint64_t     aCur = a->downloadedCur + a->uploadedCur;
 
534
    const uint64_t     bCur = b->downloadedCur + b->uploadedCur;
 
535
 
 
536
    if( aCur != bCur )
 
537
        return aCur > bCur ? -1 : 1; /* close the biggest torrents first */
 
538
 
 
539
    return 0;
489
540
}
490
541
 
491
542
static void
492
543
tr_closeAllConnections( void * vsession )
493
544
{
494
 
    tr_handle * session = vsession;
495
 
    tr_torrent * tor;
496
 
    int i, n;
 
545
    tr_handle *   session = vsession;
 
546
    tr_torrent *  tor;
 
547
    int           i, n;
497
548
    tr_torrent ** torrents;
498
549
 
499
550
    tr_statsClose( session );
505
556
     * at least we get the most important ones first. */
506
557
    tor = NULL;
507
558
    n = session->torrentCount;
508
 
    torrents = tr_new( tr_torrent*, session->torrentCount );
509
 
    for( i=0; i<n; ++i )
 
559
    torrents = tr_new( tr_torrent *, session->torrentCount );
 
560
    for( i = 0; i < n; ++i )
510
561
        torrents[i] = tor = tr_torrentNext( session, tor );
511
 
    qsort( torrents, n, sizeof(tr_torrent*), compareTorrentByCur );
512
 
    for( i=0; i<n; ++i )
 
562
    qsort( torrents, n, sizeof( tr_torrent* ), compareTorrentByCur );
 
563
    for( i = 0; i < n; ++i )
513
564
        tr_torrentFree( torrents[i] );
514
565
    tr_free( torrents );
515
566
 
516
567
    tr_peerMgrFree( session->peerMgr );
517
568
 
518
 
    tr_rcClose( session->upload );
519
 
    tr_rcClose( session->download );
520
 
 
521
569
    tr_trackerSessionClose( session );
522
 
    tr_list_free( &session->blocklists, (TrListForeachFunc)_tr_blocklistFree );
 
570
    tr_list_free( &session->blocklists,
 
571
                  (TrListForeachFunc)_tr_blocklistFree );
523
572
    tr_webClose( &session->web );
524
 
    
 
573
 
525
574
    session->isClosed = TRUE;
526
575
}
527
576
 
533
582
 
534
583
#define SHUTDOWN_MAX_SECONDS 30
535
584
 
536
 
#define dbgmsg(fmt...) tr_deepLog( __FILE__, __LINE__, NULL, ##fmt )
 
585
#define dbgmsg( ... ) \
 
586
    do { \
 
587
        if( tr_deepLoggingIsActive( ) ) \
 
588
            tr_deepLog( __FILE__, __LINE__, NULL, __VA_ARGS__ ); \
 
589
    } while( 0 )
537
590
 
538
591
void
539
592
tr_sessionClose( tr_handle * session )
540
593
{
541
 
    int i;
542
 
    const int maxwait_msec = SHUTDOWN_MAX_SECONDS * 1000;
 
594
    int            i;
 
595
    const int      maxwait_msec = SHUTDOWN_MAX_SECONDS * 1000;
543
596
    const uint64_t deadline = tr_date( ) + maxwait_msec;
544
597
 
545
598
    dbgmsg( "shutting down transmission session %p", session );
546
599
 
547
600
    /* close the session */
548
601
    tr_runInEventThread( session, tr_closeAllConnections, session );
549
 
    while( !session->isClosed && !deadlineReached( deadline ) ) {
550
 
        dbgmsg( "waiting for the shutdown commands to run in the main thread" );
 
602
    while( !session->isClosed && !deadlineReached( deadline ) )
 
603
    {
 
604
        dbgmsg(
 
605
            "waiting for the shutdown commands to run in the main thread" );
551
606
        tr_wait( 100 );
552
607
    }
553
608
 
555
610
     * so we need to keep the transmission thread alive
556
611
     * for a bit while they tell the router & tracker
557
612
     * that we're closing now */
558
 
    while( ( session->shared || session->tracker ) && !deadlineReached( deadline ) ) {
 
613
    while( ( session->shared
 
614
           || session->tracker ) && !deadlineReached( deadline ) )
 
615
    {
559
616
        dbgmsg( "waiting on port unmap (%p) or tracker (%p)",
560
617
                session->shared, session->tracker );
561
618
        tr_wait( 100 );
562
619
    }
 
620
 
563
621
    tr_fdClose( );
564
622
 
565
623
    /* close the libtransmission thread */
566
624
    tr_eventClose( session );
567
 
    while( session->events && !deadlineReached( deadline ) ) {
 
625
    while( session->events && !deadlineReached( deadline ) )
 
626
    {
568
627
        dbgmsg( "waiting for the libevent thread to shutdown cleanly" );
569
628
        tr_wait( 100 );
570
629
    }
571
630
 
572
631
    /* free the session memory */
 
632
    tr_rcClose( session->pieceSpeed[TR_PEER_TO_CLIENT] );
 
633
    tr_rcClose( session->pieceSpeed[TR_CLIENT_TO_PEER] );
 
634
    tr_rcClose( session->rawSpeed[TR_PEER_TO_CLIENT] );
 
635
    tr_rcClose( session->rawSpeed[TR_CLIENT_TO_PEER] );
573
636
    tr_lockFree( session->lock );
574
 
    for( i=0; i<session->metainfoLookupCount; ++i )
 
637
    for( i = 0; i < session->metainfoLookupCount; ++i )
575
638
        tr_free( session->metainfoLookup[i].filename );
576
639
    tr_free( session->metainfoLookup );
577
640
    tr_free( session->tag );
586
649
}
587
650
 
588
651
tr_torrent **
589
 
tr_sessionLoadTorrents ( tr_handle   * h,
590
 
                         tr_ctor     * ctor,
591
 
                         int         * setmeCount )
 
652
tr_sessionLoadTorrents( tr_handle * h,
 
653
                        tr_ctor *   ctor,
 
654
                        int *       setmeCount )
592
655
{
593
 
    int i, n = 0;
594
 
    struct stat sb;
595
 
    DIR * odir = NULL;
596
 
    const char * dirname = tr_getTorrentDir( h );
 
656
    int           i, n = 0;
 
657
    struct stat   sb;
 
658
    DIR *         odir = NULL;
 
659
    const char *  dirname = tr_getTorrentDir( h );
597
660
    tr_torrent ** torrents;
598
 
    tr_list *l=NULL, *list=NULL;
 
661
    tr_list *     l = NULL, *list = NULL;
599
662
 
600
663
    tr_ctorSetSave( ctor, FALSE ); /* since we already have them */
601
664
 
602
665
    if( !stat( dirname, &sb )
603
 
        && S_ISDIR( sb.st_mode )
604
 
        && (( odir = opendir ( dirname ) )) )
 
666
      && S_ISDIR( sb.st_mode )
 
667
      && ( ( odir = opendir ( dirname ) ) ) )
605
668
    {
606
669
        struct dirent *d;
607
 
        for (d = readdir( odir ); d!=NULL; d=readdir( odir ) )
 
670
        for( d = readdir( odir ); d != NULL; d = readdir( odir ) )
608
671
        {
609
 
            if( d->d_name && d->d_name[0]!='.' ) /* skip dotfiles, ., and .. */
 
672
            if( d->d_name && d->d_name[0] != '.' ) /* skip dotfiles, ., and ..
 
673
                                                     */
610
674
            {
611
675
                tr_torrent * tor;
612
 
                char filename[MAX_PATH_LENGTH];
613
 
                tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
614
 
 
615
 
                tr_ctorSetMetainfoFromFile( ctor, filename );
616
 
                tor = tr_torrentNew( h, ctor, NULL );
617
 
                if( tor ) {
 
676
                char * path = tr_buildPath( dirname, d->d_name, NULL );
 
677
                tr_ctorSetMetainfoFromFile( ctor, path );
 
678
                if(( tor = tr_torrentNew( h, ctor, NULL )))
 
679
                {
618
680
                    tr_list_append( &list, tor );
619
681
                    ++n;
620
682
                }
 
683
                tr_free( path );
621
684
            }
622
685
        }
623
686
        closedir( odir );
624
687
    }
625
688
 
626
 
    torrents = tr_new( tr_torrent*, n );
627
 
    for( i=0, l=list; l!=NULL; l=l->next )
 
689
    torrents = tr_new( tr_torrent *, n );
 
690
    for( i = 0, l = list; l != NULL; l = l->next )
628
691
        torrents[i++] = (tr_torrent*) l->data;
629
 
    assert( i==n );
 
692
    assert( i == n );
630
693
 
631
694
    tr_list_free( &list, NULL );
632
695
 
643
706
***/
644
707
 
645
708
void
646
 
tr_sessionSetPexEnabled( tr_handle * handle, int isPexEnabled )
 
709
tr_sessionSetPexEnabled( tr_handle * handle,
 
710
                         int         enabled )
647
711
{
648
 
    handle->isPexEnabled = isPexEnabled ? 1 : 0;
 
712
    handle->isPexEnabled = enabled ? 1 : 0;
649
713
}
650
714
 
651
715
int
659
723
***/
660
724
 
661
725
void
662
 
tr_sessionSetPortForwardingEnabled( tr_handle * h, int enable )
 
726
tr_sessionSetLazyBitfieldEnabled( tr_handle * handle,
 
727
                                  int         enabled )
 
728
{
 
729
    handle->useLazyBitfield = enabled ? 1 : 0;
 
730
}
 
731
 
 
732
int
 
733
tr_sessionIsLazyBitfieldEnabled( const tr_handle * handle )
 
734
{
 
735
    return handle->useLazyBitfield;
 
736
}
 
737
 
 
738
/***
 
739
****
 
740
***/
 
741
 
 
742
void
 
743
tr_sessionSetPortForwardingEnabled( tr_handle * h,
 
744
                                    int         enable )
663
745
{
664
746
    tr_globalLock( h );
665
747
    tr_sharedTraversalEnable( h->shared, enable );
679
761
int
680
762
tr_blocklistGetRuleCount( const tr_session * session )
681
763
{
682
 
    int n = 0;
 
764
    int       n = 0;
683
765
    tr_list * l;
684
 
    for( l=session->blocklists; l; l=l->next )
 
766
 
 
767
    for( l = session->blocklists; l; l = l->next )
685
768
        n += _tr_blocklistGetRuleCount( l->data );
686
769
    return n;
687
770
}
693
776
}
694
777
 
695
778
void
696
 
tr_blocklistSetEnabled( tr_session * session, int isEnabled )
 
779
tr_blocklistSetEnabled( tr_session * session,
 
780
                        int          isEnabled )
697
781
{
698
782
    tr_list * l;
 
783
 
699
784
    session->isBlocklistEnabled = isEnabled ? 1 : 0;
700
 
    for( l=session->blocklists; l; l=l->next )
 
785
    for( l = session->blocklists; l; l = l->next )
701
786
        _tr_blocklistSetEnabled( l->data, isEnabled );
702
787
}
703
788
 
708
793
}
709
794
 
710
795
int
711
 
tr_blocklistSetContent( tr_session  * session, const char * contentFilename )
 
796
tr_blocklistSetContent( tr_session * session,
 
797
                        const char * contentFilename )
712
798
{
713
 
    tr_list * l;
 
799
    tr_list *      l;
714
800
    tr_blocklist * b;
715
 
    const char * defaultName = "level1.bin";
 
801
    const char *   defaultName = "level1.bin";
716
802
 
717
 
    for( b=NULL, l=session->blocklists; !b && l; l=l->next )
718
 
        if( tr_stringEndsWith( _tr_blocklistGetFilename( l->data ), defaultName ) )
 
803
    for( b = NULL, l = session->blocklists; !b && l; l = l->next )
 
804
        if( tr_stringEndsWith( _tr_blocklistGetFilename( l->data ),
 
805
                               defaultName ) )
719
806
            b = l->data;
720
807
 
721
 
    if( !b ) {
722
 
        char filename[MAX_PATH_LENGTH];
723
 
        tr_buildPath( filename, sizeof( filename ), session->configDir, "blocklists", defaultName, NULL );
724
 
        b = _tr_blocklistNew( filename, session->isBlocklistEnabled );
 
808
    if( !b )
 
809
    {
 
810
        char * path = tr_buildPath( session->configDir, "blocklists", defaultName, NULL );
 
811
        b = _tr_blocklistNew( path, session->isBlocklistEnabled );
725
812
        tr_list_append( &session->blocklists, b );
 
813
        tr_free( path );
726
814
    }
727
815
 
728
816
    return _tr_blocklistSetContent( b, contentFilename );
729
817
}
730
818
 
731
819
int
732
 
tr_sessionIsAddressBlocked( const tr_session      * session,
733
 
                            const struct in_addr  * addr )
 
820
tr_sessionIsAddressBlocked( const tr_session *     session,
 
821
                            const struct in_addr * addr )
734
822
{
735
823
    tr_list * l;
736
 
    for( l=session->blocklists; l; l=l->next )
 
824
 
 
825
    for( l = session->blocklists; l; l = l->next )
737
826
        if( _tr_blocklistHasAddress( l->data, addr ) )
738
827
            return TRUE;
739
828
    return FALSE;
744
833
***/
745
834
 
746
835
static int
747
 
compareLookupEntries( const void * va, const void * vb )
 
836
compareLookupEntries( const void * va,
 
837
                      const void * vb )
748
838
{
749
839
    const struct tr_metainfo_lookup * a = va;
750
840
    const struct tr_metainfo_lookup * b = vb;
 
841
 
751
842
    return strcmp( a->hashString, b->hashString );
752
843
}
753
844
 
754
845
static void
755
846
metainfoLookupResort( tr_handle * h )
756
847
{
757
 
    qsort( h->metainfoLookup, 
 
848
    qsort( h->metainfoLookup,
758
849
           h->metainfoLookupCount,
759
850
           sizeof( struct tr_metainfo_lookup ),
760
851
           compareLookupEntries );
761
852
}
762
853
 
763
854
static int
764
 
compareHashStringToLookupEntry( const void * va, const void * vb )
 
855
compareHashStringToLookupEntry( const void * va,
 
856
                                const void * vb )
765
857
{
766
 
    const char * a = va;
 
858
    const char *                      a = va;
767
859
    const struct tr_metainfo_lookup * b = vb;
 
860
 
768
861
    return strcmp( a, b->hashString );
769
862
}
770
863
 
771
864
const char*
772
 
tr_sessionFindTorrentFile( const tr_handle  * h,
773
 
                           const char       * hashStr )
 
865
tr_sessionFindTorrentFile( const tr_handle * h,
 
866
                           const char *      hashStr )
774
867
{
775
868
    struct tr_metainfo_lookup * l = bsearch( hashStr,
776
869
                                             h->metainfoLookup,
777
870
                                             h->metainfoLookupCount,
778
 
                                             sizeof( struct tr_metainfo_lookup ),
 
871
                                             sizeof( struct
 
872
                                                     tr_metainfo_lookup ),
779
873
                                             compareHashStringToLookupEntry );
 
874
 
780
875
    return l ? l->filename : NULL;
781
876
}
782
877
 
783
878
static void
784
879
metainfoLookupRescan( tr_handle * h )
785
880
{
786
 
    int i;
787
 
    int n;
788
 
    struct stat sb;
 
881
    int          i;
 
882
    int          n;
 
883
    struct stat  sb;
789
884
    const char * dirname = tr_getTorrentDir( h );
790
 
    DIR * odir = NULL;
791
 
    tr_ctor * ctor = NULL;
792
 
    tr_list * list = NULL;
 
885
    DIR *        odir = NULL;
 
886
    tr_ctor *    ctor = NULL;
 
887
    tr_list *    list = NULL;
793
888
 
794
889
    /* walk through the directory and find the mappings */
795
890
    ctor = tr_ctorNew( h );
796
891
    tr_ctorSetSave( ctor, FALSE ); /* since we already have them */
797
 
    if( !stat( dirname, &sb ) && S_ISDIR( sb.st_mode ) && (( odir = opendir( dirname ))))
 
892
    if( !stat( dirname,
 
893
               &sb ) && S_ISDIR( sb.st_mode )
 
894
      && ( ( odir = opendir( dirname ) ) ) )
798
895
    {
799
896
        struct dirent *d;
800
 
        for (d = readdir( odir ); d!=NULL; d=readdir( odir ) )
 
897
        for( d = readdir( odir ); d != NULL; d = readdir( odir ) )
801
898
        {
802
 
            if( d->d_name && d->d_name[0]!='.' ) /* skip dotfiles, ., and .. */
 
899
            if( d->d_name && d->d_name[0] != '.' ) /* skip dotfiles, ., and ..
 
900
                                                     */
803
901
            {
804
902
                tr_info inf;
805
 
                char filename[MAX_PATH_LENGTH];
806
 
                tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
807
 
                tr_ctorSetMetainfoFromFile( ctor, filename );
 
903
                char * path = tr_buildPath( dirname, d->d_name, NULL );
 
904
                tr_ctorSetMetainfoFromFile( ctor, path );
808
905
                if( !tr_torrentParse( h, ctor, &inf ) )
809
906
                {
810
907
                    tr_list_append( &list, tr_strdup( inf.hashString ) );
811
 
                    tr_list_append( &list, tr_strdup( filename ) );
 
908
                    tr_list_append( &list, tr_strdup( path ) );
812
909
                    tr_metainfoFree( &inf );
813
910
                }
 
911
                tr_free( path );
814
912
            }
815
913
        }
816
914
        closedir( odir );
820
918
    n = tr_list_size( list ) / 2;
821
919
    h->metainfoLookup = tr_new0( struct tr_metainfo_lookup, n );
822
920
    h->metainfoLookupCount = n;
823
 
    for( i=0; i<n; ++i )
 
921
    for( i = 0; i < n; ++i )
824
922
    {
825
923
        char * hashString = tr_list_pop_front( &list );
826
924
        char * filename = tr_list_pop_front( &list );
827
925
 
828
 
        memcpy( h->metainfoLookup[i].hashString, hashString, 2*SHA_DIGEST_LENGTH+1 );
 
926
        memcpy( h->metainfoLookup[i].hashString, hashString,
 
927
                2 * SHA_DIGEST_LENGTH + 1 );
829
928
        tr_free( hashString );
830
929
        h->metainfoLookup[i].filename = filename;
831
930
    }
835
934
}
836
935
 
837
936
void
838
 
tr_sessionSetTorrentFile( tr_handle    * h,
839
 
                          const char   * hashString,
840
 
                          const char   * filename )
 
937
tr_sessionSetTorrentFile( tr_handle *  h,
 
938
                          const char * hashString,
 
939
                          const char * filename )
841
940
{
842
941
    struct tr_metainfo_lookup * l = bsearch( hashString,
843
942
                                             h->metainfoLookup,
844
943
                                             h->metainfoLookupCount,
845
 
                                             sizeof( struct tr_metainfo_lookup ),
 
944
                                             sizeof( struct
 
945
                                                     tr_metainfo_lookup ),
846
946
                                             compareHashStringToLookupEntry );
 
947
 
847
948
    if( l )
848
949
    {
849
950
        if( l->filename != filename )
854
955
    }
855
956
    else
856
957
    {
857
 
        const int n = h->metainfoLookupCount++;
 
958
        const int                   n = h->metainfoLookupCount++;
858
959
        struct tr_metainfo_lookup * node;
859
960
        h->metainfoLookup = tr_renew( struct tr_metainfo_lookup,
860
961
                                      h->metainfoLookup,
861
962
                                      h->metainfoLookupCount );
862
963
        node = h->metainfoLookup + n;
863
 
        memcpy( node->hashString, hashString, 2*SHA_DIGEST_LENGTH+1 );
 
964
        memcpy( node->hashString, hashString, 2 * SHA_DIGEST_LENGTH + 1 );
864
965
        node->filename = tr_strdup( filename );
865
966
        metainfoLookupResort( h );
866
967
    }
867
968
}
868
969
 
869
970
tr_torrent*
870
 
tr_torrentNext( tr_handle * session, tr_torrent * tor )
 
971
tr_torrentNext( tr_handle *  session,
 
972
                tr_torrent * tor )
871
973
{
872
974
    return tor ? tor->next : session->torrentList;
873
975
}
877
979
***/
878
980
 
879
981
void
880
 
tr_sessionSetRPCEnabled( tr_session * session, int isEnabled )
 
982
tr_sessionSetRPCEnabled( tr_session * session,
 
983
                         int          isEnabled )
881
984
{
882
985
    tr_rpcSetEnabled( session->rpcServer, isEnabled );
883
986
}
 
987
 
884
988
int
885
989
tr_sessionIsRPCEnabled( const tr_session * session )
886
990
{
887
991
    return tr_rpcIsEnabled( session->rpcServer );
888
992
}
 
993
 
889
994
void
890
 
tr_sessionSetRPCPort( tr_session * session, int port )
 
995
tr_sessionSetRPCPort( tr_session * session,
 
996
                      uint16_t     port )
891
997
{
892
998
    tr_rpcSetPort( session->rpcServer, port );
893
999
}
894
 
int
 
1000
 
 
1001
uint16_t
895
1002
tr_sessionGetRPCPort( const tr_session * session )
896
1003
{
897
1004
    return tr_rpcGetPort( session->rpcServer );
898
1005
}
 
1006
 
899
1007
void
900
 
tr_sessionSetRPCCallback( tr_session    * session,
901
 
                          tr_rpc_func    func,
902
 
                          void         * user_data )
 
1008
tr_sessionSetRPCCallback( tr_session * session,
 
1009
                          tr_rpc_func  func,
 
1010
                          void *       user_data )
903
1011
{
904
1012
    session->rpc_func = func;
905
1013
    session->rpc_func_user_data = user_data;
906
1014
}
907
 
int
908
 
tr_sessionTestRPCACL( const tr_session  * session,
909
 
                      const char       * acl,
910
 
                      char            ** allocme_errmsg )
911
 
{
912
 
    return tr_rpcTestACL( session->rpcServer, acl, allocme_errmsg );
913
 
}
914
 
int
915
 
tr_sessionSetRPCACL( tr_session    * session,
916
 
                     const char   * acl,
917
 
                     char        ** allocme_errmsg )
918
 
{
919
 
    return tr_rpcSetACL( session->rpcServer, acl, allocme_errmsg );
920
 
}
 
1015
 
 
1016
void
 
1017
tr_sessionSetRPCWhitelist( tr_session * session,
 
1018
                           const char * whitelist )
 
1019
{
 
1020
    tr_rpcSetWhitelist( session->rpcServer, whitelist );
 
1021
}
 
1022
 
921
1023
char*
922
 
tr_sessionGetRPCACL( const tr_session * session )
923
 
{
924
 
    return tr_rpcGetACL( session->rpcServer );
925
 
}
926
 
void
927
 
tr_sessionSetRPCPassword( tr_session * session, const char * password )
 
1024
tr_sessionGetRPCWhitelist( const tr_session * session )
 
1025
{
 
1026
    return tr_rpcGetWhitelist( session->rpcServer );
 
1027
}
 
1028
 
 
1029
void
 
1030
tr_sessionSetRPCWhitelistEnabled( tr_session * session,
 
1031
                                  int          isEnabled )
 
1032
{
 
1033
    tr_rpcSetWhitelistEnabled( session->rpcServer, isEnabled );
 
1034
}
 
1035
 
 
1036
int
 
1037
tr_sessionGetRPCWhitelistEnabled( const tr_session * session )
 
1038
{
 
1039
    return tr_rpcGetWhitelistEnabled( session->rpcServer );
 
1040
}
 
1041
 
 
1042
 
 
1043
void
 
1044
tr_sessionSetRPCPassword( tr_session * session,
 
1045
                          const char * password )
928
1046
{
929
1047
    tr_rpcSetPassword( session->rpcServer, password );
930
1048
}
 
1049
 
931
1050
char*
932
1051
tr_sessionGetRPCPassword( const tr_session * session )
933
1052
{
934
1053
    return tr_rpcGetPassword( session->rpcServer );
935
1054
}
 
1055
 
936
1056
void
937
 
tr_sessionSetRPCUsername( tr_session * session, const char * username )
 
1057
tr_sessionSetRPCUsername( tr_session * session,
 
1058
                          const char * username )
938
1059
{
939
1060
    tr_rpcSetUsername( session->rpcServer, username );
940
1061
}
 
1062
 
941
1063
char*
942
1064
tr_sessionGetRPCUsername( const tr_session * session )
943
1065
{
944
1066
    return tr_rpcGetUsername( session->rpcServer );
945
1067
}
 
1068
 
946
1069
void
947
 
tr_sessionSetRPCPasswordEnabled( tr_session * session, int isEnabled )
 
1070
tr_sessionSetRPCPasswordEnabled( tr_session * session,
 
1071
                                 int          isEnabled )
948
1072
{
949
1073
    tr_rpcSetPasswordEnabled( session->rpcServer, isEnabled );
950
1074
}
 
1075
 
951
1076
int
952
1077
tr_sessionIsRPCPasswordEnabled( const tr_session * session )
953
1078
{
963
1088
{
964
1089
    return session->isProxyEnabled;
965
1090
}
 
1091
 
966
1092
void
967
 
tr_sessionSetProxyEnabled( tr_session * session, int isEnabled )
 
1093
tr_sessionSetProxyEnabled( tr_session * session,
 
1094
                           int          isEnabled )
968
1095
{
969
1096
    session->isProxyEnabled = isEnabled ? 1 : 0;
970
1097
}
 
1098
 
971
1099
tr_proxy_type
972
1100
tr_sessionGetProxyType( const tr_session * session )
973
1101
{
974
1102
    return session->proxyType;
975
1103
}
 
1104
 
976
1105
void
977
 
tr_sessionSetProxyType( tr_session * session, tr_proxy_type type )
 
1106
tr_sessionSetProxyType( tr_session *  session,
 
1107
                        tr_proxy_type type )
978
1108
{
979
1109
    session->proxyType = type;
980
1110
}
 
1111
 
981
1112
const char*
982
1113
tr_sessionGetProxy( const tr_session * session )
983
1114
{
984
1115
    return session->proxy;
985
1116
}
 
1117
 
986
1118
int
987
1119
tr_sessionGetProxyPort( const tr_session * session )
988
1120
{
989
1121
    return session->proxyPort;
990
1122
}
 
1123
 
991
1124
void
992
 
tr_sessionSetProxy( tr_session * session, const char * proxy )
 
1125
tr_sessionSetProxy( tr_session * session,
 
1126
                    const char * proxy )
993
1127
{
994
1128
    if( proxy != session->proxy )
995
1129
    {
997
1131
        session->proxy = tr_strdup( proxy );
998
1132
    }
999
1133
}
 
1134
 
1000
1135
void
1001
 
tr_sessionSetProxyPort( tr_session * session, int port )
 
1136
tr_sessionSetProxyPort( tr_session * session,
 
1137
                        int          port )
1002
1138
{
1003
1139
    session->proxyPort = port;
1004
1140
}
 
1141
 
1005
1142
int
1006
1143
tr_sessionIsProxyAuthEnabled( const tr_session * session )
1007
1144
{
1008
1145
    return session->isProxyAuthEnabled;
1009
1146
}
 
1147
 
1010
1148
void
1011
 
tr_sessionSetProxyAuthEnabled( tr_session * session, int isEnabled )
 
1149
tr_sessionSetProxyAuthEnabled( tr_session * session,
 
1150
                               int          isEnabled )
1012
1151
{
1013
1152
    session->isProxyAuthEnabled = isEnabled ? 1 : 0;
1014
1153
}
 
1154
 
1015
1155
const char*
1016
1156
tr_sessionGetProxyUsername( const tr_session * session )
1017
1157
{
1018
1158
    return session->proxyUsername;
1019
1159
}
 
1160
 
1020
1161
void
1021
 
tr_sessionSetProxyUsername( tr_session * session, const char * username )
 
1162
tr_sessionSetProxyUsername( tr_session * session,
 
1163
                            const char * username )
1022
1164
{
1023
1165
    if( username != session->proxyUsername )
1024
1166
    {
1026
1168
        session->proxyUsername = tr_strdup( username );
1027
1169
    }
1028
1170
}
 
1171
 
1029
1172
const char*
1030
1173
tr_sessionGetProxyPassword( const tr_session * session )
1031
1174
{
1032
1175
    return session->proxyPassword;
1033
1176
}
 
1177
 
1034
1178
void
1035
 
tr_sessionSetProxyPassword( tr_session * session, const char * password )
 
1179
tr_sessionSetProxyPassword( tr_session * session,
 
1180
                            const char * password )
1036
1181
{
1037
1182
    if( password != session->proxyPassword )
1038
1183
    {
1040
1185
        session->proxyPassword = tr_strdup( password );
1041
1186
    }
1042
1187
}
 
1188