Esempio n. 1
0
static tr_benc*
get_node (struct jsonsl_st * jsn)
{
  tr_benc * parent;
  tr_benc * node = NULL;
  struct json_wrapper_data * data = jsn->data;

  parent = tr_ptrArrayEmpty (&data->stack)
         ? NULL
         : tr_ptrArrayBack (&data->stack);

  if (!parent)
    {
      node = data->top;
    }
  else if (tr_bencIsList (parent))
    {
      node = tr_bencListAdd (parent);
    }
  else if (tr_bencIsDict (parent) && (data->key!=NULL))
    {
      node = tr_bencDictAdd (parent, data->key);
      tr_free (data->key);
      data->key = NULL;
    }

  return node;
}
Esempio n. 2
0
tr_session *
tr_sessionInit( const char  * tag,
                const char  * configDir,
                tr_bool       messageQueuingEnabled,
                tr_benc     * clientSettings )
{
    tr_session * session;
    struct init_data data;

    assert( tr_bencIsDict( clientSettings ) );

    /* initialize the bare skeleton of the session object */
    session = tr_new0( tr_session, 1 );
    session->bandwidth = tr_bandwidthNew( session, NULL );
    session->lock = tr_lockNew( );
    session->tag = tr_strdup( tag );
    session->magicNumber = SESSION_MAGIC_NUMBER;

    /* start the libtransmission thread */
    tr_netInit( ); /* must go before tr_eventInit */
    tr_eventInit( session );
    assert( session->events != NULL );

    /* run the rest in the libtransmission thread */
    session->isWaiting = TRUE;
    data.session = session;
    data.configDir = configDir;
    data.messageQueuingEnabled = messageQueuingEnabled;
    data.clientSettings = clientSettings;
    tr_runInEventThread( session, tr_sessionInitImpl, &data );
    while( session->isWaiting )
        tr_wait( 100 );

    return session;
}
Esempio n. 3
0
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 );
}
Esempio n. 4
0
static const char*
parseFiles (tr_info * inf, tr_benc * files, const tr_benc * length)
{
  int64_t len;

  inf->totalSize = 0;

  if (tr_bencIsList (files)) /* multi-file mode */
    {
      tr_file_index_t i;
      struct evbuffer * buf = evbuffer_new ();

      inf->isMultifile = 1;
      inf->fileCount = tr_bencListSize (files);
      inf->files = tr_new0 (tr_file, inf->fileCount);

      for (i=0; i<inf->fileCount; i++)
        {
          tr_benc * file;
          tr_benc * path;

          file = tr_bencListChild (files, i);
          if (!tr_bencIsDict (file))
            return "files";

          if (!tr_bencDictFindList (file, "path.utf-8", &path))
            if (!tr_bencDictFindList (file, "path", &path))
              return "path";

          if (!getfile (&inf->files[i].name, inf->name, path, buf))
            return "path";

          if (!tr_bencDictFindInt (file, "length", &len))
            return "length";

          inf->files[i].length = len;
          inf->totalSize      += len;
        }

      evbuffer_free (buf);
    }
  else if (tr_bencGetInt (length, &len)) /* single-file mode */
    {
      if (path_is_suspicious (inf->name))
        return "path";

      inf->isMultifile      = 0;
      inf->fileCount        = 1;
      inf->files            = tr_new0 (tr_file, 1);
      inf->files[0].name    = tr_strdup (inf->name);
      inf->files[0].length  = len;
      inf->totalSize       += len;
    }
  else
    {
      return "length";
    }

  return NULL;
}
Esempio n. 5
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_OPEN_FILE_LIMIT,          s->openFileLimit );
    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_bencDictAddInt( d, TR_PREFS_KEY_PREALLOCATION,            s->preallocationMode );
    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_bencDictAddDouble( d, TR_PREFS_KEY_RATIO,                 s->desiredRatio );
    tr_bencDictAddInt( d, TR_PREFS_KEY_RATIO_ENABLED,            s->isRatioLimited );
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_AUTH_REQUIRED,        tr_sessionIsRPCPasswordEnabled( s ) );
    tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_ENABLED,              tr_sessionIsRPCEnabled( 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 ) );
    tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, s->uploadSlotsPerTorrent );

    for( i=0; i<n; ++i )
        tr_free( freeme[i] );
}
Esempio n. 6
0
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_OPEN_FILE_LIMIT,          atoi( TR_DEFAULT_OPEN_FILE_LIMIT_STR ) );
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL,        atoi( TR_DEFAULT_PEER_LIMIT_GLOBAL_STR ) );
    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT,       atoi( TR_DEFAULT_PEER_LIMIT_TORRENT_STR ) );
    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_bencDictAddInt( d, TR_PREFS_KEY_PREALLOCATION,            TR_PREALLOCATE_SPARSE );
    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_bencDictAddDouble( d, TR_PREFS_KEY_RATIO,                 2.0 );
    tr_bencDictAddInt( d, TR_PREFS_KEY_RATIO_ENABLED,            FALSE );
    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 );
    tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, 14 );
}
Esempio n. 7
0
static int
testParse2( void )
{
    tr_benc top;
    tr_benc top2;
    int64_t intVal;
    const char * strVal;
    double realVal;
    bool boolVal;
    int len;
    char * benc;
    const uint8_t * end;

    tr_bencInitDict( &top, 0 );
    tr_bencDictAddBool( &top, "this-is-a-bool", true );
    tr_bencDictAddInt( &top, "this-is-an-int", 1234 );
    tr_bencDictAddReal( &top, "this-is-a-real", 0.5 );
    tr_bencDictAddStr( &top, "this-is-a-string", "this-is-a-string" );

    benc = tr_bencToStr( &top, TR_FMT_BENC, &len );
    check_streq( "d14:this-is-a-booli1e14:this-is-a-real8:0.50000016:this-is-a-string16:this-is-a-string14:this-is-an-inti1234ee", benc );
    check( !tr_bencParse( benc, benc+len, &top2, &end ) );
    check( (char*)end == benc + len );
    check( tr_bencIsDict( &top2 ) );
    check( tr_bencDictFindInt( &top, "this-is-an-int", &intVal ) );
    check_int_eq (1234, intVal);
    check( tr_bencDictFindBool( &top, "this-is-a-bool", &boolVal ) );
    check( boolVal == true );
    check( tr_bencDictFindStr( &top, "this-is-a-string", &strVal ) );
    check_streq ("this-is-a-string", strVal);
    check( tr_bencDictFindReal( &top, "this-is-a-real", &realVal ) );
    check_int_eq (50, (int)(realVal*100));

    tr_bencFree( &top2 );
    tr_free( benc );
    tr_bencFree( &top );

    return 0;
}
Esempio n. 8
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 );
}
Esempio n. 9
0
static tr_benc*
getNode( struct json_benc_data * data )
{
    tr_benc * parent;
    tr_benc * node = NULL;

    if( tr_ptrArrayEmpty( data->stack ) )
        parent = NULL;
    else
        parent = tr_ptrArrayBack( data->stack );

    if( !parent )
        node = data->top;
    else if( tr_bencIsList( parent ) )
        node = tr_bencListAdd( parent );
    else if( tr_bencIsDict( parent ) && data->key )
    {
        node = tr_bencDictAdd( parent, data->key );
        tr_free( data->key );
        data->key = NULL;
    }

    return node;
}
Esempio n. 10
0
static void
on_announce_done( tr_session   * session,
                  bool           did_connect,
                  bool           did_timeout,
                  long           response_code,
                  const void   * msg,
                  size_t         msglen,
                  void         * vdata )
{
    tr_announce_response * response;
    struct announce_data * data = vdata;

    response = &data->response;
    response->did_connect = did_connect;
    response->did_timeout = did_timeout;
    dbgmsg( data->log_name, "Got announce response" );

    if( response_code != HTTP_OK )
    {
        const char * fmt = _( "Tracker gave HTTP response code %1$ld (%2$s)" );
        const char * response_str = tr_webGetResponseStr( response_code );
        response->errmsg = tr_strdup_printf( fmt, response_code, response_str );
    }
    else
    {
        tr_benc benc;
        const int benc_loaded = !tr_bencLoad( msg, msglen, &benc, NULL );

        if( getenv( "TR_CURL_VERBOSE" ) != NULL )
        {
            struct evbuffer * buf = tr_bencToBuf( &benc, TR_FMT_JSON );
            fprintf( stderr, "Announce response:\n< %s\n", evbuffer_pullup( buf, -1 ) );
            tr_free( buf );
        }

        if( benc_loaded && tr_bencIsDict( &benc ) )
        {
            int64_t i;
            size_t rawlen;
            tr_benc * tmp;
            const char * str;
            const uint8_t * raw;

            if( tr_bencDictFindStr( &benc, "failure reason", &str ) )
                response->errmsg = tr_strdup( str );

            if( tr_bencDictFindStr( &benc, "warning message", &str ) )
                response->warning = tr_strdup( str );

            if( tr_bencDictFindInt( &benc, "interval", &i ) )
                response->interval = i;

            if( tr_bencDictFindInt( &benc, "min interval", &i ) )
                response->min_interval = i;

            if( tr_bencDictFindStr( &benc, "tracker id", &str ) )
                response->tracker_id_str = tr_strdup( str );

            if( tr_bencDictFindInt( &benc, "complete", &i ) )
                response->seeders = i;

            if( tr_bencDictFindInt( &benc, "incomplete", &i ) )
                response->leechers = i;

            if( tr_bencDictFindInt( &benc, "downloaded", &i ) )
                response->downloads = i;

            if( tr_bencDictFindRaw( &benc, "peers6", &raw, &rawlen ) ) {
                dbgmsg( data->log_name, "got a peers6 length of %zu", rawlen );
                response->pex6 = tr_peerMgrCompact6ToPex( raw, rawlen,
                                              NULL, 0, &response->pex6_count );
            }

            if( tr_bencDictFindRaw( &benc, "peers", &raw, &rawlen ) ) {
                dbgmsg( data->log_name, "got a compact peers length of %zu", rawlen );
                response->pex = tr_peerMgrCompactToPex( raw, rawlen,
                                               NULL, 0, &response->pex_count );
            } else if( tr_bencDictFindList( &benc, "peers", &tmp ) ) {
                response->pex = listToPex( tmp, &response->pex_count );
                dbgmsg( data->log_name, "got a peers list with %zu entries",
                        response->pex_count );
            }
        }

        if( benc_loaded )
            tr_bencFree( &benc );
    }

    tr_runInEventThread( session, on_announce_done_eventthread, data );
}
Esempio n. 11
0
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 );
}