Changeset 6146


Ignore:
Timestamp:
Jun 11, 2008, 8:09:36 PM (15 years ago)
Author:
charles
Message:

#966: allow blocklist support in the daemon. add extra info in the man page explaining how to add blocklists.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/daemon/daemon.c

    r6120 r6146  
    3434static char myConfigFilename[MAX_PATH_LENGTH];
    3535
     36#define KEY_BLOCKLIST        "blocklist-enabled"
     37#define KEY_DOWNLOAD_DIR     "download-dir"
     38#define KEY_ENCRYPTION       "encryption"
     39#define KEY_PEER_LIMIT       "peer-limit"
     40#define KEY_PEER_PORT        "peer-port"
     41#define KEY_PORT_FORWARDING  "port-forwarding-enabled"
     42#define KEY_PEX_ENABLED      "pex-enabled"
     43#define KEY_AUTH_REQUIRED    "rpc-auth-required"
     44#define KEY_USERNAME         "rpc-username"
     45#define KEY_PASSWORD         "rpc-password"
     46#define KEY_ACL              "rpc-acl"
     47#define KEY_RPC_PORT         "rpc-port"
     48#define KEY_DSPEED           "speed-limit-down"
     49#define KEY_DSPEED_ENABLED   "speed-limit-down-enabled"
     50#define KEY_USPEED           "speed-limit-up"
     51#define KEY_USPEED_ENABLED   "speed-limit-up-enabled"
     52
     53#define CONFIG_FILE          "session.json"
     54
     55const char * encryption_str[3] = { "tolerated", "preferred", "required" };
     56
    3657static void
    37 saveState( tr_handle * h )
     58saveState( tr_session * s )
    3859{
    3960    tr_benc d;
    40     const char * str;
    41     char * username = tr_sessionGetRPCUsername( h );
    42     char * password = tr_sessionGetRPCPassword( h );
    43     char * auth = tr_strdup_printf( "%s:%s", username, password );
    44 
    45     tr_bencInitDict( &d, 14 );
    46     tr_bencDictAddStr( &d, "download-dir", tr_sessionGetDownloadDir( h ) );
    47     tr_bencDictAddInt( &d, "peer-limit", tr_sessionGetPeerLimit( h ) );
    48     tr_bencDictAddInt( &d, "pex-allowed", tr_sessionIsPexEnabled( h ) );
    49     tr_bencDictAddInt( &d, "port", tr_sessionGetPeerPort( h ) );
    50     tr_bencDictAddStr( &d, "auth", auth );
    51     tr_bencDictAddInt( &d, "auth-required",
    52                            tr_sessionIsRPCPasswordEnabled( h ) );
    53     tr_bencDictAddInt( &d, "port-forwarding-enabled",
    54                            tr_sessionIsPortForwardingEnabled( h ) );
    55     tr_bencDictAddStr( &d, "rpc-acl", tr_sessionGetRPCACL( h ) );
    56     tr_bencDictAddInt( &d, "rpc-port", tr_sessionGetRPCPort( h ) );
    57     tr_bencDictAddInt( &d, "speed-limit-down",
    58                            tr_sessionGetSpeedLimit( h, TR_DOWN ) );
    59     tr_bencDictAddInt( &d, "speed-limit-down-enabled",
    60                            tr_sessionIsSpeedLimitEnabled( h, TR_DOWN ) );
    61     tr_bencDictAddInt( &d, "speed-limit-up",
    62                            tr_sessionGetSpeedLimit( h, TR_UP ) );
    63     tr_bencDictAddInt( &d, "speed-limit-up-enabled",
    64                            tr_sessionIsSpeedLimitEnabled( h, TR_UP ) );
    65     switch( tr_sessionGetEncryption( h ) ) {
    66         case TR_PLAINTEXT_PREFERRED: str = "tolerated"; break;
    67         case TR_ENCRYPTION_REQUIRED: str = "required"; break;
    68         default: str = "preferred"; break;
    69     }
    70     tr_bencDictAddStr( &d, "encryption", str );
    71 
    72     tr_ninf( MY_NAME, "saving \"%s\"", myConfigFilename );
    73     tr_bencSaveFile( myConfigFilename, &d );
    74 
     61fprintf( stderr, "tr_sessionGetDownloadDir(s) returned [%s]\n", tr_sessionGetDownloadDir(s));
     62    tr_bencInitDict( &d, 16 );
     63    tr_bencDictAddInt( &d, KEY_BLOCKLIST,        tr_blocklistIsEnabled( s ) );
     64    tr_bencDictAddStr( &d, KEY_DOWNLOAD_DIR,     tr_sessionGetDownloadDir( s ) );
     65    tr_bencDictAddInt( &d, KEY_PEER_LIMIT,       tr_sessionGetPeerLimit( s ) );
     66    tr_bencDictAddInt( &d, KEY_PEER_PORT,        tr_sessionGetPeerPort( s ) );
     67    tr_bencDictAddInt( &d, KEY_PORT_FORWARDING,  tr_sessionIsPortForwardingEnabled( s ) );
     68    tr_bencDictAddInt( &d, KEY_PEX_ENABLED,      tr_sessionIsPexEnabled( s ) );
     69    tr_bencDictAddStr( &d, KEY_USERNAME,         tr_sessionGetRPCUsername( s ) );
     70    tr_bencDictAddStr( &d, KEY_PASSWORD,         tr_sessionGetRPCPassword( s ) );
     71    tr_bencDictAddStr( &d, KEY_ACL,              tr_sessionGetRPCACL( s ) );
     72    tr_bencDictAddInt( &d, KEY_RPC_PORT,         tr_sessionGetRPCPort( s ) );
     73    tr_bencDictAddInt( &d, KEY_AUTH_REQUIRED,    tr_sessionIsRPCPasswordEnabled( s ) );
     74    tr_bencDictAddInt( &d, KEY_DSPEED,           tr_sessionGetSpeedLimit( s, TR_DOWN ) );
     75    tr_bencDictAddInt( &d, KEY_DSPEED_ENABLED,   tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) );
     76    tr_bencDictAddInt( &d, KEY_USPEED,           tr_sessionGetSpeedLimit( s, TR_UP ) );
     77    tr_bencDictAddInt( &d, KEY_USPEED_ENABLED,   tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );
     78    tr_bencDictAddStr( &d, KEY_ENCRYPTION,       encryption_str[tr_sessionGetEncryption( s )] );
     79    tr_bencSaveJSONFile( myConfigFilename, &d );
     80fprintf( stderr, "saved:\n%s\n", tr_bencSaveAsJSON(&d,NULL) );
    7581    tr_bencFree( &d );
    76     tr_free( auth );
    77     tr_free( password );
    78     tr_free( username );
    79 }
    80 
    81 static int
    82 parseAuth( const char * auth, char ** username, char ** password )
    83 {
    84     int err = 0;
    85     const char * pch = strchr( auth, ':' );
    86     if( !pch )
    87         err = -1;
    88     else {
    89         *username = tr_strndup( auth, pch-auth );
    90         *password = tr_strdup( pch+1 );
    91     }
    92     return err;
    93 }
    94 
     82    tr_ninf( MY_NAME, "saved \"%s\"", myConfigFilename );
     83}
     84
     85/**
     86 * @param port      port number, or -1 if not set in the command line
     87 * @param auth      TRUE, FALSE, or -1 if not set on the command line
     88 * @param blocklist TRUE, FALSE, or -1 if not set on the command line
     89 */
    9590static void
    96 session_init( const char * configDir, int rpc_port,
    97               const char * acl, const char * auth, int noauth )
    98 {
     91session_init( const char * configDir, const char * downloadDir,
     92              int rpcPort, const char * acl,
     93              int authRequired, const char * username, const char * password,
     94              int blocklistEnabled )
     95{
     96    char mycwd[MAX_PATH_LENGTH];
    9997    tr_benc state;
    10098    int have_state;
     99    int64_t i;
    101100    int64_t peer_port = TR_DEFAULT_PORT;
    102101    int64_t peers = TR_DEFAULT_GLOBAL_PEER_LIMIT;
     
    108107    int64_t down_limited = FALSE;
    109108    int encryption = TR_ENCRYPTION_PREFERRED;
    110     char downloadDir[MAX_PATH_LENGTH] = { '\0' };
    111     const char * acl_fallback = TR_DEFAULT_RPC_ACL;
    112     int64_t rpc_port_fallback = TR_DEFAULT_RPC_PORT;
    113     int64_t auth_required_fallback = 0;
    114     const char * auth_fallback = NULL;
    115109    tr_ctor * ctor;
    116110    tr_torrent ** torrents;
    117     int auth_required;
    118     char * user = NULL;
    119     char * pass = NULL;
    120 
    121     if(( have_state = !tr_bencLoadFile( myConfigFilename, &state )))
     111
     112    if(( have_state = !tr_bencLoadJSONFile( myConfigFilename, &state )))
    122113    {
    123114        const char * str;
    124115        tr_ninf( MY_NAME, "loading settings from \"%s\"", myConfigFilename );
    125116
    126         if( tr_bencDictFindStr( &state, "download-dir", &str ) )
    127             tr_strlcpy( downloadDir, str, sizeof( downloadDir ) );
    128         tr_bencDictFindInt( &state, "peer-limit", &peers );
    129         tr_bencDictFindInt( &state, "pex-allowed", &pex_enabled );
    130         tr_bencDictFindInt( &state, "port", &peer_port );
    131         tr_bencDictFindInt( &state, "port-forwarding-enabled", &fwd_enabled );
    132         tr_bencDictFindStr( &state, "rpc-acl", &acl_fallback );
    133         tr_bencDictFindStr( &state, "auth", &auth_fallback );
    134         tr_bencDictFindInt( &state, "auth-required", &auth_required_fallback );
    135         tr_bencDictFindInt( &state, "rpc-port", &rpc_port_fallback );
    136         tr_bencDictFindInt( &state, "speed-limit-down", &down_limit );
    137         tr_bencDictFindInt( &state, "speed-limit-down-enabled", &down_limited );
    138         tr_bencDictFindInt( &state, "speed-limit-up", &up_limit );
    139         tr_bencDictFindInt( &state, "speed-limit-up-enabled", &up_limited );
    140         if( tr_bencDictFindStr( &state, "encryption", &str ) ) {
     117        tr_bencDictFindInt( &state, KEY_PEER_LIMIT, &peers );
     118        tr_bencDictFindInt( &state, KEY_PEX_ENABLED, &pex_enabled );
     119        tr_bencDictFindInt( &state, KEY_PEER_PORT, &peer_port );
     120        tr_bencDictFindInt( &state, KEY_PORT_FORWARDING, &fwd_enabled );
     121        tr_bencDictFindInt( &state, KEY_DSPEED, &down_limit );
     122        tr_bencDictFindInt( &state, KEY_DSPEED_ENABLED, &down_limited );
     123        tr_bencDictFindInt( &state, KEY_USPEED, &up_limit );
     124        tr_bencDictFindInt( &state, KEY_USPEED_ENABLED, &up_limited );
     125        if( tr_bencDictFindStr( &state, KEY_ENCRYPTION, &str ) ) {
    141126            if( !strcmp( str, "required" ) )
    142127                encryption = TR_ENCRYPTION_REQUIRED;
     
    146131    }
    147132
    148     /* fallbacks */
    149     if( !*downloadDir )
    150         getcwd( downloadDir, sizeof( downloadDir ) );
    151     if( rpc_port < 1 )
    152         rpc_port = rpc_port_fallback;
    153     if( !acl || !*acl )
    154         acl = acl_fallback;
    155     if( !auth || !*auth )
    156         auth = auth_fallback;
    157 
    158     if( auth && parseAuth( auth, &user, &pass ) ) {
    159         tr_nerr( MY_NAME, "Unable to parse authentication string \"%s\"", auth );
    160         abort( );
    161     }
    162 
    163     if( noauth ) {
    164         /* user has explicitly turned off authentication */
    165         user = NULL;
    166         pass = NULL;
    167     }
    168 
    169     auth_required = user || pass;
     133    /***
     134    ****  Decide on which values to pass into tr_sessionInitFull().
     135    ****  The command-line arguments are given precedence and
     136    ****  the state file from the previous session is used as a fallback.
     137    ****  If neither of those can be found, the TR_DEFAULT fields are used .
     138    ***/
     139
     140    /* authorization */
     141    if( authRequired < 0 ) {
     142        if( have_state && tr_bencDictFindInt( &state, KEY_AUTH_REQUIRED, &i ) )
     143            authRequired = i;
     144        if( authRequired < 0 )
     145            authRequired = FALSE;
     146    }
     147
     148    /* username */
     149    if( !username )
     150        tr_bencDictFindStr( &state, KEY_USERNAME, &username );
     151
     152    /* password */
     153    if( !password )
     154        tr_bencDictFindStr( &state, KEY_PASSWORD, &password );
     155
     156    /* acl */
     157    if( !acl ) {
     158        if( have_state )
     159            tr_bencDictFindStr( &state, KEY_ACL, &acl );
     160        if( !acl )
     161            acl = TR_DEFAULT_RPC_ACL;
     162    }
     163
     164    /* rpc port */
     165    if( rpcPort < 0 ) {
     166        if( have_state && tr_bencDictFindInt( &state, KEY_RPC_PORT, &i ) )
     167            rpcPort = i;
     168        if( rpcPort < 0 )
     169            rpcPort = TR_DEFAULT_RPC_PORT;
     170    }
     171
     172
     173    /* blocklist */
     174    if( blocklistEnabled < 0 ) {
     175        if( have_state && tr_bencDictFindInt( &state, KEY_BLOCKLIST, &i ) )
     176            blocklistEnabled = i;
     177        if( blocklistEnabled < 0 )
     178            blocklistEnabled = TR_DEFAULT_BLOCKLIST_ENABLED;
     179    }
     180
     181    /* download dir */
     182    if( !downloadDir ) {
     183        if( have_state )
     184            tr_bencDictFindStr( &state, KEY_DOWNLOAD_DIR, &downloadDir );
     185        if( !downloadDir ) {
     186            getcwd( mycwd, sizeof( mycwd ) );
     187            fprintf( stderr, "cwd is [%s]\n", mycwd );
     188            downloadDir = mycwd;
     189        }
     190    }
     191
     192    /***
     193    ****
     194    ***/
    170195
    171196    /* start the session */
     
    177202                                    peers,
    178203                                    TR_MSG_INF, 0,
    179                                     FALSE, /* is the blocklist enabled? */
     204                                    blocklistEnabled,
    180205                                    TR_DEFAULT_PEER_SOCKET_TOS,
    181                                     TRUE, rpc_port, acl,
    182                                     auth_required, user, pass,
     206                                    TRUE, rpcPort, acl, authRequired, username, password,
    183207                                    TR_DEFAULT_PROXY_ENABLED,
    184208                                    TR_DEFAULT_PROXY,
     
    188212
    189213
    190     if( auth_required )
     214    if( authRequired )
    191215        tr_ninf( MY_NAME, "requiring authentication" );
    192216
     
    206230    puts( "usage: " MY_NAME " [-dfh] [-p file] [-s file]\n"
    207231          "\n"
    208           "Transmission " LONG_VERSION_STRING " http://www.transmissionbt.com/\n"
     232          "Transmission "LONG_VERSION_STRING" http://www.transmissionbt.com/\n"
    209233          "A fast and easy BitTorrent client\n"
    210234          "\n"
    211           "  -a --acl <list>         Access Control List.  (Default: "TR_DEFAULT_RPC_ACL")\n"
    212           "  -f --foreground         Run in the foreground and log to stderr\n"
    213           "  -g --config-dir <dir>   Where to look for torrents and daemon-config.benc\n"
    214           "  -h --help               Display this message and exit\n"
    215           "  -t --auth <user>:<pass> Username and password for authentication\n"
    216           "  -p --port n             Port to listen to for requests  (Default: "TR_DEFAULT_RPC_PORT_STR")\n"
     235          "  -a  --acl <list>         Access Control List.  (Default: "TR_DEFAULT_RPC_ACL")\n"
     236          "  -b  --blocklist          Enable peer blocklists\n"
     237          "  -b0 --blocklist=0        Disable peer blocklists\n"
     238          "  -d  --download-dir <dir> Where store downloaded data\n"
     239          "  -f  --foreground         Run in the foreground and log to stderr\n"
     240          "  -g  --config-dir <dir>   Where to look for torrents and "CONFIG_FILE"\n"
     241          "  -h  --help               Display this message and exit\n"
     242          "  -p  --port=n             Port to listen to for requests  (Default: "TR_DEFAULT_RPC_PORT_STR")\n"
     243          "  -t  --auth               Require authentication\n"
     244          "  -t0 --auth=0             Don't require authentication\n"
     245          "  -u  --username <user>    Set username for authentication\n"
     246          "  -w  --password <pass>    Set password for authentication\n"
    217247          "\n"
    218248          MY_NAME" is a headless Transmission session\n"
     
    223253static void
    224254readargs( int argc, char ** argv,
    225           int * nofork, int * port,
    226           char ** configDir,
    227           char ** acl,
    228           char ** auth,
    229           int * noauth )
     255          int * nofork, char ** configDir, char ** downloadDir,
     256          int * rpcPort, char ** acl, int * authRequired, char ** username, char ** password,
     257          int * blocklistEnabled )
    230258{
    231259    int opt;
    232     char optstr[] = "a:fg:hnp:t:u:w:";
     260    char shortopts[] = "a:b::d:fg:hp:t::u:w:";
    233261    struct option longopts[] = {
    234         { "acl",         required_argument,  NULL, 'a'  },
    235         { "foreground",  no_argument,        NULL, 'f'  },
    236         { "config-dir",  required_argument,  NULL, 'g'  },
    237         { "help",        no_argument,        NULL, 'h'  },
    238         { "noauth",      no_argument,        NULL, 'n'  },
    239         { "port",        required_argument,  NULL, 'p'  },
    240         { "auth",        required_argument,  NULL, 't'  },
    241         { NULL,          0,                  NULL, '\0' }
     262        { "acl",           required_argument,  NULL, 'a'  },
     263        { "blocklist",     optional_argument,  NULL, 'b'  },
     264        { "download-dir",  required_argument,  NULL, 'd'  },
     265        { "foreground",    no_argument,        NULL, 'f'  },
     266        { "config-dir",    required_argument,  NULL, 'g'  },
     267        { "help",          no_argument,        NULL, 'h'  },
     268        { "port",          required_argument,  NULL, 'p'  },
     269        { "auth",          optional_argument,  NULL, 't'  },
     270        { "username",      required_argument,  NULL, 'u'  },
     271        { "password",      required_argument,  NULL, 'w'  },
     272        { NULL,            0,                  NULL, '\0' }
    242273    };
    243     while((( opt = getopt_long( argc, argv, optstr, longopts, NULL ))) != -1 ) {
     274    while((( opt = getopt_long( argc, argv, shortopts, longopts, NULL ))) != -1 ) {
    244275        switch( opt ) {
    245276            case 'a': *acl = tr_strdup( optarg ); break;
     277            case 'b': *blocklistEnabled = optarg ? atoi(optarg)!=0 : TRUE; break;
     278            case 'd': *downloadDir = tr_strdup( optarg ); break;
    246279            case 'f': *nofork = 1; break;
    247             case 'n': *noauth = 1; break;
     280            case 'n': *authRequired = FALSE; break;
    248281            case 'g': *configDir = tr_strdup( optarg ); break;
    249             case 't': *auth = tr_strdup( optarg ); break;
    250             case 'p': *port = atoi( optarg ); break;
     282            case 't': *authRequired = optarg ? atoi(optarg)!=0 : TRUE; break;
     283            case 'u': *username = tr_strdup( optarg ); break;
     284            case 'w': *password = tr_strdup( optarg ); break;
     285            case 'p': *rpcPort = atoi( optarg ); break;
    251286            default: daemonUsage( ); break;
    252287        }
     
    318353{
    319354    int nofork = 0;
    320     int noauth = 0;
    321     int port = TR_DEFAULT_RPC_PORT;
     355    int rpcPort = -1;
     356    int authRequired = -1;
     357    int blocklistEnabled = -1;
    322358    char * configDir = NULL;
     359    char * downloadDir = NULL;
    323360    char * acl = NULL;
    324     char * auth = NULL;
     361    char * username = NULL;
     362    char * password = NULL;
    325363
    326364    signal( SIGINT, gotsig );
     
    330368    signal( SIGHUP, SIG_IGN );
    331369
    332     readargs( argc, argv, &nofork, &port, &configDir, &acl, &auth, &noauth );
     370    readargs( argc, argv, &nofork, &configDir, &downloadDir,
     371              &rpcPort, &acl, &authRequired, &username, &password,
     372              &blocklistEnabled );
    333373    if( configDir == NULL )
    334374        configDir = tr_strdup_printf( "%s-daemon", tr_getDefaultConfigDir() );
    335375    tr_buildPath( myConfigFilename, sizeof( myConfigFilename ),
    336                   configDir, "daemon-config.benc", NULL );
     376                  configDir, CONFIG_FILE, NULL );
    337377
    338378    if( !nofork ) {
     
    343383    }
    344384
    345     session_init( configDir, port, acl, auth, noauth );
     385    session_init( configDir, downloadDir,
     386                  rpcPort, acl, authRequired, username, password,
     387                  blocklistEnabled );
    346388
    347389    while( !closing )
     
    354396
    355397    tr_free( configDir );
     398    tr_free( downloadDir );
     399    tr_free( username );
     400    tr_free( password );
     401    tr_free( acl );
    356402    return 0;
    357403}
  • trunk/daemon/transmission-daemon.1

    r6096 r6146  
    1010.Fl h
    1111.Nm
     12.Op Fl a Ar (+|-)x.x.x.x[/x],...
     13.Op Fl b
     14.Op Fl b0
     15.Op Fl d
    1216.Op Fl f
    13 .Op Fl a Ar (+|-)x.x.x.x[/x],...
    1417.Op Fl g Ar directory
     18.Op Fl h
    1519.Op Fl p Ar port
    16 .Op Fl t Ar user:pass
     20.Op Fl t
     21.Op Fl t0
     22.Op Fl u Ar username
     23.Op Fl w Ar password
    1724.Ek
    1825
     
    2734The options are as follows:
    2835.Bl -tag -width Ds
     36
    2937.It Fl a Fl -acl Ar (+|-)x.x.x.x[/x],...
    3038Specify access control list (ACL) to control which hosts may submit RPC requests.
     
    3543Masks may vary from 0 to 32 inclusive.
    3644Default: +127.0.0.1
     45
     46.It Fl b Fl -blocklist
     47Enable peer blocklists.  Transmission understands the bluetack blocklist file format.
     48New blocklists can be added by copying them into the config-dir's "blocklists" subdirectory.
     49
     50.It Fl b0 Fl -blocklist=0
     51Disble blocklists.
     52
     53.It Fl d Fl -download-dir
     54Where to store downloaded data.
     55
    3756.It Fl f Fl -foreground
    38 Run in the foreground and print errors to stderr instead of forking
    39 and logging errors with syslog.
     57Run in the foreground and print errors to stderr.
     58
    4059.It Fl g Fl -config-dir Ar directory
    4160Where to look for .torrent and config files on startup.
    42 .It Fl t Fl -auth Ar user:pass
    43 Requre
    44 .Ar username
    45 and
    46 .Ar password
    47 authentication
     61
    4862.It Fl h Fl -help
    4963Print command-line option descriptions.
     64
    5065.It Fl p Fl -port Ar port
    5166Port to open and listen for RPC requests on.  Default: 9091
     67
     68.It Fl t Fl -auth
     69Require clients to authenticate themselves.
     70This doesn't do much good unless
     71.Ar username and
     72.Ar password are also set.
     73
     74.It Fl t0 Fl -auth=0
     75Don't require authentication from clients.
     76
     77.It Fl u Fl -username ar username
     78Used for client authentication.
     79
     80.It Fl w Fl -password ar password
     81Used for client authentication.
     82
    5283.El
    5384
  • trunk/libtransmission/bencode.c

    r6073 r6146  
    3434#include "transmission.h"
    3535#include "bencode.h"
     36#include "json.h"
    3637#include "list.h"
    3738#include "ptrarray.h"
     
    12221223***/
    12231224
    1224 int
    1225 tr_bencSaveFile( const char * filename,  const tr_benc * b )
     1225static int
     1226saveFile( const char * filename, const char * content, size_t len )
    12261227{
    12271228    int err = TR_OK;
    1228     int len;
    1229     char * content = tr_bencSave( b, &len );
    12301229    FILE * out = NULL;
    12311230
     
    12461245    if( !err )
    12471246        tr_dbg( "tr_bencSaveFile saved \"%s\"", filename );
    1248     tr_free( content );
    12491247    if( out )
    12501248        fclose( out );
     1249    return err;
     1250}
     1251
     1252int
     1253tr_bencSaveFile( const char * filename,  const tr_benc * b )
     1254{
     1255    int len;
     1256    char * content = tr_bencSave( b, &len );
     1257    const int err = saveFile( filename, content, len );
     1258    tr_free( content );
    12511259    return err;
    12521260}
     
    12631271    return ret;
    12641272}
     1273
     1274int
     1275tr_bencSaveJSONFile( const char * filename, const tr_benc * b )
     1276{
     1277    int len;
     1278    char * content = tr_bencSaveAsJSON( b, &len );
     1279    const int err = saveFile( filename, content, len );
     1280    tr_free( content );
     1281    return err;
     1282}
     1283
     1284int
     1285tr_bencLoadJSONFile( const char * filename, tr_benc * b )
     1286{
     1287    int ret;
     1288    size_t contentLen;
     1289    uint8_t * content = tr_loadFile( filename, &contentLen );
     1290    ret = content ? tr_jsonParse( content, contentLen, b, NULL )
     1291                  : TR_ERROR_IO_OTHER;
     1292    tr_free( content );
     1293    return ret;
     1294}
  • trunk/libtransmission/bencode.h

    r5987 r6146  
    113113int          tr_bencDictRemove( tr_benc * dict, const char * key );
    114114
    115 char*  tr_bencSave( const tr_benc * val, int * len );
    116 char*  tr_bencSaveAsJSON( const tr_benc * top, int * len );
    117 int    tr_bencSaveFile( const char * filename, const tr_benc * );
    118 int    tr_bencLoadFile( const char * filename, tr_benc * );
     115char*  tr_bencSave         ( const tr_benc * val, int * len );
     116char*  tr_bencSaveAsJSON   ( const tr_benc * top, int * len );
     117int    tr_bencSaveFile     ( const char * filename, const tr_benc * );
     118int    tr_bencSaveJSONFile ( const char * filename, const tr_benc * );
     119int    tr_bencLoadFile     ( const char * filename, tr_benc * );
     120int    tr_bencLoadJSONFile ( const char * filename, tr_benc * );
    119121
    120122int tr_bencGetInt( const tr_benc * val, int64_t * setme );
  • trunk/libtransmission/session.c

    r6140 r6146  
    186186tr_handle *
    187187tr_sessionInitFull( const char  * configDir,
     188                    const char  * tag,
    188189                    const char  * downloadDir,
    189                     const char  * tag,
    190190                    int           isPexEnabled,
    191191                    int           isPortForwardingEnabled,
  • trunk/libtransmission/transmission.h

    r6140 r6146  
    225225 */
    226226tr_handle * tr_sessionInitFull( const char  * configDir,
     227                                const char  * tag,
    227228                                const char  * downloadDir,
    228                                 const char  * tag,
    229229                                int           isPexEnabled,
    230230                                int           isPortForwardingEnabled,
Note: See TracChangeset for help on using the changeset viewer.