mirror of
https://github.com/transmission/transmission
synced 2025-03-03 18:25:35 +00:00
add torrent-ctor so that xcode can be updated. it's not plugged in yet though.
This commit is contained in:
parent
71471102bc
commit
f1baca587b
3 changed files with 341 additions and 4 deletions
|
@ -28,6 +28,7 @@ libtransmission_a_SOURCES = \
|
|||
shared.c \
|
||||
stats.c \
|
||||
torrent.c \
|
||||
torrent-ctor.c \
|
||||
tracker.c \
|
||||
transmission.c \
|
||||
trevent.c \
|
||||
|
|
222
libtransmission/torrent-ctor.c
Normal file
222
libtransmission/torrent-ctor.c
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#include "transmission.h"
|
||||
#include "bencode.h"
|
||||
#include "platform.h"
|
||||
#include "trcompat.h" /* strlcpy */
|
||||
#include "utils.h"
|
||||
|
||||
struct optional_args
|
||||
{
|
||||
unsigned int isSet_paused : 1;
|
||||
unsigned int isSet_unchoked : 1;
|
||||
unsigned int isSet_connected : 1;
|
||||
unsigned int isSet_destination : 1;
|
||||
|
||||
unsigned int isPaused : 1;
|
||||
uint8_t maxUnchokedPeers;
|
||||
uint16_t maxConnectedPeers;
|
||||
char destination[MAX_PATH_LENGTH];
|
||||
};
|
||||
|
||||
struct tr_ctor
|
||||
{
|
||||
tr_handle * handle;
|
||||
|
||||
unsigned int isSet_metadata : 1;
|
||||
benc_val_t metadata;
|
||||
|
||||
struct optional_args optionalArgs[2];
|
||||
};
|
||||
|
||||
tr_ctor*
|
||||
tr_ctorNew( tr_handle * handle )
|
||||
{
|
||||
tr_ctor * ctor = tr_new0( struct tr_ctor, 1 );
|
||||
ctor->handle = handle;
|
||||
tr_ctorSetMaxConnectedPeers( ctor, TR_FALLBACK, 50 );
|
||||
tr_ctorSetMaxUnchokedPeers( ctor, TR_FALLBACK, 16 );
|
||||
tr_ctorSetPaused( ctor, TR_FALLBACK, FALSE );
|
||||
return ctor;
|
||||
}
|
||||
|
||||
void
|
||||
tr_ctorFree( tr_ctor * ctor )
|
||||
{
|
||||
tr_free( ctor );
|
||||
}
|
||||
|
||||
static void
|
||||
clearMetadata( tr_ctor * ctor )
|
||||
{
|
||||
if( ctor->isSet_metadata ) {
|
||||
ctor->isSet_metadata = 0;
|
||||
tr_bencFree( &ctor->metadata );
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tr_ctorSetMetadata( tr_ctor * ctor,
|
||||
const uint8_t * metadata,
|
||||
size_t len )
|
||||
{
|
||||
int err;
|
||||
clearMetadata( ctor );
|
||||
err = tr_bencLoad( metadata, len, &ctor->metadata, NULL );
|
||||
ctor->isSet_metadata = !err;
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ctorSetMetadataFromFile( tr_ctor * ctor,
|
||||
const char * filename )
|
||||
{
|
||||
uint8_t * metadata;
|
||||
size_t len;
|
||||
int err;
|
||||
|
||||
metadata = tr_loadFile( filename, &len );
|
||||
if( metadata && len )
|
||||
err = tr_ctorSetMetadata( ctor, metadata, len );
|
||||
else {
|
||||
clearMetadata( ctor );
|
||||
err = 1;
|
||||
}
|
||||
|
||||
tr_free( metadata );
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ctorSetMetadataFromHash( tr_ctor * ctor,
|
||||
const char * hashString )
|
||||
{
|
||||
int err = -1;
|
||||
char basename[2048];
|
||||
char filename[MAX_PATH_LENGTH];
|
||||
|
||||
if( err && ( ctor->handle->tag != NULL ) ) {
|
||||
snprintf( basename, sizeof(basename), "%s-%s", hashString, ctor->handle->tag );
|
||||
tr_buildPath( filename, sizeof(filename), tr_getTorrentsDirectory(), basename );
|
||||
err = tr_ctorSetMetadataFromFile( ctor, filename );
|
||||
}
|
||||
|
||||
if( err ) {
|
||||
tr_buildPath( filename, sizeof(filename), tr_getTorrentsDirectory(), hashString );
|
||||
err = tr_ctorSetMetadataFromFile( ctor, filename );
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
void
|
||||
tr_ctorSetPaused( tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
int isPaused )
|
||||
{
|
||||
struct optional_args * args = &ctor->optionalArgs[mode];
|
||||
args->isSet_paused = 1;
|
||||
args->isPaused = isPaused;
|
||||
}
|
||||
|
||||
void
|
||||
tr_ctorSetMaxUnchokedPeers( tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
uint8_t maxUnchokedPeers)
|
||||
{
|
||||
struct optional_args * args = &ctor->optionalArgs[mode];
|
||||
args->isSet_unchoked = 1;
|
||||
args->maxUnchokedPeers = maxUnchokedPeers;
|
||||
}
|
||||
|
||||
void
|
||||
tr_ctorSetMaxConnectedPeers( tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
uint16_t maxConnectedPeers )
|
||||
{
|
||||
struct optional_args * args = &ctor->optionalArgs[mode];
|
||||
args->isSet_connected = 1;
|
||||
args->maxConnectedPeers = maxConnectedPeers;
|
||||
}
|
||||
|
||||
void
|
||||
tr_ctorSetDestination( tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
const char * directory )
|
||||
{
|
||||
struct optional_args * args = &ctor->optionalArgs[mode];
|
||||
args->isSet_destination = 1;
|
||||
strlcpy( args->destination, directory, sizeof( args->destination ) );
|
||||
}
|
||||
|
||||
int
|
||||
tr_ctorGetMaxConnectedPeers( const tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
uint16_t * setmeCount )
|
||||
{
|
||||
const struct optional_args * args = &ctor->optionalArgs[mode];
|
||||
const int isSet = args->isSet_connected;
|
||||
if( isSet )
|
||||
*setmeCount = args->maxConnectedPeers;
|
||||
return isSet;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ctorGetMaxUnchokedPeers( const tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
uint8_t * setmeCount )
|
||||
{
|
||||
const struct optional_args * args = &ctor->optionalArgs[mode];
|
||||
const int isSet = args->isSet_unchoked;
|
||||
if( isSet )
|
||||
*setmeCount = args->maxUnchokedPeers;
|
||||
return isSet;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ctorGetIsPaused( const tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
int * setmeIsPaused )
|
||||
{
|
||||
const struct optional_args * args = &ctor->optionalArgs[mode];
|
||||
const int isSet = args->isSet_paused;
|
||||
if( isSet )
|
||||
*setmeIsPaused = args->isPaused;
|
||||
return isSet;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ctorGetDestination( const tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
const char ** setmeDestination )
|
||||
{
|
||||
const struct optional_args * args = &ctor->optionalArgs[mode];
|
||||
const int isSet = args->isSet_destination;
|
||||
if( isSet )
|
||||
*setmeDestination = args->destination;
|
||||
return isSet;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ctorGetMetadata( const tr_ctor * ctor,
|
||||
const struct benc_val_s ** setme )
|
||||
{
|
||||
const int isSet = ctor->isSet_metadata;
|
||||
if( isSet )
|
||||
*setme = &ctor->metadata;
|
||||
return isSet;
|
||||
}
|
|
@ -352,6 +352,124 @@ tr_torrent ** tr_loadTorrents ( tr_handle * h,
|
|||
int * setmeCount );
|
||||
|
||||
|
||||
/**
|
||||
* Torrent Instantiation
|
||||
*
|
||||
* Creating torrents has gotten more complicated as we've added options,
|
||||
* and there are now a lot of functions for creating torrents, all slightly
|
||||
* different. To remedy this, a Torrent Constructor (struct tr_ctor) has
|
||||
* been introduced. You can fill in the settings you want, and leave the
|
||||
* rest to the system defaults. It also gives us a backwards-compatable
|
||||
* way of adding features in the future -- we can add new tr_ctor() functions
|
||||
* and leave tr_torrentInit()'s signature alone.
|
||||
*
|
||||
* You _must_ call one of the SetMetadata() functions before creating
|
||||
* a torrent with a tr_ctor. The other functions are optional.
|
||||
*
|
||||
* You can reuse a tr_ctor when creating a batch of torrents.
|
||||
* Just call one of the SetMetadata() functions between each
|
||||
* tr_torrentInit() call.
|
||||
*
|
||||
* The tr_ctorGet*() functions will return nonzero if that field
|
||||
* has been set via one of the tr_ctorSet*() functions.
|
||||
*
|
||||
* Every call to tr_ctorSetMetadata*() will free the previous metadata.
|
||||
* The tr_ctorSetMetadata*() functions return an error number, or zero
|
||||
* if no error occurred.
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TR_FALLBACK, /* indicates the ctor value should be used only
|
||||
in case of missing fastresume settings */
|
||||
|
||||
TR_FORCE, /* manditory use -- overrides the fastresume settings */
|
||||
}
|
||||
tr_ctorMode;
|
||||
|
||||
typedef struct tr_ctor tr_ctor;
|
||||
struct benc_val_s;
|
||||
|
||||
tr_ctor* tr_ctorNew ( tr_handle * handle);
|
||||
|
||||
void tr_ctorFree ( tr_ctor * ctor );
|
||||
|
||||
int tr_ctorSetMetadata ( tr_ctor * ctor,
|
||||
const uint8_t * metadata,
|
||||
size_t len );
|
||||
|
||||
int tr_ctorSetMetadataFromFile ( tr_ctor * ctor,
|
||||
const char * filename );
|
||||
|
||||
int tr_ctorSetMetadataFromHash ( tr_ctor * ctor,
|
||||
const char * hashString );
|
||||
|
||||
void tr_ctorSetMaxConnectedPeers ( tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
uint16_t maxConnectedPeers );
|
||||
|
||||
void tr_ctorSetMaxUnchokedPeers ( tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
uint8_t maxUnchokedPeers);
|
||||
|
||||
void tr_ctorSetDestination ( tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
const char * directory );
|
||||
|
||||
void tr_ctorSetPaused ( tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
int isPaused );
|
||||
|
||||
int tr_ctorGetMaxConnectedPeers ( const tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
uint16_t * setmeCount );
|
||||
|
||||
int tr_ctorGetMaxUnchokedPeers ( const tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
uint8_t * setmeCount );
|
||||
|
||||
int tr_ctorGetIsPaused ( const tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
int * setmeIsPaused );
|
||||
|
||||
int tr_ctorGetDestination ( const tr_ctor * ctor,
|
||||
tr_ctorMode mode,
|
||||
const char ** setmeDestination );
|
||||
|
||||
int tr_ctorGetMetadata ( const tr_ctor * ctor,
|
||||
const struct benc_val_s ** setme );
|
||||
|
||||
/**
|
||||
* Parses the specified metainfo.
|
||||
* Returns TR_OK if it parsed and can be added to Transmission.
|
||||
* Returns TR_INVALID if it couldn't be parsed.
|
||||
* Returns TR_EDUPLICATE if it parsed but can't be added.
|
||||
* "destination" must be set to test for TR_EDUPLICATE.
|
||||
*
|
||||
* "setme_info" can be NULL if you don't need the information.
|
||||
* If the metainfo can be parsed and setme_info is non-NULL,
|
||||
* it will be filled with the metadata's info. You'll need to
|
||||
* call tr_metainfoFree( setme_info ) when done with it.
|
||||
*/
|
||||
int tr_torrentParseFromCtor( tr_handle * handle,
|
||||
const tr_ctor * ctor );
|
||||
|
||||
/**
|
||||
* Instantiate the torrent from the given tr_ctor.
|
||||
*/
|
||||
#define TR_EINVALID 1
|
||||
#define TR_EUNSUPPORTED 2
|
||||
#define TR_EDUPLICATE 3
|
||||
#define TR_EOTHER 666
|
||||
tr_torrent * tr_torrentNew( tr_handle * handle,
|
||||
const tr_ctor * ctor,
|
||||
int * setmeError );
|
||||
|
||||
|
||||
/**
|
||||
***
|
||||
**/
|
||||
|
||||
/***********************************************************************
|
||||
* tr_torrentInit
|
||||
***********************************************************************
|
||||
|
@ -362,10 +480,6 @@ tr_torrent ** tr_loadTorrents ( tr_handle * h,
|
|||
* then it's 20-byte hash will be copied in. If the TR_FLAG_SAVE flag
|
||||
* is passed then a copy of the torrent file will be saved.
|
||||
**********************************************************************/
|
||||
#define TR_EINVALID 1
|
||||
#define TR_EUNSUPPORTED 2
|
||||
#define TR_EDUPLICATE 3
|
||||
#define TR_EOTHER 666
|
||||
tr_torrent * tr_torrentInit( tr_handle * handle,
|
||||
const char * metainfo_filename,
|
||||
const char * destination,
|
||||
|
|
Loading…
Add table
Reference in a new issue