void tr_sessionLoadSettings( tr_benc * d, const char * configDir, const char * appName ) { char * filename; tr_benc fileSettings; tr_benc sessionDefaults; tr_benc tmp; assert( tr_bencIsDict( d ) ); /* initializing the defaults: caller may have passed in some app-level defaults. * preserve those and use the session defaults to fill in any missing gaps. */ tr_bencInitDict( &sessionDefaults, 0 ); tr_sessionGetDefaultSettings( &sessionDefaults ); tr_bencMergeDicts( &sessionDefaults, d ); tmp = *d; *d = sessionDefaults; sessionDefaults = tmp; /* 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_bencFree( &sessionDefaults ); tr_free( filename ); }
static int testMerge( void ) { tr_benc dest, src; int64_t i; const char * s; /* initial dictionary (default values) */ tr_bencInitDict( &dest, 10 ); tr_bencDictAddInt( &dest, "i1", 1 ); tr_bencDictAddInt( &dest, "i2", 2 ); tr_bencDictAddInt( &dest, "i4", -35 ); /* remains untouched */ tr_bencDictAddStr( &dest, "s5", "abc" ); tr_bencDictAddStr( &dest, "s6", "def" ); tr_bencDictAddStr( &dest, "s7", "127.0.0.1" ); /* remains untouched */ /* new dictionary, will overwrite items in dest */ tr_bencInitDict( &src, 10 ); tr_bencDictAddInt( &src, "i1", 1 ); /* same value */ tr_bencDictAddInt( &src, "i2", 4 ); /* new value */ tr_bencDictAddInt( &src, "i3", 3 ); /* new key:value */ tr_bencDictAddStr( &src, "s5", "abc" ); /* same value */ tr_bencDictAddStr( &src, "s6", "xyz" ); /* new value */ tr_bencDictAddStr( &src, "s8", "ghi" ); /* new key:value */ tr_bencMergeDicts( &dest, /*const*/ &src ); check( tr_bencDictFindInt( &dest, "i1", &i )); check_int_eq (1, i); check( tr_bencDictFindInt( &dest, "i2", &i )); check_int_eq (4, i); check( tr_bencDictFindInt( &dest, "i3", &i )); check_int_eq (3, i); check( tr_bencDictFindInt( &dest, "i4", &i )); check_int_eq (-35, i); check( tr_bencDictFindStr( &dest, "s5", &s )); check_streq ("abc", s); check( tr_bencDictFindStr( &dest, "s6", &s )); check_streq ("xyz", s); check( tr_bencDictFindStr( &dest, "s7", &s )); check_streq ("127.0.0.1", s); check( tr_bencDictFindStr( &dest, "s8", &s )); check_streq ("ghi", s); tr_bencFree( &dest ); tr_bencFree( &src ); return 0; }
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 tr_sessionInitImpl( void * vdata ) { int64_t i; int64_t j; double d; tr_bool found; const char * str; tr_benc settings; char * filename; struct init_data * data = vdata; tr_benc * clientSettings = data->clientSettings; tr_session * session = data->session; assert( tr_amInEventThread( session ) ); assert( tr_bencIsDict( clientSettings ) ); dbgmsg( "tr_sessionInit: the session's top-level bandwidth object is %p", session->bandwidth ); tr_bencInitDict( &settings, 0 ); tr_sessionGetDefaultSettings( &settings ); tr_bencMergeDicts( &settings, clientSettings ); #ifndef WIN32 /* Don't exit when writing on a broken socket */ signal( SIGPIPE, SIG_IGN ); #endif 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( data->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 ); assert( tr_isEncryptionMode( i ) ); session->encryptionMode = i; found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PREALLOCATION, &i ); assert( found ); assert( tr_isPreallocationMode( i ) ); session->preallocationMode = 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, data->configDir ); tr_trackerSessionInit( session ); assert( session->tracker != NULL ); session->peerMgr = tr_peerMgrNew( session ); found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_LAZY_BITFIELD, &i ); assert( found ); session->useLazyBitfield = i != 0; /* Initialize rate and file descripts controls */ found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_OPEN_FILE_LIMIT, &i ); assert( found ); session->openFileLimit = i; found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &j ); assert( found ); tr_fdInit( session->openFileLimit, j ); /** *** 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; /** **/ found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, &i ); assert( found ); session->uploadSlotsPerTorrent = i; 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 ); found = tr_bencDictFindDouble( &settings, TR_PREFS_KEY_RATIO, &d ) && tr_bencDictFindInt( &settings, TR_PREFS_KEY_RATIO_ENABLED, &j ); assert( found ); tr_sessionSetRatioLimit( session, d ); tr_sessionSetRatioLimited( session, j ); /* initialize the blocklist */ filename = tr_buildPath( session->configDir, "blocklists", NULL ); tr_mkdirp( filename, 0777 ); tr_free( filename ); found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, &i ); assert( found ); session->isBlocklistEnabled = i; loadBlocklists( session ); session->rpcServer = tr_rpcInit( session, &settings ); tr_bencFree( &settings ); assert( tr_isSession( session ) ); /* first %s is the application name second %s is the version number */ tr_inf( _( "%s %s started" ), TR_NAME, LONG_VERSION_STRING ); tr_statsInit( session ); session->web = tr_webInit( session ); metainfoLookupRescan( session ); session->isWaiting = FALSE; dbgmsg( "returning session %p; session->tracker is %p", session, session->tracker ); }