(trunk) #1559: Simplify tr_sessionInitFull

This commit is contained in:
Charles Kerr 2008-12-13 23:17:36 +00:00
parent 35f40bdfa6
commit 6b0d98a695
22 changed files with 900 additions and 1198 deletions

332
cli/cli.c
View File

@ -38,23 +38,14 @@
#define LINEWIDTH 80
#define MY_NAME "transmission-cli"
static int showInfo = 0;
static int showScrape = 0;
static int isPrivate = 0;
static int verboseLevel = 0;
static int encryptionMode = TR_DEFAULT_ENCRYPTION;
static int peerPort = TR_DEFAULT_PORT;
static int peerSocketTOS = TR_DEFAULT_PEER_SOCKET_TOS;
static int blocklistEnabled = TR_DEFAULT_BLOCKLIST_ENABLED;
static int uploadLimit = 20;
static int downloadLimit = -1;
static int natTraversal = TR_DEFAULT_PORT_FORWARDING_ENABLED;
static int verify = 0;
static tr_bool showInfo = 0;
static tr_bool showScrape = 0;
static tr_bool isPrivate = 0;
static tr_bool verify = 0;
static sig_atomic_t gotsig = 0;
static sig_atomic_t manualUpdate = 0;
static const char * torrentPath = NULL;
static const char * downloadDir = NULL;
static const char * finishCall = NULL;
static const char * announce = NULL;
static const char * configdir = NULL;
@ -63,57 +54,30 @@ static const char * comment = NULL;
static const struct tr_option options[] =
{
{ 'a', "announce", "Set the new torrent's announce URL",
"a", 1, "<url>" },
{ 'b', "blocklist", "Enable peer blocklists",
"b", 0, NULL },
{ 'B', "no-blocklist", "Disable peer blocklists",
"B", 0, NULL },
{ 'c', "comment", "Set the new torrent's comment",
"c", 1, "<comment>" },
{ 'd', "downlimit", "Set max download speed in KB/s",
"d", 1, "<speed>" },
{ 'D', "no-downlimit", "Don't limit the download speed",
"D", 0, NULL },
{ 910, "encryption-required", "Encrypt all peer connections",
"er", 0, NULL },
{ 911, "encryption-preferred", "Prefer encrypted peer connections",
"ep", 0, NULL },
{ 912, "encryption-tolerated", "Prefer unencrypted peer connections",
"et", 0, NULL },
{ 'f', "finish", "Run a script when the torrent finishes",
"f", 1, "<script>" },
{ 'g', "config-dir", "Where to find configuration files",
"g", 1, "<path>" },
{ 'i', "info", "Show torrent details and exit",
"i", 0, NULL },
{ 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP",
"m", 0, NULL },
{ 'M', "no-portmap", "Disable portmapping",
"M", 0, NULL },
{ 'n', "new", "Create a new torrent",
"n", 1, "<source>" },
{ 'p', "port",
"Port for incoming peers (Default: " TR_DEFAULT_PORT_STR ")",
"p", 1, "<port>" },
{ 'r', "private", "Set the new torrent's 'private' flag",
"r", 0, NULL },
{ 's', "scrape", "Scrape the torrent and exit",
"s", 0, NULL },
{ 't', "tos",
"Peer socket TOS (0 to 255, default=" TR_DEFAULT_PEER_SOCKET_TOS_STR
")",
"t", 1, "<tos>" },
{ 'u', "uplimit", "Set max upload speed in KB/s",
"u", 1, "<speed>" },
{ 'U', "no-uplimit", "Don't limit the upload speed",
"U", 0, NULL },
{ 'v', "verify", "Verify the specified torrent",
"v", 0, NULL },
{ 'w', "download-dir", "Where to save downloaded data",
"w", 1, "<path>" },
{ 0, NULL, NULL,
NULL, 0, NULL }
{ 'a', "announce", "Set the new torrent's announce URL", "a", 1, "<url>" },
{ 'b', "blocklist", "Enable peer blocklists", "b", 0, NULL },
{ 'B', "no-blocklist", "Disable peer blocklists", "B", 0, NULL },
{ 'c', "comment", "Set the new torrent's comment", "c", 1, "<comment>" },
{ 'd', "downlimit", "Set max download speed in KB/s", "d", 1, "<speed>" },
{ 'D', "no-downlimit", "Don't limit the download speed", "D", 0, NULL },
{ 910, "encryption-required", "Encrypt all peer connections", "er", 0, NULL },
{ 911, "encryption-preferred", "Prefer encrypted peer connections", "ep", 0, NULL },
{ 912, "encryption-tolerated", "Prefer unencrypted peer connections", "et", 0, NULL },
{ 'f', "finish", "Run a script when the torrent finishes", "f", 1, "<script>" },
{ 'g', "config-dir", "Where to find configuration files", "g", 1, "<path>" },
{ 'i', "info", "Show torrent details and exit", "i", 0, NULL },
{ 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP", "m", 0, NULL },
{ 'M', "no-portmap", "Disable portmapping", "M", 0, NULL },
{ 'n', "new", "Create a new torrent", "n", 1, "<source>" },
{ 'p', "port", "Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")", "p", 1, "<port>" },
{ 'r', "private", "Set the new torrent's 'private' flag", "r", 0, NULL },
{ 's', "scrape", "Scrape the torrent and exit", "s", 0, NULL },
{ 't', "tos", "Peer socket TOS (0 to 255, default=" TR_DEFAULT_PEER_SOCKET_TOS_STR ")", "t", 1, "<tos>" },
{ 'u', "uplimit", "Set max upload speed in KB/s", "u", 1, "<speed>" },
{ 'U', "no-uplimit", "Don't limit the upload speed", "U", 0, NULL },
{ 'v', "verify", "Verify the specified torrent", "v", 0, NULL },
{ 'w', "download-dir", "Where to save downloaded data", "w", 1, "<path>" },
{ 0, NULL, NULL, NULL, 0, NULL }
};
static const char *
@ -124,8 +88,7 @@ getUsage( void )
"Usage: " MY_NAME " [options] <torrent-filename>";
}
static int parseCommandLine( int argc,
const char ** argv );
static int parseCommandLine( tr_benc*, int argc, const char ** argv );
static void sigHandler( int signal );
@ -301,6 +264,26 @@ getStatusStr( const tr_stat * st,
else *buf = '\0';
}
static const char*
getConfigDir( int argc, const char ** argv )
{
int c;
const char * configDir = NULL;
const char * optarg;
const int ind = tr_optind;
while(( c = tr_getopt( getUsage( ), argc, argv, options, &optarg )))
if( c == 'g' )
configdir = optarg;
tr_optind = ind;
if( configDir == NULL )
configDir = tr_getDefaultConfigDir( MY_NAME );
return configDir;
}
int
main( int argc,
char ** argv )
@ -309,6 +292,8 @@ main( int argc,
tr_session * h;
tr_ctor * ctor;
tr_torrent * tor = NULL;
tr_benc settings;
const char * configDir;
printf( "Transmission %s - http://www.transmissionbt.com/\n",
LONG_VERSION_STRING );
@ -319,71 +304,27 @@ main( int argc,
return EXIT_FAILURE;
}
/* Get options */
if( parseCommandLine( argc, (const char**)argv ) )
/* load the defaults from config file + libtransmission defaults */
tr_bencInitDict( &settings, 0 );
configDir = getConfigDir( argc, (const char**)argv );
tr_sessionLoadSettings( &settings, configDir, MY_NAME );
/* the command line overrides defaults */
if( parseCommandLine( &settings, argc, (const char**)argv ) )
return EXIT_FAILURE;
/* Check the options for validity */
if( !torrentPath )
{
if( !torrentPath ) {
fprintf( stderr, "No torrent specified!\n" );
return EXIT_FAILURE;
}
if( peerPort < 1 || peerPort > 65535 )
{
fprintf( stderr, "Error: Port must between 1 and 65535; got %d\n",
peerPort );
return EXIT_FAILURE;
}
if( peerSocketTOS < 0 || peerSocketTOS > 255 )
{
fprintf( stderr, "Error: value must between 0 and 255; got %d\n",
peerSocketTOS );
return EXIT_FAILURE;
}
/* don't bind the port if we're just running the CLI
* to get metainfo or to create a torrent */
to get metainfo or to create a torrent */
if( showInfo || showScrape || ( sourceFile != NULL ) )
peerPort = -1;
tr_bencDictAddInt( &settings, TR_PREFS_KEY_PEER_PORT, -1 );
if( configdir == NULL )
configdir = tr_getDefaultConfigDir( );
if( downloadDir == NULL )
downloadDir = tr_getDefaultDownloadDir( );
/* Initialize libtransmission */
h = tr_sessionInitFull(
configdir,
"cli", /* tag */
downloadDir, /* where to download torrents */
TR_DEFAULT_PEX_ENABLED,
natTraversal, /* nat enabled */
peerPort,
encryptionMode,
TR_DEFAULT_LAZY_BITFIELD_ENABLED,
uploadLimit >= 0,
uploadLimit,
downloadLimit >= 0,
downloadLimit,
TR_DEFAULT_GLOBAL_PEER_LIMIT,
verboseLevel + 1, /* messageLevel */
0, /* is message queueing enabled? */
blocklistEnabled,
peerSocketTOS,
TR_DEFAULT_RPC_ENABLED,
TR_DEFAULT_RPC_PORT,
TR_DEFAULT_RPC_WHITELIST_ENABLED,
TR_DEFAULT_RPC_WHITELIST,
FALSE, "fnord", "potzrebie",
TR_DEFAULT_PROXY_ENABLED,
TR_DEFAULT_PROXY,
TR_DEFAULT_PROXY_PORT,
TR_DEFAULT_PROXY_TYPE,
TR_DEFAULT_PROXY_AUTH_ENABLED,
TR_DEFAULT_PROXY_USERNAME,
TR_DEFAULT_PROXY_PASSWORD );
h = tr_sessionInit( "cli", configDir, FALSE, &settings );
if( sourceFile && *sourceFile ) /* creating a torrent */
{
@ -407,7 +348,6 @@ main( int argc,
ctor = tr_ctorNew( h );
tr_ctorSetMetainfoFromFile( ctor, torrentPath );
tr_ctorSetPaused( ctor, TR_FORCE, showScrape );
tr_ctorSetDownloadDir( ctor, TR_FORCE, downloadDir );
if( showScrape )
{
@ -521,7 +461,11 @@ main( int argc,
}
cleanup:
tr_sessionSaveSettings( h, configDir, &settings );
printf( "\n" );
tr_bencFree( &settings );
tr_sessionClose( h );
return EXIT_SUCCESS;
}
@ -532,112 +476,68 @@ cleanup:
****
***/
static void
showUsage( void )
{
tr_getopt_usage( MY_NAME, getUsage( ), options );
exit( 0 );
}
static int
numarg( const char * arg )
{
char * end = NULL;
const long num = strtol( arg, &end, 10 );
if( *end )
{
fprintf( stderr, "Not a number: \"%s\"\n", arg );
showUsage( );
}
return num;
}
static int
parseCommandLine( int argc,
const char ** argv )
parseCommandLine( tr_benc * d, int argc, const char ** argv )
{
int c;
const char * optarg;
while( ( c = tr_getopt( getUsage( ), argc, argv, options, &optarg ) ) )
while(( c = tr_getopt( getUsage( ), argc, argv, options, &optarg )))
{
switch( c )
{
case 'a':
announce = optarg; break;
case 'b':
blocklistEnabled = 1; break;
case 'B':
blocklistEnabled = 0; break;
case 'c':
comment = optarg; break;
case 'd':
downloadLimit = numarg( optarg ); break;
case 'D':
downloadLimit = -1; break;
case 'f':
finishCall = optarg; break;
case 'g':
configdir = optarg; break;
case 'i':
showInfo = 1; break;
case 'm':
natTraversal = 1; break;
case 'M':
natTraversal = 0; break;
case 'n':
sourceFile = optarg; break;
case 'p':
peerPort = numarg( optarg ); break;
case 'r':
isPrivate = 1; break;
case 's':
showScrape = 1; break;
case 't':
peerSocketTOS = numarg( optarg ); break;
case 'u':
uploadLimit = numarg( optarg ); break;
case 'U':
uploadLimit = -1; break;
case 'v':
verify = 1; break;
case 'w':
downloadDir = optarg; break;
case 910:
encryptionMode = TR_ENCRYPTION_REQUIRED; break;
case 911:
encryptionMode = TR_CLEAR_PREFERRED; break;
case 912:
encryptionMode = TR_ENCRYPTION_PREFERRED; break;
case 'b': tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, 1 );
break;
case 'B': tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, 0 );
break;
case 'c': comment = optarg;
break;
case 'd': tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED, atoi( optarg ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, 1 );
break;
case 'D': tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, 0 );
break;
case 'f': finishCall = optarg;
break;
case 'g': /* handled above */
break;
case 'i': showInfo = 1;
break;
case 'm': tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, 1 );
break;
case 'M': tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, 0 );
break;
case 'n': sourceFile = optarg; break;
case 'p': tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, 1 );
break;
case 'r': isPrivate = 1;
break;
case 's': showScrape = 1;
break;
case 't': tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_SOCKET_TOS, atoi( optarg ) );
break;
case 'u': tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, atoi( optarg ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, 1 );
break;
case 'U': tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, 0 );
break;
case 'v': verify = 1;
break;
case 'w': tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, optarg );
break;
case 910: tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, TR_ENCRYPTION_REQUIRED );
break;
case 911: tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, TR_CLEAR_PREFERRED );
break;
case 912: tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, TR_ENCRYPTION_PREFERRED );
break;
case TR_OPT_UNK:
torrentPath = optarg; break;
default:
return 1;
torrentPath = optarg;
break;
default: return 1;
}
}

View File

@ -30,217 +30,11 @@
static int closing = FALSE;
static tr_session * mySession = NULL;
static char * myConfigFilename = NULL;
#define KEY_BLOCKLIST "blocklist-enabled"
#define KEY_DOWNLOAD_DIR "download-dir"
#define KEY_ENCRYPTION "encryption"
#define KEY_LAZY_BITFIELD "lazy-bitfield-enabled"
#define KEY_PEER_LIMIT "max-peers-global"
#define KEY_PEER_PORT "peer-port"
#define KEY_PORT_FORWARDING "port-forwarding-enabled"
#define KEY_PEX_ENABLED "pex-enabled"
#define KEY_AUTH_REQUIRED "rpc-authentication-required"
#define KEY_USERNAME "rpc-username"
#define KEY_PASSWORD "rpc-password"
#define KEY_WHITELIST "rpc-whitelist"
#define KEY_WHITELIST_ENABLED "rpc-whitelist-enabled"
#define KEY_RPC_PORT "rpc-port"
#define KEY_DSPEED "download-limit"
#define KEY_DSPEED_ENABLED "download-limit-enabled"
#define KEY_USPEED "upload-limit"
#define KEY_USPEED_ENABLED "upload-limit-enabled"
#define CONFIG_FILE "settings.json"
/***
**** Config File
***/
static void
replaceInt( tr_benc * dict,
const char * key,
int64_t value )
{
tr_bencDictRemove( dict, key );
tr_bencDictAddInt( dict, key, value );
}
static void
replaceStr( tr_benc * dict,
const char * key,
const char* value )
{
tr_bencDictRemove( dict, key );
tr_bencDictAddStr( dict, key, value );
}
static void
saveState( tr_session * s )
{
int i, n = 0;
char * strs[4];
tr_benc d;
if( tr_bencLoadJSONFile( myConfigFilename, &d ) )
tr_bencInitDict( &d, 16 );
replaceInt( &d, KEY_BLOCKLIST, tr_blocklistIsEnabled( s ) );
replaceStr( &d, KEY_DOWNLOAD_DIR, tr_sessionGetDownloadDir( s ) );
replaceInt( &d, KEY_PEER_LIMIT, tr_sessionGetPeerLimit( s ) );
replaceInt( &d, KEY_PEER_PORT, tr_sessionGetPeerPort( s ) );
replaceInt( &d, KEY_PORT_FORWARDING, tr_sessionIsPortForwardingEnabled( s ) );
replaceInt( &d, KEY_PEX_ENABLED, tr_sessionIsPexEnabled( s ) );
replaceStr( &d, KEY_USERNAME, strs[n++] = tr_sessionGetRPCUsername( s ) );
replaceStr( &d, KEY_PASSWORD, strs[n++] = tr_sessionGetRPCPassword( s ) );
replaceStr( &d, KEY_WHITELIST, strs[n++] = tr_sessionGetRPCWhitelist( s ) );
replaceInt( &d, KEY_RPC_PORT, tr_sessionGetRPCPort( s ) );
replaceInt( &d, KEY_AUTH_REQUIRED, tr_sessionIsRPCPasswordEnabled( s ) );
replaceInt( &d, KEY_DSPEED, tr_sessionGetSpeedLimit( s, TR_DOWN ) );
replaceInt( &d, KEY_DSPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) );
replaceInt( &d, KEY_USPEED, tr_sessionGetSpeedLimit( s, TR_UP ) );
replaceInt( &d, KEY_USPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );
replaceInt( &d, KEY_ENCRYPTION, tr_sessionGetEncryption( s ) );
tr_bencSaveJSONFile( myConfigFilename, &d );
tr_bencFree( &d );
tr_ninf( MY_NAME, "saved \"%s\"", myConfigFilename );
for( i = 0; i < n; ++i )
tr_free( strs[i] );
}
static void
getConfigInt( tr_benc * dict,
const char * key,
int * setme,
int defaultVal )
{
if( *setme < 0 )
{
int64_t i;
if( tr_bencDictFindInt( dict, key, &i ) )
*setme = i;
else
*setme = defaultVal;
}
}
static void
getConfigStr( tr_benc * dict,
const char * key,
const char ** setme,
const char * defaultVal )
{
if( !*setme )
{
const char * s;
if( tr_bencDictFindStr( dict, key, &s ) )
*setme = s;
else
*setme = defaultVal;
}
}
/**
* @param port port number, or -1 if not set in the command line
* @param auth TRUE, FALSE, or -1 if not set on the command line
* @param blocklist TRUE, FALSE, or -1 if not set on the command line
*/
static void
session_init( const char * configDir,
const char * downloadDir,
int rpcPort,
const char * whitelist,
int authRequired,
const char * username,
const char * password,
int blocklistEnabled )
{
tr_benc state, *dict = NULL;
int peerPort = -1, peers = -1;
int whitelistEnabled = -1;
int pexEnabled = -1;
int fwdEnabled = -1;
int upLimit = -1, upLimited = -1, downLimit = -1,
downLimited = -1;
int encryption = -1;
int useLazyBitfield = -1;
tr_ctor * ctor;
tr_torrent ** torrents;
if( !tr_bencLoadJSONFile( myConfigFilename, &state ) )
dict = &state;
/***
**** Decide on which values to pass into tr_sessionInitFull().
**** The command-line arguments are given precedence and
**** the state file from the previous session is used as a fallback.
**** If neither of those can be found, the TR_DEFAULT fields are used .
***/
getConfigStr( dict, KEY_DOWNLOAD_DIR, &downloadDir, TR_DEFAULT_DOWNLOAD_DIR );
getConfigInt( dict, KEY_PEX_ENABLED, &pexEnabled, TR_DEFAULT_PEX_ENABLED );
getConfigInt( dict, KEY_PORT_FORWARDING, &fwdEnabled, TR_DEFAULT_PORT_FORWARDING_ENABLED );
getConfigInt( dict, KEY_PEER_PORT, &peerPort, TR_DEFAULT_PORT );
getConfigInt( dict, KEY_DSPEED, &downLimit, 100 );
getConfigInt( dict, KEY_DSPEED_ENABLED, &downLimited, FALSE );
getConfigInt( dict, KEY_USPEED, &upLimit, 100 );
getConfigInt( dict, KEY_USPEED_ENABLED, &upLimited, FALSE );
getConfigInt( dict, KEY_LAZY_BITFIELD, &useLazyBitfield, TR_DEFAULT_LAZY_BITFIELD_ENABLED );
getConfigInt( dict, KEY_PEER_LIMIT, &peers, TR_DEFAULT_GLOBAL_PEER_LIMIT );
getConfigInt( dict, KEY_BLOCKLIST, &blocklistEnabled, TR_DEFAULT_BLOCKLIST_ENABLED );
getConfigInt( dict, KEY_RPC_PORT, &rpcPort, TR_DEFAULT_RPC_PORT );
getConfigStr( dict, KEY_WHITELIST, &whitelist, TR_DEFAULT_RPC_WHITELIST );
getConfigInt( dict, KEY_AUTH_REQUIRED, &authRequired, FALSE );
getConfigStr( dict, KEY_USERNAME, &username, NULL );
getConfigStr( dict, KEY_PASSWORD, &password, NULL );
getConfigInt( dict, KEY_ENCRYPTION, &encryption, TR_DEFAULT_ENCRYPTION );
whitelistEnabled = whitelist && *whitelist;
/***
****
***/
/* start the session */
mySession = tr_sessionInitFull( configDir, "daemon", downloadDir,
pexEnabled, fwdEnabled, peerPort,
encryption,
useLazyBitfield,
upLimited, upLimit,
downLimited, downLimit,
peers,
TR_MSG_INF, 0,
blocklistEnabled,
TR_DEFAULT_PEER_SOCKET_TOS,
TRUE, rpcPort,
whitelistEnabled, whitelist,
authRequired, username, password,
TR_DEFAULT_PROXY_ENABLED,
TR_DEFAULT_PROXY,
TR_DEFAULT_PROXY_PORT,
TR_DEFAULT_PROXY_TYPE,
TR_DEFAULT_PROXY_AUTH_ENABLED,
TR_DEFAULT_PROXY_USERNAME,
TR_DEFAULT_PROXY_PASSWORD );
if( authRequired )
tr_ninf( MY_NAME, "requiring authentication" );
/* load the torrents */
ctor = tr_ctorNew( mySession );
torrents = tr_sessionLoadTorrents( mySession, ctor, NULL );
tr_free( torrents );
tr_ctorFree( ctor );
if( dict )
tr_bencFree( &state );
}
static const char *
getUsage( void )
{
@ -256,32 +50,18 @@ getUsage( void )
static const struct tr_option options[] =
{
{ 'a', "allowed",
"Allowed IP addresses. (Default: " TR_DEFAULT_RPC_WHITELIST ")", "a",
1, "<list>" },
{ 'b', "blocklist", "Enable peer blocklists",
"b", 0, NULL },
{ 'B', "no-blocklist", "Disable peer blocklists",
"B", 0, NULL },
{ 'f', "foreground", "Run in the foreground instead of daemonizing",
"f", 0, NULL },
{ 'g', "config-dir", "Where to look for configuration files",
"g", 1, "<path>" },
{ 'p', "port",
"RPC port (Default: " TR_DEFAULT_RPC_PORT_STR ")", "p",
1, "<port>" },
{ 't', "auth", "Require authentication",
"t", 0, NULL },
{ 'T', "no-auth", "Don't require authentication",
"T", 0, NULL },
{ 'u', "username", "Set username for authentication",
"u", 1, "<username>" },
{ 'v', "password", "Set password for authentication",
"v", 1, "<password>" },
{ 'w', "download-dir", "Where to save downloaded data",
"w", 1, "<path>" },
{ 0, NULL, NULL,
NULL, 0, NULL }
{ 'a', "allowed", "Allowed IP addresses. (Default: " TR_DEFAULT_RPC_WHITELIST ")", "a", 1, "<list>" },
{ 'b', "blocklist", "Enable peer blocklists", "b", 0, NULL },
{ 'B', "no-blocklist", "Disable peer blocklists", "B", 0, NULL },
{ 'f', "foreground", "Run in the foreground instead of daemonizing", "f", 0, NULL },
{ 'g', "config-dir", "Where to look for configuration files", "g", 1, "<path>" },
{ 'p', "port", "RPC port (Default: " TR_DEFAULT_RPC_PORT_STR ")", "p", 1, "<port>" },
{ 't', "auth", "Require authentication", "t", 0, NULL },
{ 'T', "no-auth", "Don't require authentication", "T", 0, NULL },
{ 'u', "username", "Set username for authentication", "u", 1, "<username>" },
{ 'v', "password", "Set password for authentication", "v", 1, "<password>" },
{ 'w', "download-dir", "Where to save downloaded data", "w", 1, "<path>" },
{ 0, NULL, NULL, NULL, 0, NULL }
};
static void
@ -291,65 +71,6 @@ showUsage( void )
exit( 0 );
}
static void
readargs( int argc,
const char ** argv,
int * nofork,
const char ** configDir,
const char ** downloadDir,
int * rpcPort,
const char ** whitelist,
int * authRequired,
const char ** username,
const char ** password,
int * blocklistEnabled )
{
int c;
const char * optarg;
while( ( c = tr_getopt( getUsage( ), argc, argv, options, &optarg ) ) )
{
switch( c )
{
case 'a':
*whitelist = optarg; break;
case 'b':
*blocklistEnabled = 1; break;
case 'B':
*blocklistEnabled = 0; break;
case 'f':
*nofork = 1; break;
case 'g':
*configDir = optarg; break;
case 'p':
*rpcPort = atoi( optarg ); break;
case 't':
*authRequired = TRUE; break;
case 'T':
*authRequired = FALSE; break;
case 'u':
*username = optarg; break;
case 'v':
*password = optarg; break;
case 'w':
*downloadDir = optarg; break;
default:
showUsage( ); break;
}
}
}
static void
gotsig( int sig UNUSED )
{
@ -433,20 +154,36 @@ daemon( int nochdir,
#endif
#endif
static const char*
getConfigDir( int argc, const char ** argv )
{
int c;
const char * configDir = NULL;
const char * optarg;
const int ind = tr_optind;
while(( c = tr_getopt( getUsage( ), argc, argv, options, &optarg )))
if( c == 'g' )
configDir = optarg;
tr_optind = ind;
if( configDir == NULL )
configDir = tr_getDefaultConfigDir( MY_NAME );
return configDir;
}
int
main( int argc,
char ** argv )
{
int nofork = 0;
int rpcPort = -1;
int authRequired = -1;
int blocklistEnabled = -1;
char * freeme = NULL;
int c;
const char * optarg;
tr_benc settings;
tr_bool foreground = FALSE;
const char * configDir = NULL;
const char * downloadDir = NULL;
const char * whitelist = NULL;
const char * username = NULL;
const char * password = NULL;
signal( SIGINT, gotsig );
signal( SIGTERM, gotsig );
@ -456,18 +193,45 @@ main( int argc,
signal( SIGHUP, SIG_IGN );
#endif
readargs( argc, (const char**)argv, &nofork, &configDir, &downloadDir,
&rpcPort, &whitelist, &authRequired, &username, &password,
&blocklistEnabled );
if( configDir == NULL )
configDir = getenv( "TRANSMISSION_HOME" );
if( configDir == NULL )
configDir = freeme = tr_strdup_printf( "%s-daemon",
tr_getDefaultConfigDir( ) );
myConfigFilename = tr_buildPath( configDir, CONFIG_FILE, NULL );
/* load settings from defaults + config file */
tr_bencInitDict( &settings, 0 );
configDir = getConfigDir( argc, (const char**)argv );
tr_sessionLoadSettings( &settings, configDir, MY_NAME );
/* overwrite settings from the comamndline */
tr_optind = 1;
while(( c = tr_getopt( getUsage(), argc, (const char**)argv, options, &optarg ))) {
switch( c ) {
case 'a': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_WHITELIST, optarg );
tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, 1 );
break;
case 'b': tr_bencDictAddInt( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, 1 );
break;
case 'B': tr_bencDictAddInt( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, 0 );
break;
case 'f': foreground = TRUE;
break;
case 'g': /* handled above */
break;
case 'p': tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_PORT, atoi( optarg ) );
break;
case 't': tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, 0 );
break;
case 'T': tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, 1 );
break;
case 'u': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_USERNAME, optarg );
break;
case 'v': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_PASSWORD, optarg );
break;
case 'w': tr_bencDictAddStr( &settings, TR_PREFS_KEY_DOWNLOAD_DIR, optarg );
break;
default: showUsage( );
break;
}
}
#ifndef WIN32
if( !nofork )
if( !foreground )
{
if( 0 > daemon( 1, 0 ) )
{
@ -477,20 +241,30 @@ main( int argc,
}
#endif
session_init( configDir, downloadDir,
rpcPort, whitelist, authRequired, username, password,
blocklistEnabled );
/* start the session */
mySession = tr_sessionInit( "daemon", configDir, FALSE, &settings );
if( tr_bencDictFindInt( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, NULL ) )
tr_ninf( MY_NAME, "requiring authentication" );
/* load the torrents */
{
tr_ctor * ctor = tr_ctorNew( mySession );
tr_torrent ** torrents = tr_sessionLoadTorrents( mySession, ctor, NULL );
tr_free( torrents );
tr_ctorFree( ctor );
}
while( !closing )
tr_wait( 1000 ); /* sleep one second */
saveState( mySession );
/* shutdown */
printf( "Closing transmission session..." );
tr_sessionSaveSettings( mySession, configDir, &settings );
tr_sessionClose( mySession );
printf( " done.\n" );
tr_free( freeme );
tr_free( myConfigFilename );
/* cleanup */
tr_bencFree( &settings );
return 0;
}

View File

@ -34,7 +34,7 @@
#define MY_NAME "transmission-remote"
#define DEFAULT_HOST "localhost"
#define DEFAULT_PORT TR_DEFAULT_RPC_PORT
#define DEFAULT_PORT atoi(TR_DEFAULT_RPC_PORT_STR)
enum { TAG_LIST, TAG_DETAILS, TAG_FILES, TAG_PEERS };
@ -89,7 +89,7 @@ static tr_option opts[] =
{ 'n', "auth", "Set authentication info",
"n", 1, "<username:password>" },
{ 'p', "port",
"Port for incoming peers (Default: " TR_DEFAULT_PORT_STR ")",
"Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")",
"p", 1, "<port>" },
{ 900, "priority-high", "Set the files' priorities as high",
"ph", 1, "<files>" },

View File

@ -42,7 +42,7 @@ get_recent_destinations( void )
}
static void
save_recent_destination( const char * dir )
save_recent_destination( TrCore * core, const char * dir )
{
int i;
GSList * list = get_recent_destinations( );
@ -70,7 +70,7 @@ save_recent_destination( const char * dir )
g_snprintf( key, sizeof( key ), "recent-download-dir-%d", i + 1 );
pref_string_set( key, l->data );
}
pref_save( );
pref_save( tr_core_session( core ) );
/* cleanup */
g_slist_foreach( list, (GFunc)g_free, NULL );
@ -116,17 +116,20 @@ addResponseCB( GtkDialog * dialog,
if( data->gtor )
{
if( response != GTK_RESPONSE_ACCEPT )
{
removeOldTorrent( data );
}
else
{
if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->
run_check ) ) )
if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->run_check ) ) )
tr_torrentStart( tr_torrent_handle( data->gtor ) );
tr_core_add_torrent( data->core, data->gtor );
if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->
trash_check ) ) )
if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->trash_check ) ) )
tr_file_trash_or_unlink( data->filename );
save_recent_destination( data->downloadDir );
save_recent_destination( data->core, data->downloadDir );
}
}

View File

@ -41,18 +41,20 @@
#include "conf.h"
#include "util.h"
#define MY_NAME "transmission"
static char * gl_confdir = NULL;
static char * gl_lockpath = NULL;
/* errstr may be NULL, this might be called before GTK is initialized */
gboolean
cf_init( const char *dir,
char ** errstr )
cf_init( const char * configDir,
char ** errstr )
{
if( errstr != NULL )
*errstr = NULL;
gl_confdir = g_strdup( dir );
gl_confdir = g_strdup( configDir );
if( mkdir_p( gl_confdir, 0755 ) )
return TRUE;
@ -151,25 +153,29 @@ getPrefsFilename( void )
static tr_benc*
getPrefs( void )
{
static tr_benc dict;
static tr_benc settings;
static gboolean loaded = FALSE;
if( !loaded )
{
char * filename = getPrefsFilename( );
if( tr_bencLoadJSONFile( filename, &dict ) )
tr_bencInitDict( &dict, 100 );
g_free( filename );
tr_bencInitDict( &settings, 0 );
tr_sessionLoadSettings( &settings, gl_confdir, MY_NAME );
loaded = TRUE;
}
return &dict;
return &settings;
}
/***
****
***/
tr_benc*
pref_get_all( void )
{
return getPrefs( );
}
int64_t
pref_int_get( const char * key )
{
@ -277,16 +283,9 @@ pref_string_set_default( const char * key,
***/
void
pref_save( void )
pref_save( tr_session * session )
{
char * filename = getPrefsFilename( );
char * path = g_path_get_dirname( filename );
mkdir_p( path, 0755 );
tr_bencSaveJSONFile( filename, getPrefs( ) );
g_free( path );
g_free( filename );
tr_sessionSaveSettings( session, gl_confdir, getPrefs( ) );
}
/***
@ -316,32 +315,29 @@ static char*
getCompat080PrefsFilename( void )
{
assert( gl_confdir != NULL );
return g_build_filename(
g_get_home_dir( ), ".transmission", "gtk", "prefs", NULL );
return g_build_filename( g_get_home_dir( ), ".transmission", "gtk", "prefs", NULL );
}
static char*
getCompat090PrefsFilename( void )
{
assert( gl_confdir != NULL );
return g_build_filename(
g_get_home_dir( ), ".transmission", "gtk", "prefs.ini", NULL );
return g_build_filename( g_get_home_dir( ), ".transmission", "gtk", "prefs.ini", NULL );
}
static char*
getCompat121PrefsFilename( void )
{
return g_build_filename(
g_get_user_config_dir( ), "transmission", "gtk", "prefs.ini",
NULL );
return g_build_filename( g_get_user_config_dir( ), "transmission", "gtk", "prefs.ini", NULL );
}
static void
translate_08_to_09( const char* oldfile,
const char* newfile )
{
static struct pref_entry
{
static struct pref_entry {
const char* oldkey;
const char* newkey;
} pref_table[] = {

View File

@ -22,6 +22,9 @@
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
struct tr_benc;
struct tr_handle;
/**
***
**/
@ -29,31 +32,20 @@
#ifndef TG_CONF_H
#define TG_CONF_H
int64_t pref_int_get( const char * key );
int64_t pref_int_get ( const char * key );
void pref_int_set ( const char * key, int64_t value );
void pref_int_set_default ( const char * key, int64_t value );
void pref_int_set( const char * key,
int64_t value );
gboolean pref_flag_get ( const char * key );
void pref_flag_set ( const char * key, gboolean value );
void pref_flag_set_default ( const char * key, gboolean value );
void pref_int_set_default( const char * key,
int64_t value );
const char* pref_string_get ( const char * key );
void pref_string_set ( const char * key, const char * value );
void pref_string_set_default( const char * key, const char * value );
gboolean pref_flag_get( const char * key );
void pref_flag_set( const char * key,
gboolean value );
void pref_flag_set_default( const char * key,
gboolean value );
const char* pref_string_get( const char * key );
void pref_string_set( const char * key,
const char * value );
void pref_string_set_default( const char * key,
const char * value );
void pref_save( void );
void pref_save ( struct tr_handle * );
struct tr_benc* pref_get_all ( void );
/**
***

View File

@ -68,6 +68,8 @@
#include <libtransmission/transmission.h>
#include <libtransmission/version.h>
#define MY_NAME "transmission"
/* interval in milliseconds to update the torrent list display */
#define UPDATE_INTERVAL 1666
@ -352,7 +354,7 @@ main( int argc,
gboolean showversion = FALSE;
gboolean startpaused = FALSE;
gboolean startminimized = FALSE;
char * domain = "transmission";
char * domain = MY_NAME;
char * configDir = NULL;
tr_lockfile_state_t tr_state;
@ -402,18 +404,17 @@ main( int argc,
}
if( configDir == NULL )
configDir = (char*) tr_getDefaultConfigDir( );
configDir = (char*) tr_getDefaultConfigDir( MY_NAME );
tr_notify_init( );
didinit = cf_init( configDir, NULL ); /* must come before actions_init */
tr_prefs_init_global( );
myUIManager = gtk_ui_manager_new ( );
actions_init ( myUIManager, cbdata );
gtk_ui_manager_add_ui_from_string ( myUIManager, fallback_ui_file, -1,
NULL );
gtk_ui_manager_add_ui_from_string ( myUIManager, fallback_ui_file, -1, NULL );
gtk_ui_manager_ensure_update ( myUIManager );
gtk_window_set_default_icon_name ( "transmission" );
gtk_window_set_default_icon_name ( MY_NAME );
setupsighandlers( ); /* set up handlers for fatal signals */
@ -440,49 +441,18 @@ main( int argc,
if( didlock && ( didinit || cf_init( configDir, &err ) ) )
{
GtkWindow * win;
tr_session * session;
tr_session * h = tr_sessionInitFull(
configDir,
"gtk",
pref_string_get( PREF_KEY_DOWNLOAD_DIR ),
pref_flag_get( PREF_KEY_PEX ),
pref_flag_get( PREF_KEY_PORT_FORWARDING ),
pref_int_get( PREF_KEY_PORT ),
pref_int_get( PREF_KEY_ENCRYPTION ),
pref_flag_get( PREF_KEY_LAZY_BITFIELD ),
pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED ),
pref_int_get( PREF_KEY_UL_LIMIT ),
pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED ),
pref_int_get( PREF_KEY_DL_LIMIT ),
pref_int_get( PREF_KEY_MAX_PEERS_GLOBAL ),
pref_int_get( PREF_KEY_MSGLEVEL ),
TRUE, /* message queueing */
pref_flag_get( PREF_KEY_BLOCKLIST_ENABLED ),
pref_int_get( PREF_KEY_PEER_SOCKET_TOS ),
pref_flag_get( PREF_KEY_RPC_ENABLED ),
pref_int_get( PREF_KEY_RPC_PORT ),
pref_flag_get( PREF_KEY_RPC_WHITELIST_ENABLED ),
pref_string_get( PREF_KEY_RPC_WHITELIST ),
pref_flag_get( PREF_KEY_RPC_AUTH_ENABLED ),
pref_string_get( PREF_KEY_RPC_USERNAME ),
pref_string_get( PREF_KEY_RPC_PASSWORD ),
pref_flag_get( PREF_KEY_PROXY_SERVER_ENABLED ),
pref_string_get( PREF_KEY_PROXY_SERVER ),
pref_int_get( PREF_KEY_PROXY_PORT ),
pref_int_get( PREF_KEY_PROXY_TYPE ),
pref_flag_get( PREF_KEY_PROXY_AUTH_ENABLED ),
pref_string_get( PREF_KEY_PROXY_USERNAME ),
pref_string_get( PREF_KEY_PROXY_PASSWORD ) );
cbdata->core = tr_core_new( h );
/* initialize the libtransmission session */
session = tr_sessionInit( "gtk", configDir, TRUE, pref_get_all( ) );
cbdata->core = tr_core_new( session );
/* create main window now to be a parent to any error dialogs */
win = GTK_WINDOW( tr_window_new( myUIManager, cbdata->core ) );
g_signal_connect( win, "size-allocate",
G_CALLBACK( onMainWindowSizeAllocated ), cbdata );
g_signal_connect( win, "size-allocate", G_CALLBACK( onMainWindowSizeAllocated ), cbdata );
appsetup( win, argfiles, cbdata, startpaused, startminimized );
tr_sessionSetRPCCallback( h, onRPCChanged, cbdata );
tr_sessionSetRPCCallback( session, onRPCChanged, cbdata );
gtr_blocklist_maybe_autoupdate( cbdata->core );
gtk_main( );
@ -555,13 +525,13 @@ updateScheduledLimits( gpointer data )
tr_inf ( _( "Ending use of scheduled bandwidth limits" ) );
b = pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED );
b = pref_flag_get( TR_PREFS_KEY_DSPEED_ENABLED );
tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, b );
limit = pref_int_get( PREF_KEY_DL_LIMIT );
limit = pref_int_get( TR_PREFS_KEY_DSPEED );
tr_sessionSetSpeedLimit( tr, TR_DOWN, limit );
b = pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED );
b = pref_flag_get( TR_PREFS_KEY_USPEED_ENABLED );
tr_sessionSetSpeedLimitEnabled( tr, TR_UP, b );
limit = pref_int_get( PREF_KEY_UL_LIMIT );
limit = pref_int_get( TR_PREFS_KEY_USPEED );
tr_sessionSetSpeedLimit( tr, TR_UP, limit );
}
@ -1058,13 +1028,13 @@ prefschanged( TrCore * core UNUSED,
struct cbdata * cbdata = data;
tr_session * tr = tr_core_session( cbdata->core );
if( !strcmp( key, PREF_KEY_ENCRYPTION ) )
if( !strcmp( key, TR_PREFS_KEY_ENCRYPTION ) )
{
const int encryption = pref_int_get( key );
g_message( "setting encryption to %d", encryption );
tr_sessionSetEncryption( tr, encryption );
}
else if( !strcmp( key, PREF_KEY_PORT ) )
else if( !strcmp( key, TR_PREFS_KEY_PEER_PORT ) )
{
const int port = pref_int_get( key );
tr_sessionSetPeerPort( tr, port );
@ -1080,22 +1050,22 @@ prefschanged( TrCore * core UNUSED,
cbdata->icon = NULL;
}
}
else if( !strcmp( key, PREF_KEY_DL_LIMIT_ENABLED ) )
else if( !strcmp( key, TR_PREFS_KEY_DSPEED_ENABLED ) )
{
const gboolean b = pref_flag_get( key );
tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, b );
}
else if( !strcmp( key, PREF_KEY_DL_LIMIT ) )
else if( !strcmp( key, TR_PREFS_KEY_DSPEED ) )
{
const int limit = pref_int_get( key );
tr_sessionSetSpeedLimit( tr, TR_DOWN, limit );
}
else if( !strcmp( key, PREF_KEY_UL_LIMIT_ENABLED ) )
else if( !strcmp( key, TR_PREFS_KEY_USPEED_ENABLED ) )
{
const gboolean b = pref_flag_get( key );
tr_sessionSetSpeedLimitEnabled( tr, TR_UP, b );
}
else if( !strcmp( key, PREF_KEY_UL_LIMIT ) )
else if( !strcmp( key, TR_PREFS_KEY_USPEED ) )
{
const int limit = pref_int_get( key );
tr_sessionSetSpeedLimit( tr, TR_UP, limit );
@ -1104,78 +1074,78 @@ prefschanged( TrCore * core UNUSED,
{
updateScheduledLimits( tr );
}
else if( !strcmp( key, PREF_KEY_PORT_FORWARDING ) )
else if( !strcmp( key, TR_PREFS_KEY_PORT_FORWARDING ) )
{
const gboolean enabled = pref_flag_get( key );
tr_sessionSetPortForwardingEnabled( tr, enabled );
}
else if( !strcmp( key, PREF_KEY_PEX ) )
else if( !strcmp( key, TR_PREFS_KEY_PEX_ENABLED ) )
{
const gboolean b = pref_flag_get( key );
tr_sessionSetPortForwardingEnabled( tr, b );
}
else if( !strcmp( key, PREF_KEY_RPC_ENABLED ) )
else if( !strcmp( key, TR_PREFS_KEY_RPC_ENABLED ) )
{
tr_sessionSetRPCEnabled( tr, pref_flag_get( key ) );
}
else if( !strcmp( key, PREF_KEY_RPC_PORT ) )
else if( !strcmp( key, TR_PREFS_KEY_RPC_PORT ) )
{
tr_sessionSetRPCPort( tr, pref_int_get( key ) );
}
else if( !strcmp( key, PREF_KEY_RPC_ENABLED ) )
else if( !strcmp( key, TR_PREFS_KEY_RPC_ENABLED ) )
{
tr_sessionSetRPCEnabled( tr, pref_flag_get( key ) );
}
else if( !strcmp( key, PREF_KEY_RPC_WHITELIST ) )
else if( !strcmp( key, TR_PREFS_KEY_RPC_WHITELIST ) )
{
const char * s = pref_string_get( key );
tr_sessionSetRPCWhitelist( tr, s );
}
else if( !strcmp( key, PREF_KEY_RPC_WHITELIST_ENABLED ) )
else if( !strcmp( key, TR_PREFS_KEY_RPC_WHITELIST_ENABLED ) )
{
tr_sessionSetRPCWhitelistEnabled( tr, pref_flag_get( key ) );
}
else if( !strcmp( key, PREF_KEY_RPC_USERNAME ) )
else if( !strcmp( key, TR_PREFS_KEY_RPC_USERNAME ) )
{
const char * s = pref_string_get( key );
tr_sessionSetRPCUsername( tr, s );
}
else if( !strcmp( key, PREF_KEY_RPC_PASSWORD ) )
else if( !strcmp( key, TR_PREFS_KEY_RPC_PASSWORD ) )
{
const char * s = pref_string_get( key );
tr_sessionSetRPCPassword( tr, s );
}
else if( !strcmp( key, PREF_KEY_RPC_AUTH_ENABLED ) )
else if( !strcmp( key, TR_PREFS_KEY_RPC_AUTH_REQUIRED ) )
{
const gboolean enabled = pref_flag_get( key );
tr_sessionSetRPCPasswordEnabled( tr, enabled );
}
else if( !strcmp( key, PREF_KEY_PROXY_SERVER ) )
else if( !strcmp( key, TR_PREFS_KEY_PROXY ) )
{
const char * s = pref_string_get( key );
tr_sessionSetProxy( tr, s );
}
else if( !strcmp( key, PREF_KEY_PROXY_TYPE ) )
else if( !strcmp( key, TR_PREFS_KEY_PROXY_TYPE ) )
{
const int i = pref_int_get( key );
tr_sessionSetProxyType( tr, i );
}
else if( !strcmp( key, PREF_KEY_PROXY_SERVER_ENABLED ) )
else if( !strcmp( key, TR_PREFS_KEY_PROXY_ENABLED ) )
{
const gboolean enabled = pref_flag_get( key );
tr_sessionSetProxyEnabled( tr, enabled );
}
else if( !strcmp( key, PREF_KEY_PROXY_AUTH_ENABLED ) )
else if( !strcmp( key, TR_PREFS_KEY_PROXY_AUTH_ENABLED ) )
{
const gboolean enabled = pref_flag_get( key );
tr_sessionSetProxyAuthEnabled( tr, enabled );
}
else if( !strcmp( key, PREF_KEY_PROXY_USERNAME ) )
else if( !strcmp( key, TR_PREFS_KEY_PROXY_USERNAME ) )
{
const char * s = pref_string_get( key );
tr_sessionSetProxyUsername( tr, s );
}
else if( !strcmp( key, PREF_KEY_PROXY_PASSWORD ) )
else if( !strcmp( key, TR_PREFS_KEY_RPC_PASSWORD ) )
{
const char * s = pref_string_get( key );
tr_sessionSetProxyPassword( tr, s );
@ -1237,9 +1207,8 @@ about( GtkWindow * parent )
"website", website_url,
"website-label", website_url,
"copyright",
_(
"Copyright 2005-2008 The Transmission Project" ),
"logo-icon-name", "transmission",
_( "Copyright 2005-2008 The Transmission Project" ),
"logo-icon-name", MY_NAME,
#ifdef SHOW_LICENSE
"license", LICENSE,
"wrap-license", TRUE,

View File

@ -68,7 +68,7 @@ level_combo_changed_cb( GtkWidget * w,
gtk_tree_model_get( m, &iter, 1, &level, -1 );
tr_setMessageLevel( level );
tr_core_set_pref_int( data->core, PREF_KEY_MSGLEVEL, level );
tr_core_set_pref_int( data->core, TR_PREFS_KEY_MSGLEVEL, level );
data->maxLevel = level;
gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( data->filter ) );
}
@ -405,7 +405,7 @@ debug_level_combo_new( void )
store = gtk_list_store_new ( 2, G_TYPE_STRING, G_TYPE_INT );
curlevel = pref_int_get( PREF_KEY_MSGLEVEL );
curlevel = pref_int_get( TR_PREFS_KEY_MSGLEVEL );
for( i = ii = 0; i < G_N_ELEMENTS( trLevels ); ++i )
{
GtkTreeIter iter;
@ -519,7 +519,7 @@ msgwin_new( TrCore * core )
gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( data->sort ),
COL_SEQUENCE,
GTK_SORT_ASCENDING );
data->maxLevel = pref_int_get( PREF_KEY_MSGLEVEL );
data->maxLevel = pref_int_get( TR_PREFS_KEY_MSGLEVEL );
gtk_tree_model_filter_set_visible_func( GTK_TREE_MODEL_FILTER( data->
filter ),
isRowVisible, data, NULL );

View File

@ -163,7 +163,6 @@ tr_core_dispose( GObject * obj )
{
GObjectClass * parent;
pref_save( );
core->priv = NULL;
parent = g_type_class_peek( g_type_parent( TR_CORE_TYPE ) );
@ -449,11 +448,11 @@ tr_core_apply_defaults( tr_ctor * ctor )
if( tr_ctorGetPeerLimit( ctor, TR_FORCE, NULL ) )
tr_ctorSetPeerLimit( ctor, TR_FORCE,
pref_int_get( PREF_KEY_MAX_PEERS_PER_TORRENT ) );
pref_int_get( TR_PREFS_KEY_PEER_LIMIT_TORRENT ) );
if( tr_ctorGetDownloadDir( ctor, TR_FORCE, NULL ) )
{
const char * path = pref_string_get( PREF_KEY_DOWNLOAD_DIR );
const char * path = pref_string_get( TR_PREFS_KEY_DOWNLOAD_DIR );
tr_ctorSetDownloadDir( ctor, TR_FORCE, path );
}
}
@ -584,7 +583,7 @@ prefsChanged( TrCore * core,
gboolean isReversed = pref_flag_get( PREF_KEY_SORT_REVERSED );
setSort( core, mode, isReversed );
}
else if( !strcmp( key, PREF_KEY_MAX_PEERS_GLOBAL ) )
else if( !strcmp( key, TR_PREFS_KEY_PEER_LIMIT_GLOBAL ) )
{
const uint16_t val = pref_int_get( key );
tr_sessionSetPeerLimit( tr_core_session( core ), val );
@ -684,10 +683,9 @@ tr_core_new( tr_session * session )
prefsChanged( core, PREF_KEY_SORT_MODE, NULL );
prefsChanged( core, PREF_KEY_SORT_REVERSED, NULL );
prefsChanged( core, PREF_KEY_DIR_WATCH_ENABLED, NULL );
prefsChanged( core, PREF_KEY_MAX_PEERS_GLOBAL, NULL );
prefsChanged( core, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, NULL );
prefsChanged( core, PREF_KEY_INHIBIT_HIBERNATION, NULL );
g_signal_connect( core, "prefs-changed", G_CALLBACK(
prefsChanged ), NULL );
g_signal_connect( core, "prefs-changed", G_CALLBACK( prefsChanged ), NULL );
return core;
}
@ -700,6 +698,7 @@ tr_core_close( TrCore * core )
if( session )
{
core->priv->session = NULL;
pref_save( session );
tr_sessionClose( session );
}
}
@ -819,7 +818,7 @@ tr_core_load( TrCore * self,
if( forcePaused )
tr_ctorSetPaused( ctor, TR_FORCE, TRUE );
tr_ctorSetPeerLimit( ctor, TR_FALLBACK,
pref_int_get( PREF_KEY_MAX_PEERS_PER_TORRENT ) );
pref_int_get( TR_PREFS_KEY_PEER_LIMIT_TORRENT ) );
torrents = tr_sessionLoadTorrents ( tr_core_session( self ), ctor, &count );
for( i = 0; i < count; ++i )
@ -1225,7 +1224,7 @@ static void
commitPrefsChange( TrCore * core,
const char * key )
{
pref_save( );
pref_save( tr_core_session( core ) );
g_signal_emit( core, TR_CORE_GET_CLASS( core )->prefsig, 0, key );
}

View File

@ -35,13 +35,7 @@
void
tr_prefs_init_global( void )
{
int i;
char pw[32];
const char * str;
const char * pool = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"1234567890";
GRand * rand;
cf_check_older_configs( );
@ -53,35 +47,22 @@ tr_prefs_init_global( void )
pref_flag_set_default ( PREF_KEY_DIR_WATCH_ENABLED, FALSE );
#endif
pref_int_set_default ( PREF_KEY_PEER_SOCKET_TOS,
TR_DEFAULT_PEER_SOCKET_TOS );
pref_flag_set_default ( PREF_KEY_INHIBIT_HIBERNATION, FALSE );
pref_flag_set_default ( PREF_KEY_BLOCKLIST_ENABLED, TRUE );
pref_flag_set_default ( PREF_KEY_BLOCKLIST_UPDATES_ENABLED, TRUE );
pref_string_set_default ( PREF_KEY_OPEN_DIALOG_FOLDER, g_get_home_dir( ) );
pref_int_set_default ( PREF_KEY_MAX_PEERS_GLOBAL,
TR_DEFAULT_GLOBAL_PEER_LIMIT );
pref_int_set_default ( PREF_KEY_MAX_PEERS_PER_TORRENT, 50 );
pref_flag_set_default ( PREF_KEY_TOOLBAR, TRUE );
pref_flag_set_default ( PREF_KEY_FILTERBAR, TRUE );
pref_flag_set_default ( PREF_KEY_STATUSBAR, TRUE );
pref_flag_set_default ( PREF_KEY_SHOW_TRAY_ICON, FALSE );
pref_string_set_default ( PREF_KEY_STATUSBAR_STATS, "total-ratio" );
pref_flag_set_default ( PREF_KEY_DL_LIMIT_ENABLED, FALSE );
pref_int_set_default ( PREF_KEY_DL_LIMIT, 100 );
pref_flag_set_default ( PREF_KEY_UL_LIMIT_ENABLED, FALSE );
pref_int_set_default ( PREF_KEY_UL_LIMIT, 50 );
pref_flag_set_default ( PREF_KEY_SCHED_LIMIT_ENABLED, FALSE );
pref_int_set_default ( PREF_KEY_SCHED_BEGIN, 60 * 23 ); /* 11pm */
pref_int_set_default ( PREF_KEY_SCHED_END, 60 * 7 ); /* 7am */
pref_int_set_default ( PREF_KEY_SCHED_DL_LIMIT, 200 ); /* 2x the other
limit */
pref_int_set_default ( PREF_KEY_SCHED_UL_LIMIT, 100 ); /* 2x the other
limit */
pref_int_set_default ( PREF_KEY_SCHED_DL_LIMIT, 200 ); /* 2x the other limit */
pref_int_set_default ( PREF_KEY_SCHED_UL_LIMIT, 100 ); /* 2x the other limit */
pref_flag_set_default ( PREF_KEY_OPTIONS_PROMPT, TRUE );
@ -90,33 +71,14 @@ tr_prefs_init_global( void )
pref_int_set_default ( PREF_KEY_MAIN_WINDOW_X, 50 );
pref_int_set_default ( PREF_KEY_MAIN_WINDOW_Y, 50 );
pref_string_set_default ( PREF_KEY_PROXY_SERVER, "" );
pref_int_set_default ( PREF_KEY_PROXY_PORT, TR_DEFAULT_PROXY_PORT );
pref_int_set_default ( PREF_KEY_PROXY_TYPE, TR_DEFAULT_PROXY_TYPE );
pref_flag_set_default ( PREF_KEY_PROXY_SERVER_ENABLED,
TR_DEFAULT_PROXY_ENABLED );
pref_flag_set_default ( PREF_KEY_PROXY_AUTH_ENABLED,
TR_DEFAULT_PROXY_AUTH_ENABLED );
pref_string_set_default ( PREF_KEY_PROXY_USERNAME, "" );
pref_string_set_default ( PREF_KEY_PROXY_PASSWORD, "" );
str = NULL;
#if GLIB_CHECK_VERSION( 2, 14, 0 )
if( !str ) str = g_get_user_special_dir( G_USER_DIRECTORY_DOWNLOAD );
#endif
if( !str ) str = g_get_home_dir( );
pref_string_set_default ( PREF_KEY_DOWNLOAD_DIR, str );
pref_string_set_default ( TR_PREFS_KEY_DOWNLOAD_DIR, str );
pref_int_set_default ( PREF_KEY_PORT, TR_DEFAULT_PORT );
pref_flag_set_default ( PREF_KEY_PORT_FORWARDING, TRUE );
pref_flag_set_default ( PREF_KEY_PEX, TR_DEFAULT_PEX_ENABLED );
pref_flag_set_default ( PREF_KEY_ASKQUIT, TRUE );
pref_flag_set_default ( PREF_KEY_ENCRYPTION, TR_DEFAULT_ENCRYPTION );
pref_flag_set_default ( PREF_KEY_LAZY_BITFIELD,
TR_DEFAULT_LAZY_BITFIELD_ENABLED );
pref_int_set_default ( PREF_KEY_MSGLEVEL, TR_MSG_INF );
pref_string_set_default ( PREF_KEY_SORT_MODE, "sort-by-name" );
pref_flag_set_default ( PREF_KEY_SORT_REVERSED, FALSE );
@ -124,24 +86,6 @@ tr_prefs_init_global( void )
pref_flag_set_default ( PREF_KEY_START, TRUE );
pref_flag_set_default ( PREF_KEY_TRASH_ORIGINAL, FALSE );
pref_flag_set_default ( PREF_KEY_RPC_ENABLED, TR_DEFAULT_RPC_ENABLED );
pref_int_set_default ( PREF_KEY_RPC_PORT, TR_DEFAULT_RPC_PORT );
pref_string_set_default ( PREF_KEY_RPC_WHITELIST, TR_DEFAULT_RPC_WHITELIST );
pref_flag_set_default ( PREF_KEY_RPC_WHITELIST_ENABLED,
TR_DEFAULT_RPC_WHITELIST_ENABLED );
rand = g_rand_new ( );
for( i = 0; i < 16; ++i )
pw[i] = pool[g_rand_int_range ( rand, 0, strlen( pool ) )];
g_rand_free ( rand );
pw[16] = '\0';
pref_string_set_default( PREF_KEY_RPC_USERNAME, "transmission" );
pref_string_set_default( PREF_KEY_RPC_PASSWORD, pw );
pref_flag_set_default ( PREF_KEY_RPC_AUTH_ENABLED, FALSE );
pref_save( );
}
/**
@ -375,7 +319,7 @@ torrentPage( GObject * core )
w = new_check_button( s, PREF_KEY_TRASH_ORIGINAL, core );
hig_workarea_add_wide_control( t, &row, w );
w = new_path_chooser_button( PREF_KEY_DOWNLOAD_DIR, core );
w = new_path_chooser_button( TR_PREFS_KEY_DOWNLOAD_DIR, core );
hig_workarea_add_row( t, &row, _( "_Destination folder:" ), w, NULL );
hig_workarea_finish( t, &row );
@ -510,7 +454,7 @@ onEncryptionToggled( GtkToggleButton * w,
? TR_ENCRYPTION_REQUIRED
: TR_ENCRYPTION_PREFERRED;
tr_core_set_pref_int( TR_CORE( core ), PREF_KEY_ENCRYPTION, val );
tr_core_set_pref_int( TR_CORE( core ), TR_PREFS_KEY_ENCRYPTION, val );
}
static GtkWidget*
@ -530,7 +474,7 @@ peerPage( GObject * core )
t = hig_workarea_create( );
hig_workarea_add_section_title( t, &row, _( "Blocklist" ) );
w = new_check_button( "", PREF_KEY_BLOCKLIST_ENABLED, core );
w = new_check_button( "", TR_PREFS_KEY_BLOCKLIST_ENABLED, core );
updateBlocklistText( w, TR_CORE( core ) );
h = gtk_hbox_new( FALSE, GUI_PAD_BIG );
gtk_box_pack_start( GTK_BOX( h ), w, TRUE, TRUE, 0 );
@ -553,11 +497,10 @@ peerPage( GObject * core )
hig_workarea_add_section_divider( t, &row );
hig_workarea_add_section_title( t, &row, _( "Limits" ) );
w = new_spin_button( PREF_KEY_MAX_PEERS_GLOBAL, core, 1, 3000, 5 );
w = new_spin_button( TR_PREFS_KEY_PEER_LIMIT_GLOBAL, core, 1, 3000, 5 );
hig_workarea_add_row( t, &row, _( "Maximum peers _overall:" ), w, NULL );
w = new_spin_button( PREF_KEY_MAX_PEERS_PER_TORRENT, core, 1, 300, 5 );
hig_workarea_add_row( t, &row, _(
"Maximum peers per _torrent:" ), w, NULL );
w = new_spin_button( TR_PREFS_KEY_PEER_LIMIT_TORRENT, core, 1, 300, 5 );
hig_workarea_add_row( t, &row, _( "Maximum peers per _torrent:" ), w, NULL );
hig_workarea_add_section_divider( t, &row );
hig_workarea_add_section_title ( t, &row, _( "Options" ) );
@ -565,14 +508,13 @@ peerPage( GObject * core )
s = _( "_Ignore unencrypted peers" );
w = gtk_check_button_new_with_mnemonic( s );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ),
pref_int_get(
PREF_KEY_ENCRYPTION ) ==
pref_int_get( TR_PREFS_KEY_ENCRYPTION ) ==
TR_ENCRYPTION_REQUIRED );
g_signal_connect( w, "toggled", G_CALLBACK( onEncryptionToggled ), core );
hig_workarea_add_wide_control( t, &row, w );
s = _( "Use peer e_xchange" );
w = new_check_button( s, PREF_KEY_PEX, core );
w = new_check_button( s, TR_PREFS_KEY_PEX_ENABLED, core );
hig_workarea_add_wide_control( t, &row, w );
hig_workarea_finish( t, &row );
@ -648,7 +590,7 @@ refreshWhitelist( struct remote_page * page )
g_string_truncate( gstr, gstr->len - 1 ); /* remove the trailing comma */
tr_core_set_pref( page->core, PREF_KEY_RPC_WHITELIST, gstr->str );
tr_core_set_pref( page->core, TR_PREFS_KEY_RPC_WHITELIST, gstr->str );
g_string_free( gstr, TRUE );
}
@ -757,7 +699,7 @@ static void
onLaunchClutchCB( GtkButton * w UNUSED,
gpointer data UNUSED )
{
int port = pref_int_get( PREF_KEY_RPC_PORT );
int port = pref_int_get( TR_PREFS_KEY_RPC_PORT );
char * url = g_strdup_printf( "http://localhost:%d/transmission/web",
port );
@ -784,7 +726,7 @@ webPage( GObject * core )
/* "enabled" checkbutton */
s = _( "_Enable web interface" );
w = new_check_button( s, PREF_KEY_RPC_ENABLED, core );
w = new_check_button( s, TR_PREFS_KEY_RPC_ENABLED, core );
page->rpc_tb = GTK_TOGGLE_BUTTON( w );
g_signal_connect( w, "clicked", G_CALLBACK( onRPCToggled ), page );
h = gtk_hbox_new( FALSE, GUI_PAD_BIG );
@ -796,14 +738,14 @@ webPage( GObject * core )
hig_workarea_add_wide_control( t, &row, h );
/* port */
w = new_spin_button( PREF_KEY_RPC_PORT, core, 0, 65535, 1 );
w = new_spin_button( TR_PREFS_KEY_RPC_PORT, core, 0, 65535, 1 );
page->widgets = g_slist_append( page->widgets, w );
w = hig_workarea_add_row( t, &row, _( "Listening _port:" ), w, NULL );
page->widgets = g_slist_append( page->widgets, w );
/* require authentication */
s = _( "_Require username" );
w = new_check_button( s, PREF_KEY_RPC_AUTH_ENABLED, core );
w = new_check_button( s, TR_PREFS_KEY_RPC_AUTH_REQUIRED, core );
hig_workarea_add_wide_control( t, &row, w );
page->auth_tb = GTK_TOGGLE_BUTTON( w );
page->widgets = g_slist_append( page->widgets, w );
@ -811,14 +753,14 @@ webPage( GObject * core )
/* username */
s = _( "_Username:" );
w = new_entry( PREF_KEY_RPC_USERNAME, core );
w = new_entry( TR_PREFS_KEY_RPC_USERNAME, core );
page->auth_widgets = g_slist_append( page->auth_widgets, w );
w = hig_workarea_add_row( t, &row, s, w, NULL );
page->auth_widgets = g_slist_append( page->auth_widgets, w );
/* password */
s = _( "Pass_word:" );
w = new_entry( PREF_KEY_RPC_PASSWORD, core );
w = new_entry( TR_PREFS_KEY_RPC_PASSWORD, core );
gtk_entry_set_visibility( GTK_ENTRY( w ), FALSE );
page->auth_widgets = g_slist_append( page->auth_widgets, w );
w = hig_workarea_add_row( t, &row, s, w, NULL );
@ -826,7 +768,7 @@ webPage( GObject * core )
/* require authentication */
s = _( "Only allow the following IP _addresses to connect:" );
w = new_check_button( s, PREF_KEY_RPC_WHITELIST_ENABLED, core );
w = new_check_button( s, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, core );
hig_workarea_add_wide_control( t, &row, w );
page->whitelist_tb = GTK_TOGGLE_BUTTON( w );
page->widgets = g_slist_append( page->widgets, w );
@ -834,7 +776,7 @@ webPage( GObject * core )
/* access control list */
{
const char * val = pref_string_get( PREF_KEY_RPC_WHITELIST );
const char * val = pref_string_get( TR_PREFS_KEY_RPC_WHITELIST );
GtkTreeModel * m = whitelist_tree_model_new( val );
GtkTreeViewColumn * c;
GtkCellRenderer * r;
@ -919,10 +861,8 @@ static void
refreshProxySensitivity( struct ProxyPage * p )
{
GSList * l;
const gboolean proxy_enabled = pref_flag_get(
PREF_KEY_PROXY_SERVER_ENABLED );
const gboolean proxy_auth_enabled = pref_flag_get(
PREF_KEY_PROXY_AUTH_ENABLED );
const gboolean proxy_enabled = pref_flag_get( TR_PREFS_KEY_PROXY_ENABLED );
const gboolean proxy_auth_enabled = pref_flag_get( TR_PREFS_KEY_PROXY_AUTH_ENABLED );
for( l = p->proxy_widgets; l != NULL; l = l->next )
gtk_widget_set_sensitive( GTK_WIDGET( l->data ), proxy_enabled );
@ -973,11 +913,9 @@ onProxyTypeChanged( GtkComboBox * w,
if( gtk_combo_box_get_active_iter( w, &iter ) )
{
struct ProxyPage * page = gpage;
int type = TR_PROXY_HTTP;
gtk_tree_model_get( gtk_combo_box_get_model(
w ), &iter, 1, &type, -1 );
tr_core_set_pref_int( TR_CORE(
page->core ), PREF_KEY_PROXY_TYPE, type );
int type = TR_PROXY_HTTP;
gtk_tree_model_get( gtk_combo_box_get_model( w ), &iter, 1, &type, -1 );
tr_core_set_pref_int( TR_CORE( page->core ), TR_PREFS_KEY_PROXY_TYPE, type );
}
}
@ -998,17 +936,17 @@ trackerPage( GObject * core )
hig_workarea_add_section_title ( t, &row, _( "Tracker Proxy" ) );
s = _( "Connect to tracker via a pro_xy" );
w = new_check_button( s, PREF_KEY_PROXY_SERVER_ENABLED, core );
w = new_check_button( s, TR_PREFS_KEY_PROXY_ENABLED, core );
g_signal_connect( w, "toggled", G_CALLBACK( onProxyToggled ), page );
hig_workarea_add_wide_control( t, &row, w );
s = _( "Proxy _server:" );
w = new_entry( PREF_KEY_PROXY_SERVER, core );
w = new_entry( TR_PREFS_KEY_PROXY, core );
page->proxy_widgets = g_slist_append( page->proxy_widgets, w );
w = hig_workarea_add_row( t, &row, s, w, NULL );
page->proxy_widgets = g_slist_append( page->proxy_widgets, w );
w = new_spin_button( PREF_KEY_PROXY_PORT, core, 0, 65535, 1 );
w = new_spin_button( TR_PREFS_KEY_PROXY_PORT, core, 0, 65535, 1 );
page->proxy_widgets = g_slist_append( page->proxy_widgets, w );
w = hig_workarea_add_row( t, &row, _( "Proxy _port:" ), w, NULL );
page->proxy_widgets = g_slist_append( page->proxy_widgets, w );
@ -1018,10 +956,8 @@ trackerPage( GObject * core )
w = gtk_combo_box_new_with_model( m );
r = gtk_cell_renderer_text_new( );
gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( w ), r, TRUE );
gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT(
w ), r, "text", 0, NULL );
gtk_combo_box_set_active( GTK_COMBO_BOX( w ),
pref_int_get( PREF_KEY_PROXY_TYPE ) );
gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( w ), r, "text", 0, NULL );
gtk_combo_box_set_active( GTK_COMBO_BOX( w ), pref_int_get( TR_PREFS_KEY_PROXY_TYPE ) );
g_signal_connect( w, "changed", G_CALLBACK( onProxyTypeChanged ), page );
g_object_unref( G_OBJECT( m ) );
page->proxy_widgets = g_slist_append( page->proxy_widgets, w );
@ -1029,19 +965,19 @@ trackerPage( GObject * core )
page->proxy_widgets = g_slist_append( page->proxy_widgets, w );
s = _( "_Authentication is required" );
w = new_check_button( s, PREF_KEY_PROXY_AUTH_ENABLED, core );
w = new_check_button( s, TR_PREFS_KEY_PROXY_AUTH_ENABLED, core );
g_signal_connect( w, "toggled", G_CALLBACK( onProxyToggled ), page );
hig_workarea_add_wide_control( t, &row, w );
page->proxy_widgets = g_slist_append( page->proxy_widgets, w );
s = _( "_Username:" );
w = new_entry( PREF_KEY_PROXY_USERNAME, core );
w = new_entry( TR_PREFS_KEY_PROXY_USERNAME, core );
page->proxy_auth_widgets = g_slist_append( page->proxy_auth_widgets, w );
w = hig_workarea_add_row( t, &row, s, w, NULL );
page->proxy_auth_widgets = g_slist_append( page->proxy_auth_widgets, w );
s = _( "Pass_word:" );
w = new_entry( PREF_KEY_PROXY_PASSWORD, core );
w = new_entry( TR_PREFS_KEY_RPC_PASSWORD, core );
gtk_entry_set_visibility( GTK_ENTRY( w ), FALSE );
page->proxy_auth_widgets = g_slist_append( page->proxy_auth_widgets, w );
w = hig_workarea_add_row( t, &row, s, w, NULL );
@ -1165,18 +1101,16 @@ bandwidthPage( GObject * core )
hig_workarea_add_section_title( t, &row, _( "Limits" ) );
s = _( "Limit _download speed (KB/s):" );
w = new_check_button( s, PREF_KEY_DL_LIMIT_ENABLED, core );
w2 = new_spin_button( PREF_KEY_DL_LIMIT, core, 0, INT_MAX, 5 );
gtk_widget_set_sensitive( GTK_WIDGET( w2 ),
pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED ) );
w = new_check_button( s, TR_PREFS_KEY_DSPEED_ENABLED, core );
w2 = new_spin_button( TR_PREFS_KEY_DSPEED, core, 0, INT_MAX, 5 );
gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_DSPEED_ENABLED ) );
g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 );
hig_workarea_add_row_w( t, &row, w, w2, NULL );
s = _( "Limit _upload speed (KB/s):" );
w = new_check_button( s, PREF_KEY_UL_LIMIT_ENABLED, core );
w2 = new_spin_button( PREF_KEY_UL_LIMIT, core, 0, INT_MAX, 5 );
gtk_widget_set_sensitive( GTK_WIDGET( w2 ),
pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED ) );
w = new_check_button( s, TR_PREFS_KEY_USPEED_ENABLED, core );
w2 = new_spin_button( TR_PREFS_KEY_USPEED, core, 0, INT_MAX, 5 );
gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_USPEED_ENABLED ) );
g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 );
hig_workarea_add_row_w( t, &row, w, w2, NULL );
@ -1201,15 +1135,12 @@ bandwidthPage( GObject * core )
w = new_spin_button( PREF_KEY_SCHED_DL_LIMIT, core, 0, INT_MAX, 5 );
page->sched_widgets = g_slist_append( page->sched_widgets, w );
l = hig_workarea_add_row( t, &row, _(
"Limit d_ownload speed (KB/s):" ), w,
NULL );
l = hig_workarea_add_row( t, &row, _( "Limit d_ownload speed (KB/s):" ), w, NULL );
page->sched_widgets = g_slist_append( page->sched_widgets, l );
w = new_spin_button( PREF_KEY_SCHED_UL_LIMIT, core, 0, INT_MAX, 5 );
page->sched_widgets = g_slist_append( page->sched_widgets, w );
l = hig_workarea_add_row( t, &row, _(
"Limit u_pload speed (KB/s):" ), w, NULL );
l = hig_workarea_add_row( t, &row, _( "Limit u_pload speed (KB/s):" ), w, NULL );
page->sched_widgets = g_slist_append( page->sched_widgets, l );
hig_workarea_finish( t, &row );
@ -1299,7 +1230,7 @@ onCorePrefsChanged( TrCore * core UNUSED,
const char * key,
gpointer gdata )
{
if( !strcmp( key, PREF_KEY_PORT ) )
if( !strcmp( key, TR_PREFS_KEY_PEER_PORT ) )
{
struct network_page_data * ndata = gdata;
struct test_port_data * data;
@ -1354,7 +1285,7 @@ networkPage( GObject * core )
hig_workarea_add_section_title( t, &row, _( "Incoming Peers" ) );
h = gtk_hbox_new( FALSE, GUI_PAD_BIG );
w2 = new_spin_button( PREF_KEY_PORT, core, 1, 65535, 1 );
w2 = new_spin_button( TR_PREFS_KEY_PEER_PORT, core, 1, 65535, 1 );
gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 );
data->label = l = gtk_label_new( NULL );
gtk_misc_set_alignment( GTK_MISC( l ), 0.0f, 0.5f );
@ -1364,13 +1295,12 @@ networkPage( GObject * core )
g_object_set_data( G_OBJECT( l ), "tr-port-spin", w2 );
g_object_set_data( G_OBJECT( l ), "session",
tr_core_session( TR_CORE( core ) ) );
data->id = g_signal_connect( TR_CORE(
core ), "prefs-changed",
data->id = g_signal_connect( TR_CORE( core ), "prefs-changed",
G_CALLBACK( onCorePrefsChanged ), data );
onCorePrefsChanged( NULL, PREF_KEY_PORT, data );
onCorePrefsChanged( NULL, TR_PREFS_KEY_PEER_PORT, data );
s = _( "Use UPnP or NAT-PMP port _forwarding from my router" );
w = new_check_button( s, PREF_KEY_PORT_FORWARDING, core );
w = new_check_button( s, TR_PREFS_KEY_PORT_FORWARDING, core );
hig_workarea_add_wide_control( t, &row, w );
hig_workarea_finish( t, &row );

View File

@ -21,17 +21,12 @@ GtkWidget * tr_prefs_dialog_new( GObject * core,
/* if you add a key here, you /must/ add its
* default in tr_prefs_init_global( void ) */
#define PREF_KEY_DL_LIMIT_ENABLED "download-limit-enabled"
#define PREF_KEY_DL_LIMIT "download-limit"
#define PREF_KEY_UL_LIMIT_ENABLED "upload-limit-enabled"
#define PREF_KEY_UL_LIMIT "upload-limit"
#define PREF_KEY_SCHED_LIMIT_ENABLED "sched-limit-enabled"
#define PREF_KEY_SCHED_BEGIN "sched-begin"
#define PREF_KEY_SCHED_END "sched-end"
#define PREF_KEY_SCHED_DL_LIMIT "sched-download-limit"
#define PREF_KEY_SCHED_UL_LIMIT "sched-upload-limit"
#define PREF_KEY_OPTIONS_PROMPT "show-options-window"
#define PREF_KEY_DOWNLOAD_DIR "download-dir"
#define PREF_KEY_OPEN_DIALOG_FOLDER "open-dialog-dir"
#define PREF_KEY_INHIBIT_HIBERNATION "inhibit-desktop-hibernation"
#define PREF_KEY_DIR_WATCH "watch-dir"
@ -39,14 +34,7 @@ GtkWidget * tr_prefs_dialog_new( GObject * core,
#define PREF_KEY_SHOW_TRAY_ICON "show-notification-area-icon"
#define PREF_KEY_START "start-added-torrents"
#define PREF_KEY_TRASH_ORIGINAL "trash-original-torrent-files"
#define PREF_KEY_PEER_SOCKET_TOS "peer-socket-tos"
#define PREF_KEY_PORT "peer-port"
#define PREF_KEY_PORT_FORWARDING "port-forwarding-enabled"
#define PREF_KEY_PEX "pex-enabled"
#define PREF_KEY_ASKQUIT "prompt-before-exit"
#define PREF_KEY_ENCRYPTION "encryption"
#define PREF_KEY_MSGLEVEL "debug-message-level"
#define PREF_KEY_LAZY_BITFIELD "lazy-bitfield-enabled"
#define PREF_KEY_SORT_MODE "sort-mode"
#define PREF_KEY_SORT_REVERSED "sort-reversed"
#define PREF_KEY_MINIMAL_VIEW "minimal-view"
@ -54,28 +42,11 @@ GtkWidget * tr_prefs_dialog_new( GObject * core,
#define PREF_KEY_STATUSBAR "show-statusbar"
#define PREF_KEY_STATUSBAR_STATS "statusbar-stats"
#define PREF_KEY_TOOLBAR "show-toolbar"
#define PREF_KEY_MAX_PEERS_GLOBAL "max-peers-global"
#define PREF_KEY_MAX_PEERS_PER_TORRENT "max-peers-per-torrent"
#define PREF_KEY_BLOCKLIST_ENABLED "blocklist-enabled"
#define PREF_KEY_BLOCKLIST_UPDATES_ENABLED "blocklist-updates-enabled"
#define PREF_KEY_MAIN_WINDOW_HEIGHT "main-window-height"
#define PREF_KEY_MAIN_WINDOW_WIDTH "main-window-width"
#define PREF_KEY_MAIN_WINDOW_X "main-window-x"
#define PREF_KEY_MAIN_WINDOW_Y "main-window-y"
#define PREF_KEY_RPC_PORT "rpc-port"
#define PREF_KEY_RPC_ENABLED "rpc-enabled"
#define PREF_KEY_RPC_WHITELIST "rpc-whitelist"
#define PREF_KEY_RPC_WHITELIST_ENABLED "rpc-whitelist-enabled"
#define PREF_KEY_RPC_AUTH_ENABLED "rpc-authentication-required"
#define PREF_KEY_RPC_PASSWORD "rpc-password"
#define PREF_KEY_RPC_USERNAME "rpc-username"
#define PREF_KEY_PROXY_SERVER "proxy-server"
#define PREF_KEY_PROXY_PORT "proxy-port"
#define PREF_KEY_PROXY_SERVER_ENABLED "proxy-server-enabled"
#define PREF_KEY_PROXY_TYPE "proxy-type"
#define PREF_KEY_PROXY_AUTH_ENABLED "proxy-authentication-required"
#define PREF_KEY_PROXY_USERNAME "proxy-username"
#define PREF_KEY_PROXY_PASSWORD "proxy-authentication"
void tr_prefs_init_global( void );

View File

@ -269,7 +269,6 @@ allocateBandwidth( tr_bandwidth * b,
}
/* notify the io buffers that there's more bandwidth available */
if( !b->band[dir].isLimited || ( b->band[dir].bytesLeft > 0 ) )
{
int i;
const int n = tr_ptrArraySize( b->iobufs );

View File

@ -420,8 +420,9 @@ tr_bencGetInt( const tr_benc * val,
{
const int success = tr_bencIsInt( val );
if( success )
if( success && setme )
*setme = val->val.i;
return success;
}
@ -444,6 +445,7 @@ tr_bencDictFindInt( tr_benc * dict, const char * key, int64_t * setme )
if( child )
found = tr_bencGetInt( child, setme );
return found;
}
@ -453,7 +455,7 @@ tr_bencDictFindDouble( tr_benc * dict, const char * key, double * setme )
const char * str;
const tr_bool success = tr_bencDictFindStr( dict, key, &str );
if( success )
if( success && setme )
*setme = strtod( str, NULL );
return success;
@ -467,7 +469,8 @@ tr_bencDictFindList( tr_benc * dict, const char * key, tr_benc ** setme )
if( child )
{
*setme = child;
if( setme != NULL )
*setme = child;
found = TRUE;
}
@ -482,7 +485,8 @@ tr_bencDictFindDict( tr_benc * dict, const char * key, tr_benc ** setme )
if( child )
{
*setme = child;
if( setme != NULL )
*setme = child;
found = TRUE;
}
@ -497,7 +501,8 @@ tr_bencDictFindStr( tr_benc * dict, const char * key, const char ** setme )
if( child )
{
*setme = child->val.s.s;
if( setme )
*setme = child->val.s.s;
found = TRUE;
}
@ -678,20 +683,48 @@ tr_bencDictAddInt( tr_benc * dict,
const char * key,
int64_t val )
{
tr_benc * child = tr_bencDictAdd( dict, key );
tr_benc * child;
/* see if it already exists, and if so, try to reuse it */
if(( child = tr_bencDictFind( dict, key ))) {
if( !tr_bencIsInt( child ) ) {
tr_bencDictRemove( dict, key );
child = NULL;
}
}
/* if it doesn't exist, create it */
if( child == NULL )
child = tr_bencDictAdd( dict, key );
/* set it */
tr_bencInitInt( child, val );
return child;
}
tr_benc*
tr_bencDictAddStr( tr_benc * dict,
const char * key,
const char * val )
tr_bencDictAddStr( tr_benc * dict, const char * key, const char * val )
{
tr_benc * child = tr_bencDictAdd( dict, key );
tr_benc * child;
/* see if it already exists, and if so, try to reuse it */
if(( child = tr_bencDictFind( dict, key ))) {
if( tr_bencIsString( child ) )
tr_free( child->val.s.s );
else {
tr_bencDictRemove( dict, key );
child = NULL;
}
}
/* if it doesn't exist, create it */
if( child == NULL )
child = tr_bencDictAdd( dict, key );
/* set it */
tr_bencInitStr( child, val, -1 );
return child;
}

View File

@ -182,6 +182,6 @@ int tr_bencParseStr( const uint8_t * buf,
***
**/
void tr_bencMergeDicts( tr_benc * b1, const tr_benc * b2 );
void tr_bencMergeDicts( tr_benc * target, const tr_benc * source );
#endif

View File

@ -408,10 +408,13 @@ tr_getResumeDir( const tr_handle * handle )
}
const char*
tr_getDefaultConfigDir( void )
tr_getDefaultConfigDir( const char * appname )
{
static char * s = NULL;
if( !appname || !*appname )
appname = "Transmission";
if( !s )
{
if( ( s = getenv( "TRANSMISSION_HOME" ) ) )
@ -421,17 +424,17 @@ tr_getDefaultConfigDir( void )
else
{
#ifdef SYS_DARWIN
s = tr_buildPath( getHomeDir( ), "Library",
"Application Support", "Transmission", NULL );
s = tr_buildPath( getHomeDir( ), "Library", "Application Support",
appname, NULL );
#elif defined( WIN32 )
char appdata[MAX_PATH]; /* SHGetFolderPath() requires MAX_PATH */
SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, appdata );
s = tr_buildPath( appdata, "Transmission", NULL );
s = tr_buildPath( appdata, appname, NULL );
#else
if( ( s = getenv( "XDG_CONFIG_HOME" ) ) )
s = tr_buildPath( s, "transmission", NULL );
s = tr_buildPath( s, appname, NULL );
else
s = tr_buildPath( getHomeDir( ), ".config", "transmission", NULL );
s = tr_buildPath( getHomeDir( ), ".config", appname, NULL );
#endif
}
}

View File

@ -696,9 +696,7 @@ tr_rpcInit( tr_handle * session,
s = tr_new0( tr_rpc_server, 1 );
s->session = session;
s->port = port;
s->whitelist = tr_strdup( whitelist && *whitelist
? whitelist
: TR_DEFAULT_RPC_WHITELIST );
s->whitelist = tr_strdup( whitelist && *whitelist ? whitelist : "127.0.0.1" );
s->username = tr_strdup( username );
s->password = tr_strdup( password );
s->isWhitelistEnabled = isWhitelistEnabled != 0;

View File

@ -22,6 +22,7 @@
#include "transmission.h"
#include "bandwidth.h"
#include "bencode.h"
#include "blocklist.h"
#include "fdlimit.h"
#include "list.h"
@ -39,8 +40,11 @@
#include "web.h"
#include "crypto.h"
#define PORT_RANDOM_MIN 1024
#define PORT_RANDOM_MAX 65535
static tr_port
getRandomPort( tr_session * s )
{
return tr_cryptoWeakRandInt( s->randomPortHigh - s->randomPortLow + 1) + s->randomPortLow;
}
/* Generate a peer id : "-TRxyzb-" + 12 random alphanumeric
characters, where x is the major version number, y is the
@ -197,43 +201,176 @@ loadBlocklists( tr_session * session )
****
***/
#ifdef TR_EMBEDDED
#define TR_DEFAULT_ENCRYPTION TR_CLEAR_PREFERRED
#else
#define TR_DEFAULT_ENCRYPTION TR_ENCRYPTION_PREFERRED
#endif
void
tr_sessionGetDefaultSettings( tr_benc * d )
{
assert( tr_bencIsDict( d ) );
tr_bencDictReserve( d, 30 );
tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, FALSE );
tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, tr_getDefaultDownloadDir( ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED, 100 );
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, 0 );
tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, TR_DEFAULT_ENCRYPTION );
tr_bencDictAddInt( d, TR_PREFS_KEY_LAZY_BITFIELD, TRUE );
tr_bencDictAddInt( d, TR_PREFS_KEY_MSGLEVEL, TR_MSG_INF );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, 240 );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT, 60 );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, atoi( TR_DEFAULT_PEER_PORT_STR ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED, FALSE );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW, 1024 );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH, 65535 );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_SOCKET_TOS, atoi( TR_DEFAULT_PEER_SOCKET_TOS_STR ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEX_ENABLED, TRUE );
tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, TRUE );
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY, "" );
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_AUTH_ENABLED, FALSE );
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_ENABLED, FALSE );
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_PASSWORD, "" );
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_PORT, 80 );
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_TYPE, TR_PROXY_HTTP );
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_USERNAME, "" );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_AUTH_REQUIRED, FALSE );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_ENABLED, TRUE );
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_PASSWORD, "" );
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_USERNAME, "" );
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST, TR_DEFAULT_RPC_WHITELIST );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, TRUE );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_PORT, atoi( TR_DEFAULT_RPC_PORT_STR ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, 100 );
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, 0 );
}
void
tr_sessionGetSettings( tr_session * s, struct tr_benc * d )
{
int i, n=0;
char * freeme[16];
assert( tr_bencIsDict( d ) );
tr_bencDictReserve( d, 30 );
tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, tr_blocklistIsEnabled( s ) );
tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, s->downloadDir );
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED, tr_sessionGetSpeedLimit( s, TR_DOWN ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, s->encryptionMode );
tr_bencDictAddInt( d, TR_PREFS_KEY_LAZY_BITFIELD, s->useLazyBitfield );
tr_bencDictAddInt( d, TR_PREFS_KEY_MSGLEVEL, tr_getMessageLevel( ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, tr_sessionGetPeerLimit( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT, s->peerLimitPerTorrent );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED, s->isPortRandom );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW, s->randomPortLow );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH, s->randomPortHigh );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_SOCKET_TOS, s->peerSocketTOS );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEX_ENABLED, s->isPexEnabled );
tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, tr_sessionIsPortForwardingEnabled( s ) );
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY, s->proxy );
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_AUTH_ENABLED, s->isProxyAuthEnabled );
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_ENABLED, s->isProxyEnabled );
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_PASSWORD, s->proxyPassword );
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_PORT, s->proxyPort );
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_TYPE, s->proxyType );
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_USERNAME, s->proxyUsername );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_AUTH_REQUIRED, tr_sessionIsRPCPasswordEnabled( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_ENABLED, tr_sessionIsRPCEnabled( s ) );
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_PASSWORD, freeme[n++] = tr_sessionGetRPCPassword( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_PORT, tr_sessionGetRPCPort( s ) );
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_USERNAME, freeme[n++] = tr_sessionGetRPCUsername( s ) );
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST, freeme[n++] = tr_sessionGetRPCWhitelist( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, tr_sessionGetRPCWhitelistEnabled( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, tr_sessionGetSpeedLimit( s, TR_UP ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );
for( i=0; i<n; ++i )
tr_free( freeme[i] );
}
void
tr_sessionLoadSettings( tr_benc * d, const char * configDir, const char * appName )
{
char * filename;
tr_benc fileSettings;
assert( tr_bencIsDict( d ) );
/* get the defaults */
tr_sessionGetDefaultSettings( d );
/* if caller didn't specify a config dir, use the default */
if( !configDir || !*configDir )
configDir = tr_getDefaultConfigDir( appName );
/* file settings override the defaults */
filename = tr_buildPath( configDir, "settings.json", NULL );
if( !tr_bencLoadJSONFile( filename, &fileSettings ) ) {
tr_bencMergeDicts( d, &fileSettings );
tr_bencFree( &fileSettings );
}
/* cleanup */
tr_free( filename );
}
void
tr_sessionSaveSettings( tr_session * session, const char * configDir, tr_benc * settings )
{
tr_benc fileSettings;
char * filename;
assert( tr_bencIsDict( settings ) );
filename = tr_buildPath( configDir, "settings.json", NULL );
tr_sessionGetSettings( session, settings );
if( tr_bencLoadJSONFile( filename, &fileSettings ) ) {
tr_bencSaveJSONFile( filename, settings );
} else {
tr_bencMergeDicts( &fileSettings, settings );
tr_bencSaveJSONFile( filename, &fileSettings );
tr_bencFree( &fileSettings );
}
tr_inf( "saved \"%s\"", filename );
tr_free( filename );
}
static void metainfoLookupRescan( tr_handle * h );
tr_handle *
tr_sessionInitFull( const char * configDir,
const char * tag,
const char * downloadDir,
int isPexEnabled,
int isPortForwardingEnabled,
int publicPort,
tr_encryption_mode encryptionMode,
int useLazyBitfield,
int useUploadLimit,
int uploadLimit,
int useDownloadLimit,
int downloadLimit,
int globalPeerLimit,
int messageLevel,
int isMessageQueueingEnabled,
int isBlocklistEnabled,
int peerSocketTOS,
int rpcIsEnabled,
tr_port rpcPort,
int rpcWhitelistIsEnabled,
const char * rpcWhitelist,
int rpcAuthIsEnabled,
const char * rpcUsername,
const char * rpcPassword,
int proxyIsEnabled,
const char * proxy,
int proxyPort,
tr_proxy_type proxyType,
int proxyAuthIsEnabled,
const char * proxyUsername,
const char * proxyPassword )
tr_session *
tr_sessionInit( const char * tag,
const char * configDir,
tr_bool messageQueuingEnabled,
tr_benc * clientSettings )
{
tr_handle * h;
char * filename;
int64_t i;
int64_t j;
tr_bool found;
const char * str;
tr_benc settings;
tr_session * session;
char * filename;
int64_t rpc_enabled, whitelist_enabled, rpc_auth_enabled, rpc_port;
const char * whitelist = NULL, *rpc_passwd = NULL, *rpc_username = NULL;
assert( tr_bencIsDict( clientSettings ) );
session = tr_new0( tr_session, 1 );
session->bandwidth = tr_bandwidthNew( session, NULL );
session->lock = tr_lockNew( );
session->tag = tr_strdup( tag );
tr_bencInitDict( &settings, 0 );
tr_sessionGetDefaultSettings( &settings );
tr_bencMergeDicts( &settings, clientSettings );
#ifndef WIN32
/* Don't exit when writing on a broken socket */
@ -241,115 +378,153 @@ tr_sessionInitFull( const char * configDir,
#endif
tr_msgInit( );
tr_setMessageLevel( messageLevel );
tr_setMessageQueuing( isMessageQueueingEnabled );
h = tr_new0( tr_handle, 1 );
h->lock = tr_lockNew( );
h->isPexEnabled = isPexEnabled ? 1 : 0;
h->encryptionMode = encryptionMode;
h->peerSocketTOS = peerSocketTOS;
h->downloadDir = tr_strdup( downloadDir );
h->isProxyEnabled = proxyIsEnabled ? 1 : 0;
h->proxy = tr_strdup( proxy );
h->proxyPort = proxyPort;
h->proxyType = proxyType;
h->isProxyAuthEnabled = proxyAuthIsEnabled != 0;
h->proxyUsername = tr_strdup( proxyUsername );
h->proxyPassword = tr_strdup( proxyPassword );
h->so_sndbuf = 1500 * 3; /* 3x MTU for most ethernet/wireless */
h->so_rcvbuf = 8192;
if( configDir == NULL )
configDir = tr_getDefaultConfigDir( );
tr_setConfigDir( h, configDir );
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_LIMIT_TORRENT, &i );
assert( found );
session->peerLimitPerTorrent = i;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_MSGLEVEL, &i );
assert( found );
tr_setMessageLevel( i );
tr_setMessageQueuing( messageQueuingEnabled );
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEX_ENABLED, &i );
assert( found );
session->isPexEnabled = i != 0;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ENCRYPTION, &i );
assert( found );
session->encryptionMode = i;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_SOCKET_TOS, &i );
assert( found );
session->peerSocketTOS = i;
found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_DOWNLOAD_DIR, &str );
assert( found );
session->downloadDir = tr_strdup( str );
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_ENABLED, &i );
assert( found );
session->isProxyEnabled = i != 0;
found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_PROXY, &str );
assert( found );
session->proxy = tr_strdup( str );
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_PORT, &i );
assert( found );
session->proxyPort = i;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_TYPE, &i );
assert( found );
session->proxyType = i;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_AUTH_ENABLED, &i );
assert( found );
session->isProxyAuthEnabled = i != 0;
found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_PROXY_USERNAME, &str );
assert( found );
session->proxyUsername = tr_strdup( str );
found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_PROXY_PASSWORD, &str );
assert( found );
session->proxyPassword = tr_strdup( str );
session->so_sndbuf = 1500 * 3; /* 3x MTU for most ethernet/wireless */
session->so_rcvbuf = 8192;
tr_setConfigDir( session, configDir );
tr_netInit( ); /* must go before tr_eventInit */
tr_eventInit( h );
while( !h->events )
tr_eventInit( session );
while( !session->events )
tr_wait( 50 );
h->tag = tr_strdup( tag );
h->peerMgr = tr_peerMgrNew( h );
session->peerMgr = tr_peerMgrNew( session );
h->useLazyBitfield = useLazyBitfield != 0;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_LAZY_BITFIELD, &i );
assert( found );
session->useLazyBitfield = i != 0;
/* Initialize rate and file descripts controls */
tr_fdInit( globalPeerLimit );
/* random port */
if ( publicPort == -1 )
publicPort = tr_cryptoWeakRandInt(PORT_RANDOM_MAX - PORT_RANDOM_MIN + 1) + PORT_RANDOM_MIN;
h->shared = tr_sharedInit( h, isPortForwardingEnabled, publicPort );
h->isPortSet = publicPort >= 0;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &i );
assert( found );
tr_fdInit( i );
h->bandwidth = tr_bandwidthNew( h, NULL );
tr_sessionSetSpeedLimit ( h, TR_UP, uploadLimit );
tr_sessionSetSpeedLimitEnabled( h, TR_UP, useUploadLimit );
tr_sessionSetSpeedLimit ( h, TR_DOWN, downloadLimit );
tr_sessionSetSpeedLimitEnabled( h, TR_DOWN, useDownloadLimit );
/**
*** random port
**/
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED, &i );
assert( found );
session->isPortRandom = i != 0;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW, &i );
assert( found );
session->randomPortLow = i;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH, &i );
assert( found );
session->randomPortHigh = i;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PORT_FORWARDING, &i )
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT, &j );
assert( found );
session->peerPort = session->isPortRandom ? getRandomPort( session ) : j;
session->shared = tr_sharedInit( session, i, session->peerPort );
session->isPortSet = session->isPortRandom || j>0;
session->bandwidth = tr_bandwidthNew( session, NULL );
/**
**/
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_USPEED, &i )
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_USPEED_ENABLED, &j );
assert( found );
tr_sessionSetSpeedLimit( session, TR_UP, i );
tr_sessionSetSpeedLimitEnabled( session, TR_UP, j );
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_DSPEED, &i )
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_DSPEED_ENABLED, &j );
assert( found );
tr_sessionSetSpeedLimit( session, TR_DOWN, i );
tr_sessionSetSpeedLimitEnabled( session, TR_DOWN, j );
/* first %s is the application name
second %s is the version number */
tr_inf( _( "%s %s started" ), TR_NAME, LONG_VERSION_STRING );
/* initialize the blocklist */
filename = tr_buildPath( h->configDir, "blocklists", NULL );
filename = tr_buildPath( session->configDir, "blocklists", NULL );
tr_mkdirp( filename, 0777 );
tr_free( filename );
h->isBlocklistEnabled = isBlocklistEnabled;
loadBlocklists( h );
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, &i );
assert( found );
session->isBlocklistEnabled = i;
loadBlocklists( session );
tr_statsInit( h );
tr_statsInit( session );
h->web = tr_webInit( h );
h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort,
rpcWhitelistIsEnabled, rpcWhitelist,
rpcAuthIsEnabled, rpcUsername, rpcPassword );
session->web = tr_webInit( session );
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_RPC_ENABLED, &rpc_enabled )
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_RPC_PORT, &rpc_port )
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, &whitelist_enabled )
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, &rpc_auth_enabled )
&& tr_bencDictFindStr( &settings, TR_PREFS_KEY_RPC_WHITELIST, &whitelist )
&& tr_bencDictFindStr( &settings, TR_PREFS_KEY_RPC_USERNAME, &rpc_username )
&& tr_bencDictFindStr( &settings, TR_PREFS_KEY_RPC_PASSWORD, &rpc_passwd );
assert( found );
session->rpcServer = tr_rpcInit( session, rpc_enabled, rpc_port, whitelist_enabled, whitelist,
rpc_auth_enabled, rpc_username, rpc_passwd );
metainfoLookupRescan( h );
metainfoLookupRescan( session );
return h;
}
tr_handle *
tr_sessionInit( const char * configDir,
const char * tag )
{
return tr_sessionInitFull( configDir,
TR_DEFAULT_DOWNLOAD_DIR,
tag,
TR_DEFAULT_PEX_ENABLED,
TR_DEFAULT_PORT_FORWARDING_ENABLED,
-1, /* public port */
TR_DEFAULT_ENCRYPTION, /* encryption mode */
TR_DEFAULT_LAZY_BITFIELD_ENABLED,
FALSE, /* use upload speed limit? */
-1, /* upload speed limit */
FALSE, /* use download speed limit? */
-1, /* download speed limit */
TR_DEFAULT_GLOBAL_PEER_LIMIT,
TR_MSG_INF, /* message level */
FALSE, /* is message queueing enabled? */
FALSE, /* is the blocklist enabled? */
TR_DEFAULT_PEER_SOCKET_TOS,
TR_DEFAULT_RPC_ENABLED,
TR_DEFAULT_RPC_PORT,
TR_DEFAULT_RPC_WHITELIST_ENABLED,
TR_DEFAULT_RPC_WHITELIST,
FALSE,
"fnord",
"potzrebie",
TR_DEFAULT_PROXY_ENABLED,
TR_DEFAULT_PROXY,
TR_DEFAULT_PROXY_PORT,
TR_DEFAULT_PROXY_TYPE,
TR_DEFAULT_PROXY_AUTH_ENABLED,
TR_DEFAULT_PROXY_USERNAME,
TR_DEFAULT_PROXY_PASSWORD );
return session;
}
/***
@ -420,30 +595,39 @@ tr_setBindPortImpl( void * vdata )
tr_free( data );
}
void
tr_sessionSetPeerPort( tr_session * session,
tr_port port )
static void
setPortImpl( tr_session * session, tr_port port )
{
struct bind_port_data * data = tr_new( struct bind_port_data, 1 );
data->session = session;
data->port = port;
tr_runInEventThread( session, tr_setBindPortImpl, data );
}
tr_port
tr_sessionSetPeerPortRandom( tr_session * session )
void
tr_sessionSetPeerPort( tr_session * session,
tr_port port )
{
const tr_port port = tr_cryptoWeakRandInt(PORT_RANDOM_MAX - PORT_RANDOM_MIN + 1) + PORT_RANDOM_MIN;
tr_sessionSetPeerPort( session, port);
return port;
session->isPortRandom = FALSE;
session->peerPort = port;
setPortImpl( session, session->peerPort );
}
tr_port
tr_sessionGetPeerPort( const tr_handle * h )
tr_sessionSetPeerPortRandom( tr_session * session )
{
assert( h );
return tr_sharedGetPeerPort( h->shared );
session->isPortRandom = TRUE;
session->peerPort = getRandomPort( session );
setPortImpl( session, session->peerPort );
return session->peerPort;
}
tr_port
tr_sessionGetPeerPort( const tr_session * session )
{
assert( session );
return session->peerPort;
}
tr_port_forwarding
@ -522,7 +706,7 @@ tr_sessionSetPeerLimit( tr_handle * handle UNUSED,
}
uint16_t
tr_sessionGetPeerLimit( const tr_handle * handle UNUSED )
tr_sessionGetPeerLimit( const tr_session * session UNUSED )
{
return tr_fdGetPeerLimit( );
}
@ -1056,7 +1240,7 @@ tr_sessionSetRPCWhitelistEnabled( tr_session * session,
tr_rpcSetWhitelistEnabled( session->rpcServer, isEnabled );
}
int
tr_bool
tr_sessionGetRPCWhitelistEnabled( const tr_session * session )
{
return tr_rpcGetWhitelistEnabled( session->rpcServer );
@ -1096,7 +1280,7 @@ tr_sessionSetRPCPasswordEnabled( tr_session * session,
tr_rpcSetPasswordEnabled( session->rpcServer, isEnabled );
}
int
tr_bool
tr_sessionIsRPCPasswordEnabled( const tr_session * session )
{
return tr_rpcIsPasswordEnabled( session->rpcServer );
@ -1106,7 +1290,7 @@ tr_sessionIsRPCPasswordEnabled( const tr_session * session )
****
***/
int
tr_bool
tr_sessionIsProxyEnabled( const tr_session * session )
{
return session->isProxyEnabled;
@ -1138,7 +1322,7 @@ tr_sessionGetProxy( const tr_session * session )
return session->proxy;
}
int
tr_port
tr_sessionGetProxyPort( const tr_session * session )
{
return session->proxyPort;
@ -1162,7 +1346,7 @@ tr_sessionSetProxyPort( tr_session * session,
session->proxyPort = port;
}
int
tr_bool
tr_sessionIsProxyAuthEnabled( const tr_session * session )
{
return session->isProxyAuthEnabled;

View File

@ -58,6 +58,7 @@ struct tr_bandwidth;
struct tr_handle
{
tr_bool isPortSet;
tr_bool isPortRandom;
tr_bool isPexEnabled;
tr_bool isBlocklistEnabled;
tr_bool isProxyEnabled;
@ -72,6 +73,12 @@ struct tr_handle
struct tr_event_handle * events;
uint16_t peerLimitPerTorrent;
tr_port peerPort;
tr_port randomPortLow;
tr_port randomPortHigh;
int proxyPort;
int peerSocketTOS;
@ -79,7 +86,6 @@ struct tr_handle
tr_torrent * torrentList;
char * tag;
char * configDir;
char * downloadDir;
char * resumeDir;

View File

@ -18,8 +18,6 @@
#include "torrent.h" /* tr_ctorGetSave() */
#include "utils.h"
#define DEFAULT_MAX_CONNECTED_PEERS 50
struct optional_args
{
tr_bool isSet_paused;
@ -35,7 +33,7 @@ struct optional_args
* @ingroup tr_ctor */
struct tr_ctor
{
const tr_handle * handle;
const tr_session * session;
tr_bool saveInOurTorrentsDir;
tr_bool doDelete;
@ -139,7 +137,7 @@ tr_ctorSetMetainfoFromHash( tr_ctor * ctor,
int err;
const char * filename;
filename = tr_sessionFindTorrentFile( ctor->handle, hashString );
filename = tr_sessionFindTorrentFile( ctor->session, hashString );
if( !filename )
err = EINVAL;
else
@ -298,14 +296,14 @@ tr_ctorGetMetainfo( const tr_ctor * ctor,
***/
tr_ctor*
tr_ctorNew( const tr_handle * handle )
tr_ctorNew( const tr_session * session )
{
tr_ctor * ctor = tr_new0( struct tr_ctor, 1 );
ctor->handle = handle;
tr_ctorSetPeerLimit( ctor, TR_FALLBACK, DEFAULT_MAX_CONNECTED_PEERS );
ctor->session = session;
tr_ctorSetPeerLimit( ctor, TR_FALLBACK, session->peerLimitPerTorrent );
tr_ctorSetPaused( ctor, TR_FALLBACK, FALSE );
tr_ctorSetDownloadDir( ctor, TR_FALLBACK, handle->downloadDir );
tr_ctorSetDownloadDir( ctor, TR_FALLBACK, session->downloadDir );
tr_ctorSetSave( ctor, TRUE );
return ctor;
}

View File

@ -533,8 +533,7 @@ torrentRealInit( tr_handle * h,
tr_peerMgrAddTorrent( h->peerMgr, tor );
if( !h->isPortSet )
tr_sessionSetPeerPort( h, TR_DEFAULT_PORT );
assert( h->isPortSet );
assert( !tor->downloadedCur );
assert( !tor->uploadedCur );

View File

@ -64,12 +64,12 @@ typedef uint8_t tr_bool;
*
* The default configuration directory is determined this way:
* 1. If the TRANSMISSION_HOME environmental variable is set, its value is used.
* 2. On Darwin, "${HOME}/Library/Application Support/Transmission" is used.
* 3. On Windows, "${CSIDL_APPDATA}/Transmission" is used.
* 4. If XDG_CONFIG_HOME is set, "${XDG_CONFIG_HOME}/transmission" is used.
* 5. ${HOME}/.config/transmission" is used as a last resort.
* 2. On Darwin, "${HOME}/Library/Application Support/${appname}" is used.
* 3. On Windows, "${CSIDL_APPDATA}/${appname}" is used.
* 4. If XDG_CONFIG_HOME is set, "${XDG_CONFIG_HOME}/${appname}" is used.
* 5. ${HOME}/.config/${appname}" is used as a last resort.
*/
const char* tr_getDefaultConfigDir( void );
const char* tr_getDefaultConfigDir( const char * appname );
/**
* @brief returns Transmisson's default download directory.
@ -91,7 +91,7 @@ typedef tr_handle tr_session;
/**
* @addtogroup tr_session Session
*
* A libtransmission session is created by calling either tr_sessionInitFull()
* A libtransmission session is created by calling either tr_sessionInit()
* or tr_sessionInit(). libtransmission creates a thread for itself so that
* it can operate independently of the caller's event loop. The session will
* continue until tr_sessionClose() is called.
@ -107,59 +107,6 @@ typedef enum
}
tr_proxy_type;
/** @see tr_sessionInitFull */
#define TR_DEFAULT_CONFIG_DIR tr_getDefaultConfigDir( )
/** @see tr_sessionInitFull */
#define TR_DEFAULT_DOWNLOAD_DIR tr_getDefaultDownloadDir( )
/** @see tr_sessionInitFull */
#ifdef TR_EMBEDDED
#define TR_DEFAULT_ENCRYPTION TR_CLEAR_PREFERRED
#else
#define TR_DEFAULT_ENCRYPTION TR_ENCRYPTION_PREFERRED
#endif
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PEX_ENABLED 1
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PORT_FORWARDING_ENABLED 0
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PORT 51413
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PORT_STR "51413"
/** @see tr_sessionInitFull */
#define TR_DEFAULT_LAZY_BITFIELD_ENABLED 1
/** @see tr_sessionInitFull */
#define TR_DEFAULT_GLOBAL_PEER_LIMIT 200
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PEER_SOCKET_TOS 8
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PEER_SOCKET_TOS_STR "8"
/** @see tr_sessionInitFull */
#define TR_DEFAULT_BLOCKLIST_ENABLED 0
/** @see tr_sessionInitFull */
#define TR_DEFAULT_RPC_ENABLED 0
/** @see tr_sessionInitFull */
#define TR_DEFAULT_RPC_PORT 9091
/** @see tr_sessionInitFull */
#define TR_DEFAULT_RPC_PORT_STR "9091"
/** @see tr_sessionInitFull */
#define TR_DEFAULT_RPC_WHITELIST "127.0.0.1"
/** @see tr_sessionInitFull */
#define TR_DEFAULT_RPC_WHITELIST_ENABLED 0
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PROXY_ENABLED 0
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PROXY NULL
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PROXY_PORT 80
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PROXY_TYPE TR_PROXY_HTTP
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PROXY_AUTH_ENABLED 0
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PROXY_USERNAME NULL
/** @see tr_sessionInitFull */
#define TR_DEFAULT_PROXY_PASSWORD NULL
typedef enum
{
TR_CLEAR_PREFERRED,
@ -168,143 +115,144 @@ typedef enum
}
tr_encryption_mode;
#define TR_DEFAULT_RPC_WHITELIST "127.0.0.1"
#define TR_DEFAULT_RPC_PORT_STR "9091"
#define TR_DEFAULT_PEER_PORT_STR "51413"
#define TR_DEFAULT_PEER_SOCKET_TOS_STR "8"
#define TR_PREFS_KEY_BLOCKLIST_ENABLED "blocklist-enabled"
#define TR_PREFS_KEY_DOWNLOAD_DIR "download-dir"
#define TR_PREFS_KEY_DSPEED "download-limit"
#define TR_PREFS_KEY_DSPEED_ENABLED "download-limit-enabled"
#define TR_PREFS_KEY_ENCRYPTION "encryption"
#define TR_PREFS_KEY_LAZY_BITFIELD "lazy-bitfield-enabled"
#define TR_PREFS_KEY_MSGLEVEL "message-level"
#define TR_PREFS_KEY_MSGQUEUE_ENABLED "message-queue-enabled"
#define TR_PREFS_KEY_PEER_LIMIT_GLOBAL "peer-limit-global"
#define TR_PREFS_KEY_PEER_LIMIT_TORRENT "peer-limit-per-torrent"
#define TR_PREFS_KEY_PEER_PORT "peer-port"
#define TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED "peer-port-random-enabled"
#define TR_PREFS_KEY_PEER_PORT_RANDOM_LOW "peer-port-random-low"
#define TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH "peer-port-random-high"
#define TR_PREFS_KEY_PEER_SOCKET_TOS "peer-socket-tos"
#define TR_PREFS_KEY_PEX_ENABLED "pex-enabled"
#define TR_PREFS_KEY_PORT_FORWARDING "port-forwarding-enabled"
#define TR_PREFS_KEY_PROXY_AUTH_ENABLED "proxy-auth-enabled"
#define TR_PREFS_KEY_PROXY_ENABLED "proxy-enabled"
#define TR_PREFS_KEY_PROXY_PASSWORD "proxy-auth-password"
#define TR_PREFS_KEY_PROXY_PORT "proxy-port"
#define TR_PREFS_KEY_PROXY "proxy"
#define TR_PREFS_KEY_PROXY_TYPE "proxy-type"
#define TR_PREFS_KEY_PROXY_USERNAME "proxy-auth-username"
#define TR_PREFS_KEY_RPC_AUTH_REQUIRED "rpc-authentication-required"
#define TR_PREFS_KEY_RPC_ENABLED "rpc-enabled"
#define TR_PREFS_KEY_RPC_PASSWORD "rpc-password"
#define TR_PREFS_KEY_RPC_PORT "rpc-port"
#define TR_PREFS_KEY_RPC_USERNAME "rpc-username"
#define TR_PREFS_KEY_RPC_WHITELIST_ENABLED "rpc-whitelist-enabled"
#define TR_PREFS_KEY_RPC_WHITELIST "rpc-whitelist"
#define TR_PREFS_KEY_USPEED_ENABLED "upload-limit-enabled"
#define TR_PREFS_KEY_USPEED "upload-limit"
struct tr_benc;
/**
* @brief Start a libtransmission session.
* @return an opaque handle to the new session
* Add libtransmission's default settings to the benc dictionary.
*
* @param configDir
* The config directory where libtransmission config subdirectories
* will be found, such as "torrents", "resume", and "blocklists".
* #TR_DEFAULT_CONFIG_DIR can be used as a default.
* Example:
* @code
* tr_benc settings;
* int64_t i;
*
* @param downloadDir
* The default directory to save added torrents.
* This can be changed per-session with
* tr_sessionSetDownloadDir() and per-torrent with
* tr_ctorSetDownloadDir().
* tr_bencInitDict( &settings, 0 );
* tr_sessionGetDefaultSettings( &settings );
* if( tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT, &i ) )
* fprintf( stderr, "the default peer port is %d\n", (int)i );
* tr_bencFree( &settings );
* @endcode
*
* @param tag
* Obsolete. Only used now for locating legacy fastresume files.
* This will be removed at some point in the future.
* Valid tags: beos cli daemon gtk macos wx
*
* @param isPexEnabled
* whether or not PEX is allowed for non-private torrents.
* This can be changed per-session with
* tr_sessionSetPexEnabled().
* #TR_DEFAULT_PEX_ENABLED is the default.
*
* @param isPortForwardingEnabled
* If true, libtransmission will attempt
* to find a local UPnP-enabled or NATPMP-enabled
* router and forward a port from there to the local
* machine. This is so remote peers can initiate
* connections with us.
* #TR_DEFAULT_PORT_FORWARDING_ENABLED is the default.
*
* @param publicPort
* Port number to open for incoming peer connections.
* -1 for random port.
* #TR_DEFAULT_PORT is the default.
*
* @param encryptionMode
* Must be one of #TR_CLEAR_PREFERRED,
* #TR_ENCRYPTION_PREFERRED, or #TR_ENCRYPTION_REQUIRED.
*
* @param isUploadLimitEnabled
* If true, libtransmission will limit the entire
* session's upload speed from "uploadLimit".
*
* @param uploadLimit
* The speed limit to use for the entire session when
* "isUploadLimitEnabled" is true. Units are KiB/s.
*
* @param isDownloadLimitEnabled
* If true, libtransmission will limit the entire
* session's download speed from "downloadLimit".
*
* @param downloadLimit
* The speed limit to use for the entire session when
* "isDownloadLimitEnabled" is true. Units are KiB/s.
*
* @param peerLimit
* The maximum number of peer connections allowed in a session.
* #TR_DEFAULT_GLOBAL_PEER_LIMIT can be used as a default.
*
* @param messageLevel
* Verbosity level of libtransmission's logging mechanism.
* Must be one of #TR_MSG_ERR, #TR_MSG_INF, #TR_MSG_DBG.
*
* @param isMessageQueueingEnabled
* If true, then messages will build up in a queue until
* processed by the client application.
*
* @param isBlocklistEnabled
* If true, then Transmission will not allow peer connections
* to the IP addressess specified in the blocklist.
*
* @param peerSocketTOS
*
* @param rpcIsEnabled
* If true, then libtransmission will open an http server port
* to listen for incoming RPC requests.
*
* @param rpcPort
* The port on which to listen for incoming RPC requests
*
* @param rpcWhitelist
* The list of IP addresses allowed to make RPC connections.
* @see tr_sessionSetRPCWhitelist()
*
* @see TR_DEFAULT_PEER_SOCKET_TOS
* @see TR_DEFAULT_BLOCKLIST_ENABLED
* @see TR_DEFAULT_RPC_ENABLED
* @see TR_DEFAULT_RPC_PORT
* @see TR_DEFAULT_RPC_WHITELIST
* @see TR_DEFAULT_RPC_WHITELIST_ENABLED
* @see tr_sessionClose()
* @param initme pointer to a tr_benc dictionary
* @see tr_sessionLoadSettings()
* @see tr_sessionInit()
* @see tr_getDefaultConfigDir()
*/
tr_session * tr_sessionInitFull( const char * configDir,
const char * tag,
const char * downloadDir,
int isPexEnabled,
int isPortForwardingEnabled,
int publicPort,
tr_encryption_mode encryptionMode,
int useLazyBitfield,
int useUploadLimit,
int uploadLimit,
int useDownloadLimit,
int downloadLimit,
int peerLimit,
int messageLevel,
int isMessageQueueingEnabled,
int isBlocklistEnabled,
int peerSocketTOS,
int rpcIsEnabled,
tr_port rpcPort,
int rpcWhitelistIsEnabled,
const char * rpcWhitelist,
int rpcPasswordIsEnabled,
const char * rpcUsername,
const char * rpcPassword,
int proxyIsEnabled,
const char * proxy,
int proxyPort,
tr_proxy_type proxyType,
int proxyAuthIsEnabled,
const char * proxyUsername,
const char * proxyPassword );
void tr_sessionGetDefaultSettings( struct tr_benc * dictionary );
/**
* Add the session's configuration settings to the benc dictionary.
*
* FIXME: this probably belongs in libtransmissionapp
*
* @param session
* @param dictionary
* @see tr_sessionGetDefaultSettings()
*/
void tr_sessionGetSettings( tr_session *, struct tr_benc * dictionary );
/** @brief Shorter form of tr_sessionInitFull()
@deprecated Use tr_sessionInitFull() instead. */
tr_session * tr_sessionInit( const char * configDir,
const char * tag );
/**
* Load settings from the configuration directory's settings.json file,
* using libtransmission's default settings as fallbacks for missing keys.
*
* FIXME: this belongs in libtransmissionapp
*
* @param configDir the configuration directory to find settings.json
* @param initme pointer to an uninitialized tr_benc
* @param appName examples: Transmission, transmission-daemon
* @see tr_sessionGetDefaultSettings()
* @see tr_sessionInit()
* @see tr_sessionSaveSettings()
*/
void tr_sessionLoadSettings( struct tr_benc * dictionary,
const char * configDir,
const char * appName );
/**
* Add the session's configuration settings to the benc dictionary
* and save it to the configuration directory's settings.json file.
*
* FIXME: this belongs in libtransmissionapp
*
* @param session
* @param dictionary
* @see tr_sessionLoadSettings()
*/
void tr_sessionSaveSettings( tr_session * session,
const char * configDir,
struct tr_benc * dictonary );
/**
* Initialize a libtransmission session.
*
* For example, this will instantiate a session with all the default values:
* @code
* tr_benc settings;
* tr_session * session;
* const char * configDir;
*
* tr_bencInitDict( &settings, 0 );
* tr_sessionGetDefaultSettings( &settings );
* configDir = tr_getDefaultConfigDir( "Transmission" );
* session = tr_sessionInit( "mac", configDir, true, &settings );
*
* tr_bencFree( &settings );
* @encode
*
* @param tag "gtk", "mac", "daemon", etc... this is only for pre-1.30 resume files
* @param configDir where Transmission will look for resume files, blocklists, etc.
* @param messageQueueingEnabled if false, messages will be dumped to stderr
* @param settings libtransmission settings
* @see tr_sessionGetDefaultSettings()
* @see tr_sessionLoadSettings()
* @see tr_getDefaultConfigDir()
*/
tr_session * tr_sessionInit( const char * tag,
const char * configDir,
tr_bool messageQueueingEnabled,
struct tr_benc * settings );
/** @brief End a libtransmission session
@see tr_sessionInitFull() */
void tr_sessionClose( tr_session * );
@see tr_sessionInit() */
void tr_sessionClose( tr_session * );
/**
* @brief Return the session's configuration directory
@ -316,7 +264,7 @@ const char * tr_sessionGetConfigDir( const tr_session * );
/**
* @brief Set the per-session default download folder for new torrents.
* @see tr_sessionInitFull()
* @see tr_sessionInit()
* @see tr_sessionGetDownloadDir()
* @see tr_ctorSetDownloadDir()
*/
@ -326,7 +274,7 @@ void tr_sessionSetDownloadDir( tr_session * session,
/**
* @brief Get the default download folder for new torrents.
*
* This is set by tr_sessionInitFull() or tr_sessionSetDownloadDir(),
* This is set by tr_sessionInit() or tr_sessionSetDownloadDir(),
* and can be overridden on a per-torrent basis by tr_ctorSetDownloadDir().
*/
const char * tr_sessionGetDownloadDir( const tr_session * session );
@ -337,25 +285,25 @@ const char * tr_sessionGetDownloadDir( const tr_session * session );
* @details If true, libtransmission will open a server socket to listen
* for incoming http RPC requests as described in docs/rpc-spec.txt.
*
* This is intially set by tr_sessionInitFull() and can be
* This is intially set by tr_sessionInit() and can be
* queried by tr_sessionIsRPCEnabled().
*/
void tr_sessionSetRPCEnabled( tr_session * session,
int isEnabled );
/** @brief Get whether or not RPC calls are allowed in this session.
@see tr_sessionInitFull()
@see tr_sessionInit()
@see tr_sessionSetRPCEnabled() */
int tr_sessionIsRPCEnabled( const tr_session * session );
/** @brief Specify which port to listen for RPC requests on.
@see tr_sessionInitFull()
@see tr_sessionInit()
@see tr_sessionGetRPCPort */
void tr_sessionSetRPCPort( tr_session * session,
tr_port port );
/** @brief Get which port to listen for RPC requests on.
@see tr_sessionInitFull()
@see tr_sessionInit()
@see tr_sessionSetRPCPort */
tr_port tr_sessionGetRPCPort( const tr_session * session );
@ -372,14 +320,14 @@ void tr_sessionSetRPCWhitelist( tr_session * session,
/** @brief get the Access Control List for allowing/denying RPC requests.
@return a comma-separated string of whitelist domains. tr_free() when done.
@see tr_sessionInitFull
@see tr_sessionInit
@see tr_sessionSetRPCWhitelist */
char* tr_sessionGetRPCWhitelist( const tr_session * );
void tr_sessionSetRPCWhitelistEnabled( tr_session * session,
int isEnabled );
int tr_sessionGetRPCWhitelistEnabled( const tr_session * session );
tr_bool tr_sessionGetRPCWhitelistEnabled( const tr_session * session );
void tr_sessionSetRPCPassword( tr_session * session,
const char * password );
@ -389,7 +337,7 @@ void tr_sessionSetRPCUsername( tr_session * session,
/** @brief get the password used to restrict RPC requests.
@return the password string. tr_free() when done.
@see tr_sessionInitFull()
@see tr_sessionInit()
@see tr_sessionSetRPCPassword() */
char* tr_sessionGetRPCPassword( const tr_session * session );
@ -398,7 +346,7 @@ char* tr_sessionGetRPCUsername( const tr_session * session );
void tr_sessionSetRPCPasswordEnabled( tr_session * session,
int isEnabled );
int tr_sessionIsRPCPasswordEnabled( const tr_session * session );
tr_bool tr_sessionIsRPCPasswordEnabled( const tr_session * session );
typedef enum
@ -447,13 +395,13 @@ void tr_sessionSetRPCCallback( tr_session * session,
***
**/
int tr_sessionIsProxyEnabled( const tr_session * );
tr_bool tr_sessionIsProxyEnabled( const tr_session * );
int tr_sessionIsProxyAuthEnabled( const tr_session * );
tr_bool tr_sessionIsProxyAuthEnabled( const tr_session * );
const char* tr_sessionGetProxy( const tr_session * );
int tr_sessionGetProxyPort( const tr_session * );
tr_port tr_sessionGetProxyPort( const tr_session * );
tr_proxy_type tr_sessionGetProxyType( const tr_session * );
@ -649,9 +597,9 @@ typedef struct tr_msg_list
}
tr_msg_list;
void tr_setMessageQueuing( int isEnabled );
void tr_setMessageQueuing( tr_bool isEnabled );
int tr_getMessageQueuing( void );
tr_bool tr_getMessageQueuing( void );
tr_msg_list * tr_getQueuedMessages( void );
@ -756,7 +704,7 @@ void tr_ctorSetPeerLimit( tr_ctor * ctor,
/** Set the download folder for the torrent being added with this ctor.
@see tr_ctorSetDownloadDir()
@see tr_sessionInitFull() */
@see tr_sessionInit() */
void tr_ctorSetDownloadDir( tr_ctor * ctor,
tr_ctorMode mode,
const char * directory );

View File

@ -49,7 +49,7 @@
static tr_lock * messageLock = NULL;
static int messageLevel = 0;
static int messageQueuing = FALSE;
static tr_bool messageQueuing = FALSE;
static tr_msg_list * messageQueue = NULL;
static tr_msg_list ** messageQueueTail = &messageQueue;
@ -118,7 +118,7 @@ tr_getMessageLevel( void )
}
void
tr_setMessageQueuing( int enabled )
tr_setMessageQueuing( tr_bool enabled )
{
tr_msgInit( );
tr_lockLock( messageLock );
@ -126,7 +126,7 @@ tr_setMessageQueuing( int enabled )
tr_lockUnlock( messageLock );
}
int
tr_bool
tr_getMessageQueuing( void )
{
int ret;