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

« back to all changes in this revision

Viewing changes to libtransmission/session.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Starr-Bochicchio, Andrew Starr-Bochicchio, Martin Pitt
  • Date: 2009-02-26 11:55:50 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20090226115550-3rnhgt9qhe3y6g74
Tags: 1.50-1ubuntu1
[ Andrew Starr-Bochicchio ]
* Merge from debian unstable (LP: #329161), remaining changes:
 - debian/control: 
  + Added replaces & provides clutch (now included as part of transmission).
  + Build-depends on quilt.
 - debian/rules: 
  + Uncommented "include /usr/share/quilt/quilt.make".
  + Added patch/unpatch targets for Quilt.
  + Create a PO template during package build.
 - 20_add_X-Ubuntu-Gettext-Domain.diff: Add X-Ubuntu-Gettext-Domain 
   to .desktop file.

[ Martin Pitt ]
* Add 01_check_notification_actions.diff: Check if notification
  agent supports actions, and do not use actions if not. (LP: #334252)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>
 
2
 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com>
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)
7
7
 * This exemption does not extend to derived works not owned by
8
8
 * the Transmission project.
9
9
 *
10
 
 * $Id: session.c 7365 2008-12-13 22:52:13Z charles $
 
10
 * $Id: session.c 7813 2009-01-29 18:18:24Z charles $
11
11
 */
12
12
 
13
13
#include <assert.h>
21
21
#include <dirent.h> /* opendir */
22
22
 
23
23
#include "transmission.h"
 
24
#include "session.h"
24
25
#include "bandwidth.h"
 
26
#include "bencode.h"
25
27
#include "blocklist.h"
26
28
#include "fdlimit.h"
27
29
#include "list.h"
39
41
#include "web.h"
40
42
#include "crypto.h"
41
43
 
 
44
#define dbgmsg( ... ) \
 
45
    do { \
 
46
        if( tr_deepLoggingIsActive( ) ) \
 
47
            tr_deepLog( __FILE__, __LINE__, NULL, __VA_ARGS__ ); \
 
48
    } while( 0 )
 
49
 
 
50
static tr_port
 
51
getRandomPort( tr_session * s )
 
52
{
 
53
    return tr_cryptoWeakRandInt( s->randomPortHigh - s->randomPortLow + 1) + s->randomPortLow;
 
54
}
 
55
 
42
56
/* Generate a peer id : "-TRxyzb-" + 12 random alphanumeric
43
57
   characters, where x is the major version number, y is the
44
58
   minor version number, z is the maintenance number, and b
126
140
    char      * dirname;
127
141
    DIR *       odir = NULL;
128
142
    tr_list *   list = NULL;
129
 
    const int   isEnabled = session->isBlocklistEnabled;
 
143
    const tr_bool   isEnabled = session->isBlocklistEnabled;
130
144
 
131
145
    /* walk through the directory and find blocklists */
132
146
    dirname = tr_buildPath( session->configDir, "blocklists", NULL );
194
208
****
195
209
***/
196
210
 
197
 
static void metainfoLookupRescan( tr_handle * h );
198
 
 
199
 
tr_handle *
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 )
231
 
{
232
 
    tr_handle * h;
233
 
    char      * filename;
 
211
#ifdef TR_EMBEDDED
 
212
 #define TR_DEFAULT_ENCRYPTION              TR_CLEAR_PREFERRED
 
213
#else
 
214
 #define TR_DEFAULT_ENCRYPTION              TR_ENCRYPTION_PREFERRED
 
215
#endif
 
216
 
 
217
void
 
218
tr_sessionGetDefaultSettings( tr_benc * d )
 
219
{
 
220
    assert( tr_bencIsDict( d ) );
 
221
 
 
222
    tr_bencDictReserve( d, 30 );
 
223
    tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED,        FALSE );
 
224
    tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR,             tr_getDefaultDownloadDir( ) );
 
225
    tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED,                   100 );
 
226
    tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED,           0 );
 
227
    tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION,               TR_DEFAULT_ENCRYPTION );
 
228
    tr_bencDictAddInt( d, TR_PREFS_KEY_LAZY_BITFIELD,            TRUE );
 
229
    tr_bencDictAddInt( d, TR_PREFS_KEY_MSGLEVEL,                 TR_MSG_INF );
 
230
    tr_bencDictAddInt( d, TR_PREFS_KEY_OPEN_FILE_LIMIT,          atoi( TR_DEFAULT_OPEN_FILE_LIMIT_STR ) );
 
231
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL,        atoi( TR_DEFAULT_PEER_LIMIT_GLOBAL_STR ) );
 
232
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT,       atoi( TR_DEFAULT_PEER_LIMIT_TORRENT_STR ) );
 
233
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT,                atoi( TR_DEFAULT_PEER_PORT_STR ) );
 
234
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED, FALSE );
 
235
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW,     1024 );
 
236
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH,    65535 );
 
237
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_SOCKET_TOS,          atoi( TR_DEFAULT_PEER_SOCKET_TOS_STR ) );
 
238
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEX_ENABLED,              TRUE );
 
239
    tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING,          TRUE );
 
240
    tr_bencDictAddInt( d, TR_PREFS_KEY_PREALLOCATION,            TR_PREALLOCATE_SPARSE );
 
241
    tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY,                    "" );
 
242
    tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_AUTH_ENABLED,       FALSE );
 
243
    tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_ENABLED,            FALSE );
 
244
    tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_PASSWORD,           "" );
 
245
    tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_PORT,               80 );
 
246
    tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_TYPE,               TR_PROXY_HTTP );
 
247
    tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_USERNAME,           "" );
 
248
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_AUTH_REQUIRED,        FALSE );
 
249
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_ENABLED,              TRUE );
 
250
    tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_PASSWORD,             "" );
 
251
    tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_USERNAME,             "" );
 
252
    tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST,            TR_DEFAULT_RPC_WHITELIST );
 
253
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED,    TRUE );
 
254
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_PORT,                 atoi( TR_DEFAULT_RPC_PORT_STR ) );
 
255
    tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED,                   100 );
 
256
    tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED,           0 );
 
257
    tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, 14 );
 
258
}
 
259
 
 
260
void
 
261
tr_sessionGetSettings( tr_session * s, struct tr_benc * d )
 
262
{
 
263
    int i, n=0;
 
264
    char * freeme[16];
 
265
 
 
266
    assert( tr_bencIsDict( d ) );
 
267
 
 
268
    tr_bencDictReserve( d, 30 );
 
269
    tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED,        tr_blocklistIsEnabled( s ) );
 
270
    tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR,             s->downloadDir );
 
271
    tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED,                   tr_sessionGetSpeedLimit( s, TR_DOWN ) );
 
272
    tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED,           tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) );
 
273
    tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION,               s->encryptionMode );
 
274
    tr_bencDictAddInt( d, TR_PREFS_KEY_LAZY_BITFIELD,            s->useLazyBitfield );
 
275
    tr_bencDictAddInt( d, TR_PREFS_KEY_MSGLEVEL,                 tr_getMessageLevel( ) );
 
276
    tr_bencDictAddInt( d, TR_PREFS_KEY_OPEN_FILE_LIMIT,          s->openFileLimit );
 
277
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL,        tr_sessionGetPeerLimit( s ) );
 
278
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT,       s->peerLimitPerTorrent );
 
279
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT,                tr_sessionGetPeerPort( s ) );
 
280
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED, s->isPortRandom );
 
281
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW,     s->randomPortLow );
 
282
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH,    s->randomPortHigh );
 
283
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_SOCKET_TOS,          s->peerSocketTOS );
 
284
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEX_ENABLED,              s->isPexEnabled );
 
285
    tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING,          tr_sessionIsPortForwardingEnabled( s ) );
 
286
    tr_bencDictAddInt( d, TR_PREFS_KEY_PREALLOCATION,            s->preallocationMode );
 
287
    tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY,                    s->proxy );
 
288
    tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_AUTH_ENABLED,       s->isProxyAuthEnabled );
 
289
    tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_ENABLED,            s->isProxyEnabled );
 
290
    tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_PASSWORD,           s->proxyPassword );
 
291
    tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_PORT,               s->proxyPort );
 
292
    tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_TYPE,               s->proxyType );
 
293
    tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_USERNAME,           s->proxyUsername );
 
294
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_AUTH_REQUIRED,        tr_sessionIsRPCPasswordEnabled( s ) );
 
295
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_ENABLED,              tr_sessionIsRPCEnabled( s ) );
 
296
    tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_PASSWORD,             freeme[n++] = tr_sessionGetRPCPassword( s ) );
 
297
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_PORT,                 tr_sessionGetRPCPort( s ) );
 
298
    tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_USERNAME,             freeme[n++] = tr_sessionGetRPCUsername( s ) );
 
299
    tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST,            freeme[n++] = tr_sessionGetRPCWhitelist( s ) );
 
300
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED,    tr_sessionGetRPCWhitelistEnabled( s ) );
 
301
    tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED,                   tr_sessionGetSpeedLimit( s, TR_UP ) );
 
302
    tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED,           tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );
 
303
    tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, s->uploadSlotsPerTorrent );
 
304
 
 
305
    for( i=0; i<n; ++i )
 
306
        tr_free( freeme[i] );
 
307
}
 
308
 
 
309
void
 
310
tr_sessionLoadSettings( tr_benc * d, const char * configDir, const char * appName )
 
311
{
 
312
    char * filename;
 
313
    tr_benc fileSettings;
 
314
 
 
315
    assert( tr_bencIsDict( d ) );
 
316
 
 
317
    /* get the defaults */
 
318
    tr_sessionGetDefaultSettings( d );
 
319
 
 
320
    /* if caller didn't specify a config dir, use the default */
 
321
    if( !configDir || !*configDir )
 
322
        configDir = tr_getDefaultConfigDir( appName );
 
323
 
 
324
    /* file settings override the defaults */
 
325
    filename = tr_buildPath( configDir, "settings.json", NULL );
 
326
    if( !tr_bencLoadJSONFile( filename, &fileSettings ) ) {
 
327
        tr_bencMergeDicts( d, &fileSettings );
 
328
        tr_bencFree( &fileSettings );
 
329
    }
 
330
 
 
331
    /* cleanup */
 
332
    tr_free( filename );
 
333
}
 
334
 
 
335
void
 
336
tr_sessionSaveSettings( tr_session * session, const char * configDir, tr_benc * settings )
 
337
{
 
338
    tr_benc fileSettings;
 
339
    char * filename;
 
340
 
 
341
    assert( tr_bencIsDict( settings ) );
 
342
 
 
343
    filename = tr_buildPath( configDir, "settings.json", NULL );
 
344
 
 
345
    tr_sessionGetSettings( session, settings );
 
346
 
 
347
    if( tr_bencLoadJSONFile( filename, &fileSettings ) ) {
 
348
        tr_bencSaveJSONFile( filename, settings );
 
349
    } else {
 
350
        tr_bencMergeDicts( &fileSettings, settings );
 
351
        tr_bencSaveJSONFile( filename, &fileSettings );
 
352
        tr_bencFree( &fileSettings );
 
353
    }
 
354
 
 
355
    tr_inf( "Saved \"%s\"", filename );
 
356
    tr_free( filename );
 
357
}
 
358
 
 
359
static void metainfoLookupRescan( tr_session * );
 
360
static void tr_sessionInitImpl( void * );
 
361
 
 
362
tr_session *
 
363
tr_sessionInit( const char  * tag,
 
364
                const char  * configDir,
 
365
                tr_bool       messageQueuingEnabled,
 
366
                tr_benc     * clientSettings )
 
367
{
 
368
    int64_t i;
 
369
    int64_t j;
 
370
    tr_bool found;
 
371
    const char * str;
 
372
    tr_benc settings;
 
373
    tr_session * session;
 
374
    char * filename;
 
375
 
 
376
    assert( tr_bencIsDict( clientSettings ) );
 
377
 
 
378
    session = tr_new0( tr_session, 1 );
 
379
    session->bandwidth = tr_bandwidthNew( session, NULL );
 
380
    session->lock = tr_lockNew( );
 
381
    session->tag = tr_strdup( tag );
 
382
    session->magicNumber = SESSION_MAGIC_NUMBER;
 
383
 
 
384
    dbgmsg( "tr_sessionInit: the session's top-level bandwidth object is %p", session->bandwidth );
 
385
 
 
386
    tr_bencInitDict( &settings, 0 );
 
387
    tr_sessionGetDefaultSettings( &settings );
 
388
    tr_bencMergeDicts( &settings, clientSettings );
234
389
 
235
390
#ifndef WIN32
236
391
    /* Don't exit when writing on a broken socket */
237
392
    signal( SIGPIPE, SIG_IGN );
238
393
#endif
239
394
 
240
 
    tr_msgInit( );
241
 
    tr_setMessageLevel( messageLevel );
242
 
    tr_setMessageQueuing( isMessageQueueingEnabled );
243
 
 
244
 
    h = tr_new0( tr_handle, 1 );
245
 
    h->lock = tr_lockNew( );
246
 
    h->isPexEnabled = isPexEnabled ? 1 : 0;
247
 
    h->encryptionMode = encryptionMode;
248
 
    h->peerSocketTOS = peerSocketTOS;
249
 
    h->downloadDir = tr_strdup( downloadDir );
250
 
    h->isProxyEnabled = proxyIsEnabled ? 1 : 0;
251
 
    h->proxy = tr_strdup( proxy );
252
 
    h->proxyPort = proxyPort;
253
 
    h->proxyType = proxyType;
254
 
    h->isProxyAuthEnabled = proxyAuthIsEnabled != 0;
255
 
    h->proxyUsername = tr_strdup( proxyUsername );
256
 
    h->proxyPassword = tr_strdup( proxyPassword );
257
 
    h->so_sndbuf = 1500 * 3; /* 3x MTU for most ethernet/wireless */
258
 
    h->so_rcvbuf = 8192;
259
 
 
260
 
    if( configDir == NULL )
261
 
        configDir = tr_getDefaultConfigDir( );
262
 
    tr_setConfigDir( h, configDir );
 
395
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_LIMIT_TORRENT, &i ); 
 
396
    assert( found ); 
 
397
    session->peerLimitPerTorrent = i; 
 
398
 
 
399
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_MSGLEVEL, &i ); 
 
400
    assert( found ); 
 
401
    tr_setMessageLevel( i ); 
 
402
    tr_setMessageQueuing( messageQueuingEnabled ); 
 
403
 
 
404
 
 
405
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEX_ENABLED, &i ); 
 
406
    assert( found ); 
 
407
    session->isPexEnabled = i != 0; 
 
408
 
 
409
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ENCRYPTION, &i ); 
 
410
    assert( found ); 
 
411
    assert( tr_isEncryptionMode( i ) );
 
412
    session->encryptionMode = i; 
 
413
 
 
414
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PREALLOCATION, &i );
 
415
    assert( found );
 
416
    assert( tr_isPreallocationMode( i ) );
 
417
    session->preallocationMode = i;
 
418
 
 
419
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_SOCKET_TOS, &i ); 
 
420
    assert( found ); 
 
421
    session->peerSocketTOS = i; 
 
422
 
 
423
    found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_DOWNLOAD_DIR, &str ); 
 
424
    assert( found ); 
 
425
    session->downloadDir = tr_strdup( str ); 
 
426
 
 
427
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_ENABLED, &i ); 
 
428
    assert( found ); 
 
429
    session->isProxyEnabled = i != 0; 
 
430
 
 
431
    found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_PROXY, &str ); 
 
432
    assert( found ); 
 
433
    session->proxy = tr_strdup( str ); 
 
434
 
 
435
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_PORT, &i ); 
 
436
    assert( found ); 
 
437
    session->proxyPort = i; 
 
438
 
 
439
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_TYPE, &i ); 
 
440
    assert( found ); 
 
441
    session->proxyType = i; 
 
442
 
 
443
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_AUTH_ENABLED, &i ); 
 
444
    assert( found ); 
 
445
    session->isProxyAuthEnabled = i != 0; 
 
446
 
 
447
    found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_PROXY_USERNAME, &str ); 
 
448
    assert( found ); 
 
449
    session->proxyUsername = tr_strdup( str ); 
 
450
 
 
451
    found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_PROXY_PASSWORD, &str ); 
 
452
    assert( found ); 
 
453
    session->proxyPassword = tr_strdup( str ); 
 
454
 
 
455
    session->so_sndbuf = 1500 * 3; /* 3x MTU for most ethernet/wireless */ 
 
456
    session->so_rcvbuf = 8192; 
 
457
 
 
458
    tr_setConfigDir( session, configDir ); 
263
459
 
264
460
    tr_netInit( ); /* must go before tr_eventInit */
265
 
 
266
 
    tr_eventInit( h );
267
 
    while( !h->events )
268
 
        tr_wait( 50 );
269
 
 
270
 
    h->tag = tr_strdup( tag );
271
 
    h->peerMgr = tr_peerMgrNew( h );
272
 
 
273
 
    h->useLazyBitfield = useLazyBitfield != 0;
 
461
    tr_eventInit( session );
 
462
    assert( session->events != NULL );
 
463
 
 
464
    session->peerMgr = tr_peerMgrNew( session );
 
465
 
 
466
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_LAZY_BITFIELD, &i ); 
 
467
    assert( found ); 
 
468
    session->useLazyBitfield = i != 0; 
274
469
 
275
470
    /* Initialize rate and file descripts controls */
276
471
 
277
 
    tr_fdInit( globalPeerLimit );
278
 
    h->shared = tr_sharedInit( h, isPortForwardingEnabled, publicPort );
279
 
    h->isPortSet = publicPort >= 0;
280
 
 
281
 
    h->bandwidth = tr_bandwidthNew( h, NULL );
282
 
    tr_sessionSetSpeedLimit       ( h, TR_UP,   uploadLimit );
283
 
    tr_sessionSetSpeedLimitEnabled( h, TR_UP,   useUploadLimit );
284
 
    tr_sessionSetSpeedLimit       ( h, TR_DOWN, downloadLimit );
285
 
    tr_sessionSetSpeedLimitEnabled( h, TR_DOWN, useDownloadLimit );
286
 
 
 
472
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_OPEN_FILE_LIMIT, &i ); 
 
473
    assert( found ); 
 
474
    session->openFileLimit = i;
 
475
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &j ); 
 
476
    assert( found ); 
 
477
    tr_fdInit( session->openFileLimit, j );
 
478
 
 
479
    /** 
 
480
    *** random port 
 
481
    **/ 
 
482
 
 
483
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED, &i ); 
 
484
    assert( found ); 
 
485
    session->isPortRandom = i != 0; 
 
486
 
 
487
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW, &i ); 
 
488
    assert( found ); 
 
489
    session->randomPortLow = i; 
 
490
 
 
491
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH, &i ); 
 
492
    assert( found ); 
 
493
    session->randomPortHigh = i; 
 
494
 
 
495
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PORT_FORWARDING, &i ) 
 
496
         && tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT, &j ); 
 
497
    assert( found ); 
 
498
    session->peerPort = session->isPortRandom ? getRandomPort( session ) : j; 
 
499
    session->shared = tr_sharedInit( session, i, session->peerPort ); 
 
500
    session->isPortSet = session->isPortRandom || j>0; 
 
501
 
 
502
    /** 
 
503
    **/ 
 
504
 
 
505
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, &i );
 
506
    assert( found );
 
507
    session->uploadSlotsPerTorrent = i;
 
508
 
 
509
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_USPEED, &i )
 
510
         && tr_bencDictFindInt( &settings, TR_PREFS_KEY_USPEED_ENABLED, &j );
 
511
    assert( found ); 
 
512
    tr_sessionSetSpeedLimit( session, TR_UP, i );
 
513
    tr_sessionSetSpeedLimitEnabled( session, TR_UP, j );
 
514
 
 
515
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_DSPEED, &i )
 
516
         && tr_bencDictFindInt( &settings, TR_PREFS_KEY_DSPEED_ENABLED, &j );
 
517
    assert( found ); 
 
518
    tr_sessionSetSpeedLimit( session, TR_DOWN, i );
 
519
    tr_sessionSetSpeedLimitEnabled( session, TR_DOWN, j );
 
520
 
 
521
    /* initialize the blocklist */
 
522
    filename = tr_buildPath( session->configDir, "blocklists", NULL );
 
523
    tr_mkdirp( filename, 0777 );
 
524
    tr_free( filename );
 
525
    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, &i ); 
 
526
    assert( found ); 
 
527
    session->isBlocklistEnabled = i; 
 
528
    loadBlocklists( session ); 
 
529
 
 
530
    session->rpcServer = tr_rpcInit( session, &settings ); 
 
531
 
 
532
    tr_bencFree( &settings );
 
533
 
 
534
    session->isWaiting = TRUE;
 
535
    tr_runInEventThread( session, tr_sessionInitImpl, session );
 
536
    while( session->isWaiting )
 
537
        tr_wait( 100 );
 
538
 
 
539
    return session;
 
540
}
 
541
static void
 
542
tr_sessionInitImpl( void * vsession )
 
543
{
 
544
    tr_session * session = vsession;
 
545
 
 
546
    assert( tr_isSession( session ) );
 
547
 
287
548
    /* first %s is the application name
288
549
       second %s is the version number */
289
550
    tr_inf( _( "%s %s started" ), TR_NAME, LONG_VERSION_STRING );
290
551
 
291
 
    /* initialize the blocklist */
292
 
    filename = tr_buildPath( h->configDir, "blocklists", NULL );
293
 
    tr_mkdirp( filename, 0777 );
294
 
    tr_free( filename );
295
 
    h->isBlocklistEnabled = isBlocklistEnabled;
296
 
    loadBlocklists( h );
297
 
 
298
 
    tr_statsInit( h );
299
 
 
300
 
    h->web = tr_webInit( h );
301
 
    h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort,
302
 
                               rpcWhitelistIsEnabled, rpcWhitelist,
303
 
                               rpcAuthIsEnabled, rpcUsername, rpcPassword );
304
 
 
305
 
    metainfoLookupRescan( h );
306
 
 
307
 
    return h;
308
 
}
309
 
 
310
 
tr_handle *
311
 
tr_sessionInit( const char * configDir,
312
 
                const char * downloadDir,
313
 
                const char * tag )
314
 
{
315
 
    return tr_sessionInitFull( configDir,
316
 
                               downloadDir,
317
 
                               tag,
318
 
                               TR_DEFAULT_PEX_ENABLED,
319
 
                               TR_DEFAULT_PORT_FORWARDING_ENABLED,
320
 
                               -1, /* public port */
321
 
                               TR_DEFAULT_ENCRYPTION, /* encryption mode */
322
 
                               TR_DEFAULT_LAZY_BITFIELD_ENABLED,
323
 
                               FALSE, /* use upload speed limit? */
324
 
                               -1, /* upload speed limit */
325
 
                               FALSE, /* use download speed limit? */
326
 
                               -1, /* download speed limit */
327
 
                               TR_DEFAULT_GLOBAL_PEER_LIMIT,
328
 
                               TR_MSG_INF, /* message level */
329
 
                               FALSE, /* is message queueing enabled? */
330
 
                               FALSE, /* is the blocklist enabled? */
331
 
                               TR_DEFAULT_PEER_SOCKET_TOS,
332
 
                               TR_DEFAULT_RPC_ENABLED,
333
 
                               TR_DEFAULT_RPC_PORT,
334
 
                               TR_DEFAULT_RPC_WHITELIST_ENABLED,
335
 
                               TR_DEFAULT_RPC_WHITELIST,
336
 
                               FALSE,
337
 
                               "fnord",
338
 
                               "potzrebie",
339
 
                               TR_DEFAULT_PROXY_ENABLED,
340
 
                               TR_DEFAULT_PROXY,
341
 
                               TR_DEFAULT_PROXY_PORT,
342
 
                               TR_DEFAULT_PROXY_TYPE,
343
 
                               TR_DEFAULT_PROXY_AUTH_ENABLED,
344
 
                               TR_DEFAULT_PROXY_USERNAME,
345
 
                               TR_DEFAULT_PROXY_PASSWORD );
 
552
    tr_statsInit( session );
 
553
    session->web = tr_webInit( session ); 
 
554
    metainfoLookupRescan( session );
 
555
    session->isWaiting = FALSE;
346
556
}
347
557
 
348
558
/***
350
560
***/
351
561
 
352
562
void
353
 
tr_sessionSetDownloadDir( tr_handle *  handle,
354
 
                          const char * dir )
 
563
tr_sessionSetDownloadDir( tr_session * session, const char * dir )
355
564
{
356
 
    if( handle->downloadDir != dir )
 
565
    assert( tr_isSession( session ) );
 
566
 
 
567
    if( session->downloadDir != dir )
357
568
    {
358
 
        tr_free( handle->downloadDir );
359
 
        handle->downloadDir = tr_strdup( dir );
 
569
        tr_free( session->downloadDir );
 
570
        session->downloadDir = tr_strdup( dir );
360
571
    }
361
572
}
362
573
 
363
574
const char *
364
 
tr_sessionGetDownloadDir( const tr_handle * handle )
 
575
tr_sessionGetDownloadDir( const tr_session * session )
365
576
{
366
 
    return handle->downloadDir;
 
577
    assert( tr_isSession( session ) );
 
578
 
 
579
    return session->downloadDir;
367
580
}
368
581
 
369
582
/***
371
584
***/
372
585
 
373
586
void
374
 
tr_globalLock( struct tr_handle * handle )
 
587
tr_globalLock( tr_session * session )
375
588
{
376
 
    tr_lockLock( handle->lock );
 
589
    assert( tr_isSession( session ) );
 
590
 
 
591
    tr_lockLock( session->lock );
377
592
}
378
593
 
379
594
void
380
 
tr_globalUnlock( struct tr_handle * handle )
 
595
tr_globalUnlock( tr_session * session )
381
596
{
382
 
    tr_lockUnlock( handle->lock );
 
597
    assert( tr_isSession( session ) );
 
598
 
 
599
    tr_lockUnlock( session->lock );
383
600
}
384
601
 
385
 
int
386
 
tr_globalIsLocked( const struct tr_handle * handle )
 
602
tr_bool
 
603
tr_globalIsLocked( const tr_session * session )
387
604
{
388
 
    return handle && tr_lockHave( handle->lock );
 
605
    return tr_isSession( session ) && tr_lockHave( session->lock );
389
606
}
390
607
 
391
608
/***********************************************************************
396
613
 
397
614
struct bind_port_data
398
615
{
399
 
    tr_handle *  handle;
400
 
    int          port;
 
616
    tr_session * session;
 
617
    tr_port      port;
401
618
};
402
619
 
403
620
static void
404
621
tr_setBindPortImpl( void * vdata )
405
622
{
406
623
    struct bind_port_data * data = vdata;
407
 
    tr_handle *             handle = data->handle;
408
 
    const int               port = data->port;
 
624
    tr_session * session = data->session;
 
625
    const tr_port port = data->port;
409
626
 
410
 
    handle->isPortSet = 1;
411
 
    tr_sharedSetPort( handle->shared, port );
 
627
    session->isPortSet = 1;
 
628
    tr_sharedSetPort( session->shared, port );
412
629
 
413
630
    tr_free( data );
414
631
}
415
632
 
416
 
void
417
 
tr_sessionSetPeerPort( tr_handle * handle,
418
 
                       int         port )
 
633
static void
 
634
setPortImpl( tr_session * session, tr_port port )
419
635
{
420
 
    struct bind_port_data * data = tr_new( struct bind_port_data, 1 );
421
 
 
422
 
    data->handle = handle;
 
636
    struct bind_port_data * data;
 
637
 
 
638
    assert( tr_isSession( session ) );
 
639
 
 
640
    data = tr_new( struct bind_port_data, 1 );
 
641
    data->session = session;
423
642
    data->port = port;
424
 
    tr_runInEventThread( handle, tr_setBindPortImpl, data );
425
 
}
426
 
 
427
 
int
428
 
tr_sessionGetPeerPort( const tr_handle * h )
429
 
{
430
 
    assert( h );
431
 
    return tr_sharedGetPeerPort( h->shared );
 
643
    tr_runInEventThread( session, tr_setBindPortImpl, data );
 
644
}
 
645
 
 
646
void
 
647
tr_sessionSetPeerPort( tr_session * session,
 
648
                       tr_port      port )
 
649
{
 
650
    assert( tr_isSession( session ) );
 
651
 
 
652
    session->isPortRandom = FALSE;
 
653
    session->peerPort = port;
 
654
    setPortImpl( session, session->peerPort );
 
655
}
 
656
 
 
657
tr_port
 
658
tr_sessionSetPeerPortRandom( tr_session * session )
 
659
{
 
660
    assert( tr_isSession( session ) );
 
661
 
 
662
    session->isPortRandom = TRUE;
 
663
    session->peerPort = getRandomPort( session );
 
664
    setPortImpl( session, session->peerPort );
 
665
    return session->peerPort;
 
666
}
 
667
 
 
668
tr_port
 
669
tr_sessionGetPeerPort( const tr_session * session )
 
670
{
 
671
    assert( tr_isSession( session ) );
 
672
 
 
673
    return session->peerPort;
432
674
}
433
675
 
434
676
tr_port_forwarding
435
 
tr_sessionGetPortForwarding( const tr_handle * h )
 
677
tr_sessionGetPortForwarding( const tr_session * session )
436
678
{
437
 
    return tr_sharedTraversalStatus( h->shared );
 
679
    assert( tr_isSession( session ) );
 
680
 
 
681
    return tr_sharedTraversalStatus( session->shared );
438
682
}
439
683
 
440
684
/***
444
688
static void
445
689
updateBandwidth( tr_session * session, tr_direction dir )
446
690
{
447
 
    const tr_bool zeroCase = session->speedLimit[dir] < 1 && session->isSpeedLimited[dir];
 
691
    tr_bool zeroCase;
 
692
 
 
693
    assert( tr_isSession( session ) );
 
694
 
 
695
    zeroCase = session->speedLimit[dir] < 1 && session->isSpeedLimited[dir];
448
696
 
449
697
    tr_bandwidthSetLimited( session->bandwidth, dir, session->isSpeedLimited[dir] && !zeroCase );
450
698
 
456
704
                                tr_direction      dir,
457
705
                                tr_bool           isLimited )
458
706
{
459
 
    assert( session );
460
 
    assert( dir==TR_UP || dir==TR_DOWN );
 
707
    assert( tr_isSession( session ) );
 
708
    assert( tr_isDirection( dir ) );
461
709
 
462
710
    session->isSpeedLimited[dir] = isLimited;
463
711
    updateBandwidth( session, dir );
468
716
                         tr_direction    dir,
469
717
                         int             desiredSpeed )
470
718
{
471
 
    assert( session );
472
 
    assert( dir==TR_UP || dir==TR_DOWN );
 
719
    assert( tr_isSession( session ) );
 
720
    assert( tr_isDirection( dir ) );
473
721
 
474
722
    session->speedLimit[dir] = desiredSpeed;
475
723
    updateBandwidth( session, dir );
479
727
tr_sessionIsSpeedLimitEnabled( const tr_session  * session,
480
728
                               tr_direction        dir )
481
729
{
482
 
    assert( session );
483
 
    assert( dir==TR_UP || dir==TR_DOWN );
 
730
    assert( tr_isSession( session ) );
 
731
    assert( tr_isDirection( dir ) );
484
732
 
485
733
    return session->isSpeedLimited[dir];
486
734
}
489
737
tr_sessionGetSpeedLimit( const tr_session  * session,
490
738
                         tr_direction        dir )
491
739
{
492
 
    assert( session );
493
 
    assert( dir==TR_UP || dir==TR_DOWN );
 
740
    assert( tr_isSession( session ) );
 
741
    assert( tr_isDirection( dir ) );
494
742
 
495
743
    return session->speedLimit[dir];
496
744
}
500
748
***/
501
749
 
502
750
void
503
 
tr_sessionSetPeerLimit( tr_handle * handle UNUSED,
504
 
                        uint16_t           maxGlobalPeers )
 
751
tr_sessionSetPeerLimit( tr_session * session,
 
752
                        uint16_t     maxGlobalPeers )
505
753
{
 
754
    assert( tr_isSession( session ) );
 
755
 
506
756
    tr_fdSetPeerLimit( maxGlobalPeers );
507
757
}
508
758
 
509
759
uint16_t
510
 
tr_sessionGetPeerLimit( const tr_handle * handle UNUSED )
 
760
tr_sessionGetPeerLimit( const tr_session * session )
511
761
{
 
762
    assert( tr_isSession( session ) );
 
763
 
512
764
    return tr_fdGetPeerLimit( );
513
765
}
514
766
 
 
767
void
 
768
tr_sessionSetPeerLimitPerTorrent( tr_session  * session, uint16_t n )
 
769
{
 
770
    assert( tr_isSession( session ) );
 
771
 
 
772
    session->peerLimitPerTorrent = n;
 
773
}
 
774
 
 
775
uint16_t
 
776
tr_sessionGetPeerLimitPerTorrent( const tr_session * session )
 
777
{
 
778
    assert( tr_isSession( session ) );
 
779
 
 
780
    return session->peerLimitPerTorrent;
 
781
}
 
782
 
515
783
/***
516
784
****
517
785
***/
519
787
double
520
788
tr_sessionGetPieceSpeed( const tr_session * session, tr_direction dir )
521
789
{
522
 
    return session ? tr_bandwidthGetPieceSpeed( session->bandwidth, dir ) : 0.0;
 
790
    return tr_isSession( session ) ? tr_bandwidthGetPieceSpeed( session->bandwidth, 0, dir ) : 0.0;
523
791
}
524
792
 
525
793
double
526
794
tr_sessionGetRawSpeed( const tr_session * session, tr_direction dir )
527
795
{
528
 
    return session ? tr_bandwidthGetPieceSpeed( session->bandwidth, dir ) : 0.0;
 
796
    return tr_isSession( session ) ? tr_bandwidthGetPieceSpeed( session->bandwidth, 0, dir ) : 0.0;
529
797
}
530
798
 
531
799
int
532
 
tr_sessionCountTorrents( const tr_handle * h )
 
800
tr_sessionCountTorrents( const tr_session * session )
533
801
{
534
 
    return h->torrentCount;
 
802
    return tr_isSession( session ) ? session->torrentCount : 0;
535
803
}
536
804
 
537
805
static int
538
 
compareTorrentByCur( const void * va,
539
 
                     const void * vb )
 
806
compareTorrentByCur( const void * va, const void * vb )
540
807
{
541
808
    const tr_torrent * a = *(const tr_torrent**)va;
542
809
    const tr_torrent * b = *(const tr_torrent**)vb;
552
819
static void
553
820
tr_closeAllConnections( void * vsession )
554
821
{
555
 
    tr_handle *   session = vsession;
 
822
    tr_session *  session = vsession;
556
823
    tr_torrent *  tor;
557
824
    int           i, n;
558
825
    tr_torrent ** torrents;
559
826
 
 
827
    assert( tr_isSession( session ) );
 
828
 
560
829
    tr_statsClose( session );
561
830
    tr_sharedShuttingDown( session->shared );
562
831
    tr_rpcClose( &session->rpcServer );
592
861
 
593
862
#define SHUTDOWN_MAX_SECONDS 30
594
863
 
595
 
#define dbgmsg( ... ) \
596
 
    do { \
597
 
        if( tr_deepLoggingIsActive( ) ) \
598
 
            tr_deepLog( __FILE__, __LINE__, NULL, __VA_ARGS__ ); \
599
 
    } while( 0 )
600
 
 
601
864
void
602
 
tr_sessionClose( tr_handle * session )
 
865
tr_sessionClose( tr_session * session )
603
866
{
604
867
    int            i;
605
868
    const int      maxwait_msec = SHUTDOWN_MAX_SECONDS * 1000;
606
869
    const uint64_t deadline = tr_date( ) + maxwait_msec;
607
870
 
 
871
    assert( tr_isSession( session ) );
 
872
 
608
873
    dbgmsg( "shutting down transmission session %p", session );
609
874
 
610
875
    /* close the session */
656
921
}
657
922
 
658
923
tr_torrent **
659
 
tr_sessionLoadTorrents( tr_handle * h,
660
 
                        tr_ctor *   ctor,
661
 
                        int *       setmeCount )
 
924
tr_sessionLoadTorrents( tr_session * session,
 
925
                        tr_ctor    * ctor,
 
926
                        int        * setmeCount )
662
927
{
663
928
    int           i, n = 0;
664
929
    struct stat   sb;
665
930
    DIR *         odir = NULL;
666
 
    const char *  dirname = tr_getTorrentDir( h );
 
931
    const char *  dirname = tr_getTorrentDir( session );
667
932
    tr_torrent ** torrents;
668
933
    tr_list *     l = NULL, *list = NULL;
669
934
 
 
935
    assert( tr_isSession( session ) );
 
936
 
670
937
    tr_ctorSetSave( ctor, FALSE ); /* since we already have them */
671
938
 
672
939
    if( !stat( dirname, &sb )
682
949
                tr_torrent * tor;
683
950
                char * path = tr_buildPath( dirname, d->d_name, NULL );
684
951
                tr_ctorSetMetainfoFromFile( ctor, path );
685
 
                if(( tor = tr_torrentNew( h, ctor, NULL )))
 
952
                if(( tor = tr_torrentNew( session, ctor, NULL )))
686
953
                {
687
954
                    tr_list_append( &list, tor );
688
955
                    ++n;
713
980
***/
714
981
 
715
982
void
716
 
tr_sessionSetPexEnabled( tr_handle * handle,
717
 
                         int         enabled )
718
 
{
719
 
    handle->isPexEnabled = enabled ? 1 : 0;
720
 
}
721
 
 
722
 
int
723
 
tr_sessionIsPexEnabled( const tr_handle * handle )
724
 
{
725
 
    return handle->isPexEnabled;
726
 
}
727
 
 
728
 
/***
729
 
****
730
 
***/
731
 
 
732
 
void
733
 
tr_sessionSetLazyBitfieldEnabled( tr_handle * handle,
734
 
                                  int         enabled )
735
 
{
736
 
    handle->useLazyBitfield = enabled ? 1 : 0;
737
 
}
738
 
 
739
 
int
740
 
tr_sessionIsLazyBitfieldEnabled( const tr_handle * handle )
741
 
{
742
 
    return handle->useLazyBitfield;
743
 
}
744
 
 
745
 
/***
746
 
****
747
 
***/
748
 
 
749
 
void
750
 
tr_sessionSetPortForwardingEnabled( tr_handle * h,
751
 
                                    int         enable )
752
 
{
753
 
    tr_globalLock( h );
754
 
    tr_sharedTraversalEnable( h->shared, enable );
755
 
    tr_globalUnlock( h );
756
 
}
757
 
 
758
 
int
759
 
tr_sessionIsPortForwardingEnabled( const tr_handle * h )
760
 
{
761
 
    return tr_sharedTraversalIsEnabled( h->shared );
 
983
tr_sessionSetPexEnabled( tr_session * session,
 
984
                         tr_bool      enabled )
 
985
{
 
986
    assert( tr_isSession( session ) );
 
987
 
 
988
    session->isPexEnabled = enabled != 0;
 
989
}
 
990
 
 
991
tr_bool
 
992
tr_sessionIsPexEnabled( const tr_session * session )
 
993
{
 
994
    assert( tr_isSession( session ) );
 
995
 
 
996
    return session->isPexEnabled;
 
997
}
 
998
 
 
999
/***
 
1000
****
 
1001
***/
 
1002
 
 
1003
void
 
1004
tr_sessionSetLazyBitfieldEnabled( tr_session * session,
 
1005
                                  tr_bool      enabled )
 
1006
{
 
1007
    assert( tr_isSession( session ) );
 
1008
 
 
1009
    session->useLazyBitfield = enabled != 0;
 
1010
}
 
1011
 
 
1012
tr_bool
 
1013
tr_sessionIsLazyBitfieldEnabled( const tr_session * session )
 
1014
{
 
1015
    assert( tr_isSession( session ) );
 
1016
 
 
1017
    return session->useLazyBitfield;
 
1018
}
 
1019
 
 
1020
/***
 
1021
****
 
1022
***/
 
1023
 
 
1024
void
 
1025
tr_sessionSetPortForwardingEnabled( tr_session  * session,
 
1026
                                    tr_bool       enabled )
 
1027
{
 
1028
    assert( tr_isSession( session ) );
 
1029
 
 
1030
    tr_globalLock( session );
 
1031
    tr_sharedTraversalEnable( session->shared, enabled );
 
1032
    tr_globalUnlock( session );
 
1033
}
 
1034
 
 
1035
tr_bool
 
1036
tr_sessionIsPortForwardingEnabled( const tr_session * session )
 
1037
{
 
1038
    assert( tr_isSession( session ) );
 
1039
 
 
1040
    return tr_sharedTraversalIsEnabled( session->shared );
762
1041
}
763
1042
 
764
1043
/***
771
1050
    int       n = 0;
772
1051
    tr_list * l;
773
1052
 
 
1053
    assert( tr_isSession( session ) );
 
1054
 
774
1055
    for( l = session->blocklists; l; l = l->next )
775
1056
        n += _tr_blocklistGetRuleCount( l->data );
776
1057
    return n;
777
1058
}
778
1059
 
779
 
int
 
1060
tr_bool
780
1061
tr_blocklistIsEnabled( const tr_session * session )
781
1062
{
 
1063
    assert( tr_isSession( session ) );
 
1064
 
782
1065
    return session->isBlocklistEnabled;
783
1066
}
784
1067
 
785
1068
void
786
1069
tr_blocklistSetEnabled( tr_session * session,
787
 
                        int          isEnabled )
 
1070
                        tr_bool      isEnabled )
788
1071
{
789
1072
    tr_list * l;
790
1073
 
791
 
    session->isBlocklistEnabled = isEnabled ? 1 : 0;
792
 
    for( l = session->blocklists; l; l = l->next )
 
1074
    assert( tr_isSession( session ) );
 
1075
 
 
1076
    session->isBlocklistEnabled = isEnabled != 0;
 
1077
 
 
1078
    for( l=session->blocklists; l!=NULL; l=l->next )
793
1079
        _tr_blocklistSetEnabled( l->data, isEnabled );
794
1080
}
795
1081
 
796
 
int
 
1082
tr_bool
797
1083
tr_blocklistExists( const tr_session * session )
798
1084
{
 
1085
    assert( tr_isSession( session ) );
 
1086
 
799
1087
    return session->blocklists != NULL;
800
1088
}
801
1089
 
807
1095
    tr_blocklist * b;
808
1096
    const char *   defaultName = "level1.bin";
809
1097
 
 
1098
    assert( tr_isSession( session ) );
 
1099
 
810
1100
    for( b = NULL, l = session->blocklists; !b && l; l = l->next )
811
1101
        if( tr_stringEndsWith( _tr_blocklistGetFilename( l->data ),
812
1102
                               defaultName ) )
823
1113
    return _tr_blocklistSetContent( b, contentFilename );
824
1114
}
825
1115
 
826
 
int
827
 
tr_sessionIsAddressBlocked( const tr_session *     session,
828
 
                            const struct in_addr * addr )
 
1116
tr_bool
 
1117
tr_sessionIsAddressBlocked( const tr_session * session,
 
1118
                            const tr_address * addr )
829
1119
{
830
1120
    tr_list * l;
831
1121
 
 
1122
    assert( tr_isSession( session ) );
 
1123
 
832
1124
    for( l = session->blocklists; l; l = l->next )
833
1125
        if( _tr_blocklistHasAddress( l->data, addr ) )
834
1126
            return TRUE;
840
1132
***/
841
1133
 
842
1134
static int
843
 
compareLookupEntries( const void * va,
844
 
                      const void * vb )
 
1135
compareLookupEntries( const void * va, const void * vb )
845
1136
{
846
1137
    const struct tr_metainfo_lookup * a = va;
847
1138
    const struct tr_metainfo_lookup * b = vb;
850
1141
}
851
1142
 
852
1143
static void
853
 
metainfoLookupResort( tr_handle * h )
 
1144
metainfoLookupResort( tr_session * session )
854
1145
{
855
 
    qsort( h->metainfoLookup,
856
 
           h->metainfoLookupCount,
 
1146
    assert( tr_isSession( session ) );
 
1147
 
 
1148
    qsort( session->metainfoLookup,
 
1149
           session->metainfoLookupCount,
857
1150
           sizeof( struct tr_metainfo_lookup ),
858
1151
           compareLookupEntries );
859
1152
}
860
1153
 
861
1154
static int
862
 
compareHashStringToLookupEntry( const void * va,
863
 
                                const void * vb )
 
1155
compareHashStringToLookupEntry( const void * va, const void * vb )
864
1156
{
865
1157
    const char *                      a = va;
866
1158
    const struct tr_metainfo_lookup * b = vb;
869
1161
}
870
1162
 
871
1163
const char*
872
 
tr_sessionFindTorrentFile( const tr_handle * h,
873
 
                           const char *      hashStr )
 
1164
tr_sessionFindTorrentFile( const tr_session * session,
 
1165
                           const char       * hashStr )
874
1166
{
875
1167
    struct tr_metainfo_lookup * l = bsearch( hashStr,
876
 
                                             h->metainfoLookup,
877
 
                                             h->metainfoLookupCount,
878
 
                                             sizeof( struct
879
 
                                                     tr_metainfo_lookup ),
 
1168
                                             session->metainfoLookup,
 
1169
                                             session->metainfoLookupCount,
 
1170
                                             sizeof( struct tr_metainfo_lookup ),
880
1171
                                             compareHashStringToLookupEntry );
881
1172
 
882
1173
    return l ? l->filename : NULL;
883
1174
}
884
1175
 
885
1176
static void
886
 
metainfoLookupRescan( tr_handle * h )
 
1177
metainfoLookupRescan( tr_session * session )
887
1178
{
888
1179
    int          i;
889
1180
    int          n;
890
1181
    struct stat  sb;
891
 
    const char * dirname = tr_getTorrentDir( h );
 
1182
    const char * dirname = tr_getTorrentDir( session );
892
1183
    DIR *        odir = NULL;
893
1184
    tr_ctor *    ctor = NULL;
894
1185
    tr_list *    list = NULL;
895
1186
 
 
1187
    assert( tr_isSession( session ) );
 
1188
 
896
1189
    /* walk through the directory and find the mappings */
897
 
    ctor = tr_ctorNew( h );
 
1190
    ctor = tr_ctorNew( session );
898
1191
    tr_ctorSetSave( ctor, FALSE ); /* since we already have them */
899
 
    if( !stat( dirname,
900
 
               &sb ) && S_ISDIR( sb.st_mode )
901
 
      && ( ( odir = opendir( dirname ) ) ) )
 
1192
    if( !stat( dirname, &sb ) && S_ISDIR( sb.st_mode ) && ( ( odir = opendir( dirname ) ) ) )
902
1193
    {
903
1194
        struct dirent *d;
904
1195
        for( d = readdir( odir ); d != NULL; d = readdir( odir ) )
909
1200
                tr_info inf;
910
1201
                char * path = tr_buildPath( dirname, d->d_name, NULL );
911
1202
                tr_ctorSetMetainfoFromFile( ctor, path );
912
 
                if( !tr_torrentParse( h, ctor, &inf ) )
 
1203
                if( !tr_torrentParse( session, ctor, &inf ) )
913
1204
                {
914
1205
                    tr_list_append( &list, tr_strdup( inf.hashString ) );
915
1206
                    tr_list_append( &list, tr_strdup( path ) );
923
1214
    tr_ctorFree( ctor );
924
1215
 
925
1216
    n = tr_list_size( list ) / 2;
926
 
    h->metainfoLookup = tr_new0( struct tr_metainfo_lookup, n );
927
 
    h->metainfoLookupCount = n;
 
1217
    session->metainfoLookup = tr_new0( struct tr_metainfo_lookup, n );
 
1218
    session->metainfoLookupCount = n;
928
1219
    for( i = 0; i < n; ++i )
929
1220
    {
930
1221
        char * hashString = tr_list_pop_front( &list );
931
1222
        char * filename = tr_list_pop_front( &list );
932
1223
 
933
 
        memcpy( h->metainfoLookup[i].hashString, hashString,
 
1224
        memcpy( session->metainfoLookup[i].hashString, hashString,
934
1225
                2 * SHA_DIGEST_LENGTH + 1 );
935
1226
        tr_free( hashString );
936
 
        h->metainfoLookup[i].filename = filename;
 
1227
        session->metainfoLookup[i].filename = filename;
937
1228
    }
938
1229
 
939
 
    metainfoLookupResort( h );
 
1230
    metainfoLookupResort( session );
940
1231
    tr_dbg( "Found %d torrents in \"%s\"", n, dirname );
941
1232
}
942
1233
 
943
1234
void
944
 
tr_sessionSetTorrentFile( tr_handle *  h,
 
1235
tr_sessionSetTorrentFile( tr_session * session,
945
1236
                          const char * hashString,
946
1237
                          const char * filename )
947
1238
{
948
1239
    struct tr_metainfo_lookup * l = bsearch( hashString,
949
 
                                             h->metainfoLookup,
950
 
                                             h->metainfoLookupCount,
951
 
                                             sizeof( struct
952
 
                                                     tr_metainfo_lookup ),
 
1240
                                             session->metainfoLookup,
 
1241
                                             session->metainfoLookupCount,
 
1242
                                             sizeof( struct tr_metainfo_lookup ),
953
1243
                                             compareHashStringToLookupEntry );
954
1244
 
955
1245
    if( l )
962
1252
    }
963
1253
    else
964
1254
    {
965
 
        const int                   n = h->metainfoLookupCount++;
 
1255
        const int n = session->metainfoLookupCount++;
966
1256
        struct tr_metainfo_lookup * node;
967
 
        h->metainfoLookup = tr_renew( struct tr_metainfo_lookup,
968
 
                                      h->metainfoLookup,
969
 
                                      h->metainfoLookupCount );
970
 
        node = h->metainfoLookup + n;
 
1257
        session->metainfoLookup = tr_renew( struct tr_metainfo_lookup,
 
1258
                                            session->metainfoLookup,
 
1259
                                            session->metainfoLookupCount );
 
1260
        node = session->metainfoLookup + n;
971
1261
        memcpy( node->hashString, hashString, 2 * SHA_DIGEST_LENGTH + 1 );
972
1262
        node->filename = tr_strdup( filename );
973
 
        metainfoLookupResort( h );
 
1263
        metainfoLookupResort( session );
974
1264
    }
975
1265
}
976
1266
 
977
1267
tr_torrent*
978
 
tr_torrentNext( tr_handle *  session,
 
1268
tr_torrentNext( tr_session * session,
979
1269
                tr_torrent * tor )
980
1270
{
 
1271
    assert( tr_isSession( session ) );
 
1272
 
981
1273
    return tor ? tor->next : session->torrentList;
982
1274
}
983
1275
 
987
1279
 
988
1280
void
989
1281
tr_sessionSetRPCEnabled( tr_session * session,
990
 
                         int          isEnabled )
 
1282
                         tr_bool      isEnabled )
991
1283
{
 
1284
    assert( tr_isSession( session ) );
 
1285
 
992
1286
    tr_rpcSetEnabled( session->rpcServer, isEnabled );
993
1287
}
994
1288
 
995
 
int
 
1289
tr_bool
996
1290
tr_sessionIsRPCEnabled( const tr_session * session )
997
1291
{
 
1292
    assert( tr_isSession( session ) );
 
1293
 
998
1294
    return tr_rpcIsEnabled( session->rpcServer );
999
1295
}
1000
1296
 
1001
1297
void
1002
1298
tr_sessionSetRPCPort( tr_session * session,
1003
 
                      uint16_t     port )
 
1299
                      tr_port      port )
1004
1300
{
 
1301
    assert( tr_isSession( session ) );
 
1302
 
1005
1303
    tr_rpcSetPort( session->rpcServer, port );
1006
1304
}
1007
1305
 
1008
 
uint16_t
 
1306
tr_port 
1009
1307
tr_sessionGetRPCPort( const tr_session * session )
1010
1308
{
 
1309
    assert( tr_isSession( session ) );
 
1310
 
1011
1311
    return tr_rpcGetPort( session->rpcServer );
1012
1312
}
1013
1313
 
1016
1316
                          tr_rpc_func  func,
1017
1317
                          void *       user_data )
1018
1318
{
 
1319
    assert( tr_isSession( session ) );
 
1320
 
1019
1321
    session->rpc_func = func;
1020
1322
    session->rpc_func_user_data = user_data;
1021
1323
}
1024
1326
tr_sessionSetRPCWhitelist( tr_session * session,
1025
1327
                           const char * whitelist )
1026
1328
{
 
1329
    assert( tr_isSession( session ) );
 
1330
 
1027
1331
    tr_rpcSetWhitelist( session->rpcServer, whitelist );
1028
1332
}
1029
1333
 
1030
1334
char*
1031
1335
tr_sessionGetRPCWhitelist( const tr_session * session )
1032
1336
{
 
1337
    assert( tr_isSession( session ) );
 
1338
 
1033
1339
    return tr_rpcGetWhitelist( session->rpcServer );
1034
1340
}
1035
1341
 
1036
1342
void
1037
1343
tr_sessionSetRPCWhitelistEnabled( tr_session * session,
1038
 
                                  int          isEnabled )
 
1344
                                  tr_bool      isEnabled )
1039
1345
{
 
1346
    assert( tr_isSession( session ) );
 
1347
 
1040
1348
    tr_rpcSetWhitelistEnabled( session->rpcServer, isEnabled );
1041
1349
}
1042
1350
 
1043
 
int
 
1351
tr_bool
1044
1352
tr_sessionGetRPCWhitelistEnabled( const tr_session * session )
1045
1353
{
 
1354
    assert( tr_isSession( session ) );
 
1355
 
1046
1356
    return tr_rpcGetWhitelistEnabled( session->rpcServer );
1047
1357
}
1048
1358
 
1051
1361
tr_sessionSetRPCPassword( tr_session * session,
1052
1362
                          const char * password )
1053
1363
{
 
1364
    assert( tr_isSession( session ) );
 
1365
 
1054
1366
    tr_rpcSetPassword( session->rpcServer, password );
1055
1367
}
1056
1368
 
1057
1369
char*
1058
1370
tr_sessionGetRPCPassword( const tr_session * session )
1059
1371
{
 
1372
    assert( tr_isSession( session ) );
 
1373
 
1060
1374
    return tr_rpcGetPassword( session->rpcServer );
1061
1375
}
1062
1376
 
1064
1378
tr_sessionSetRPCUsername( tr_session * session,
1065
1379
                          const char * username )
1066
1380
{
 
1381
    assert( tr_isSession( session ) );
 
1382
 
1067
1383
    tr_rpcSetUsername( session->rpcServer, username );
1068
1384
}
1069
1385
 
1070
1386
char*
1071
1387
tr_sessionGetRPCUsername( const tr_session * session )
1072
1388
{
 
1389
    assert( tr_isSession( session ) );
 
1390
 
1073
1391
    return tr_rpcGetUsername( session->rpcServer );
1074
1392
}
1075
1393
 
1076
1394
void
1077
1395
tr_sessionSetRPCPasswordEnabled( tr_session * session,
1078
 
                                 int          isEnabled )
 
1396
                                 tr_bool      isEnabled )
1079
1397
{
 
1398
    assert( tr_isSession( session ) );
 
1399
 
1080
1400
    tr_rpcSetPasswordEnabled( session->rpcServer, isEnabled );
1081
1401
}
1082
1402
 
1083
 
int
 
1403
tr_bool
1084
1404
tr_sessionIsRPCPasswordEnabled( const tr_session * session )
1085
1405
{
 
1406
    assert( tr_isSession( session ) );
 
1407
 
1086
1408
    return tr_rpcIsPasswordEnabled( session->rpcServer );
1087
1409
}
1088
1410
 
1090
1412
****
1091
1413
***/
1092
1414
 
1093
 
int
 
1415
tr_bool
1094
1416
tr_sessionIsProxyEnabled( const tr_session * session )
1095
1417
{
 
1418
    assert( tr_isSession( session ) );
 
1419
 
1096
1420
    return session->isProxyEnabled;
1097
1421
}
1098
1422
 
1099
1423
void
1100
1424
tr_sessionSetProxyEnabled( tr_session * session,
1101
 
                           int          isEnabled )
 
1425
                           tr_bool      isEnabled )
1102
1426
{
1103
 
    session->isProxyEnabled = isEnabled ? 1 : 0;
 
1427
    assert( tr_isSession( session ) );
 
1428
 
 
1429
    session->isProxyEnabled = isEnabled != 0;
1104
1430
}
1105
1431
 
1106
1432
tr_proxy_type
1107
1433
tr_sessionGetProxyType( const tr_session * session )
1108
1434
{
 
1435
    assert( tr_isSession( session ) );
 
1436
 
1109
1437
    return session->proxyType;
1110
1438
}
1111
1439
 
1113
1441
tr_sessionSetProxyType( tr_session *  session,
1114
1442
                        tr_proxy_type type )
1115
1443
{
 
1444
    assert( tr_isSession( session ) );
 
1445
 
1116
1446
    session->proxyType = type;
1117
1447
}
1118
1448
 
1119
1449
const char*
1120
1450
tr_sessionGetProxy( const tr_session * session )
1121
1451
{
 
1452
    assert( tr_isSession( session ) );
 
1453
 
1122
1454
    return session->proxy;
1123
1455
}
1124
1456
 
1125
 
int
 
1457
tr_port
1126
1458
tr_sessionGetProxyPort( const tr_session * session )
1127
1459
{
 
1460
    assert( tr_isSession( session ) );
 
1461
 
1128
1462
    return session->proxyPort;
1129
1463
}
1130
1464
 
1132
1466
tr_sessionSetProxy( tr_session * session,
1133
1467
                    const char * proxy )
1134
1468
{
 
1469
    assert( tr_isSession( session ) );
 
1470
 
1135
1471
    if( proxy != session->proxy )
1136
1472
    {
1137
1473
        tr_free( session->proxy );
1141
1477
 
1142
1478
void
1143
1479
tr_sessionSetProxyPort( tr_session * session,
1144
 
                        int          port )
 
1480
                        tr_port      port )
1145
1481
{
 
1482
    assert( tr_isSession( session ) );
 
1483
 
1146
1484
    session->proxyPort = port;
1147
1485
}
1148
1486
 
1149
 
int
 
1487
tr_bool
1150
1488
tr_sessionIsProxyAuthEnabled( const tr_session * session )
1151
1489
{
 
1490
    assert( tr_isSession( session ) );
 
1491
 
1152
1492
    return session->isProxyAuthEnabled;
1153
1493
}
1154
1494
 
1155
1495
void
1156
1496
tr_sessionSetProxyAuthEnabled( tr_session * session,
1157
 
                               int          isEnabled )
 
1497
                               tr_bool      isEnabled )
1158
1498
{
1159
 
    session->isProxyAuthEnabled = isEnabled ? 1 : 0;
 
1499
    assert( tr_isSession( session ) );
 
1500
 
 
1501
    session->isProxyAuthEnabled = isEnabled != 0;
1160
1502
}
1161
1503
 
1162
1504
const char*
1163
1505
tr_sessionGetProxyUsername( const tr_session * session )
1164
1506
{
 
1507
    assert( tr_isSession( session ) );
 
1508
 
1165
1509
    return session->proxyUsername;
1166
1510
}
1167
1511
 
1169
1513
tr_sessionSetProxyUsername( tr_session * session,
1170
1514
                            const char * username )
1171
1515
{
 
1516
    assert( tr_isSession( session ) );
 
1517
 
1172
1518
    if( username != session->proxyUsername )
1173
1519
    {
1174
1520
        tr_free( session->proxyUsername );
1179
1525
const char*
1180
1526
tr_sessionGetProxyPassword( const tr_session * session )
1181
1527
{
 
1528
    assert( tr_isSession( session ) );
 
1529
 
1182
1530
    return session->proxyPassword;
1183
1531
}
1184
1532
 
1186
1534
tr_sessionSetProxyPassword( tr_session * session,
1187
1535
                            const char * password )
1188
1536
{
 
1537
    assert( tr_isSession( session ) );
 
1538
 
1189
1539
    if( password != session->proxyPassword )
1190
1540
    {
1191
1541
        tr_free( session->proxyPassword );
1193
1543
    }
1194
1544
}
1195
1545
 
 
1546
int
 
1547
tr_sessionGetActiveTorrentCount( tr_session * session )
 
1548
{
 
1549
    int ret = 0;
 
1550
    tr_torrent * tor = NULL;
 
1551
 
 
1552
    assert( tr_isSession( session ) );
 
1553
 
 
1554
    while(( tor = tr_torrentNext( session, tor )))
 
1555
        if( tr_torrentGetActivity( tor ) != TR_STATUS_STOPPED )
 
1556
            ++ret;
 
1557
    
 
1558
    return ret;
 
1559
}