1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-26 01:27:28 +00:00
transmission/libtransmission/transmission.h
Jordan Lee 35fb00fd9e (trunk libt) #4315 "Transmission 2.31 crashes (segfaults) immediately after launch" -- remove the "max-open-files" code.
max-open-files might have been a nice configuration option once, but (1) we've never advertised it in the gui apps, and (2) the crazy cases are causing more trouble than this feature is worth. It's more complicated now after #4164 -- see #4294, #4311, and this ticket.
2011-06-24 22:39:20 +00:00

1954 lines
66 KiB
C

/******************************************************************************
* $Id$
*
* Copyright (c) Transmission authors and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
/*
* This file defines the public API for the libtransmission library.
*
* Other headers with a public API are bencode.h and utils.h.
* Most of the remaining headers in libtransmission are private.
*/
#ifndef TR_TRANSMISSION_H
#define TR_TRANSMISSION_H 1
#ifdef __cplusplus
extern "C" {
#endif
/***
****
**** Basic Types
****
***/
#include <inttypes.h> /* uintN_t */
#include <time.h> /* time_t */
#if !defined(__cplusplus)
#ifdef HAVE_STDBOOL_H
#include <stdbool.h>
#elif !defined(__bool_true_false_are_defined)
#define bool uint8_t
#define true 1
#define false 0
#endif
#endif
#ifndef PRId64
#define PRId64 "lld"
#endif
#ifndef PRIu64
#define PRIu64 "llu"
#endif
#ifndef PRIu32
#define PRIu32 "lu"
#endif
#if defined(WIN32) && defined(_MSC_VER)
#define inline __inline
#endif
#define SHA_DIGEST_LENGTH 20
#define TR_INET6_ADDRSTRLEN 46
typedef uint32_t tr_file_index_t;
typedef uint32_t tr_piece_index_t;
/* assuming a 16 KiB block, a 32-bit block index gives us a maximum torrent size of 63 TiB.
* if we ever need to grow past that, change this to uint64_t ;) */
typedef uint32_t tr_block_index_t;
typedef uint16_t tr_port;
typedef struct tr_ctor tr_ctor;
typedef struct tr_info tr_info;
typedef struct tr_torrent tr_torrent;
typedef struct tr_session tr_session;
struct tr_benc;
typedef int8_t tr_priority_t;
#define TR_RPC_SESSION_ID_HEADER "X-Transmission-Session-Id"
typedef enum
{
TR_PREALLOCATE_NONE = 0,
TR_PREALLOCATE_SPARSE = 1,
TR_PREALLOCATE_FULL = 2
}
tr_preallocation_mode;
typedef enum
{
TR_CLEAR_PREFERRED,
TR_ENCRYPTION_PREFERRED,
TR_ENCRYPTION_REQUIRED
}
tr_encryption_mode;
/***
****
**** Startup & Shutdown
****
***/
/**
* @addtogroup tr_session Session
*
* A libtransmission session is created by calling 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.
*
* @{
*/
/**
* @brief returns Transmission's default configuration file directory.
*
* The default configuration directory is determined this way:
* -# If the TRANSMISSION_HOME environment variable is set, its value is used.
* -# On Darwin, "${HOME}/Library/Application Support/${appname}" is used.
* -# On Windows, "${CSIDL_APPDATA}/${appname}" is used.
* -# If XDG_CONFIG_HOME is set, "${XDG_CONFIG_HOME}/${appname}" is used.
* -# ${HOME}/.config/${appname}" is used as a last resort.
*/
const char* tr_getDefaultConfigDir( const char * appname );
/**
* @brief returns Transmisson's default download directory.
*
* The default download directory is determined this way:
* -# If the HOME environment variable is set, "${HOME}/Downloads" is used.
* -# On Windows, "${CSIDL_MYDOCUMENTS}/Downloads" is used.
* -# Otherwise, getpwuid(getuid())->pw_dir + "/Downloads" is used.
*/
const char* tr_getDefaultDownloadDir( void );
#define TR_DEFAULT_BIND_ADDRESS_IPV4 "0.0.0.0"
#define TR_DEFAULT_BIND_ADDRESS_IPV6 "::"
#define TR_DEFAULT_RPC_WHITELIST "127.0.0.1"
#define TR_DEFAULT_RPC_PORT_STR "9091"
#define TR_DEFAULT_RPC_URL_STR "/transmission/"
#define TR_DEFAULT_PEER_PORT_STR "51413"
#define TR_DEFAULT_PEER_SOCKET_TOS_STR "default"
#define TR_DEFAULT_PEER_LIMIT_GLOBAL_STR "240"
#define TR_DEFAULT_PEER_LIMIT_TORRENT_STR "60"
#define TR_PREFS_KEY_ALT_SPEED_ENABLED "alt-speed-enabled"
#define TR_PREFS_KEY_ALT_SPEED_UP_KBps "alt-speed-up"
#define TR_PREFS_KEY_ALT_SPEED_DOWN_KBps "alt-speed-down"
#define TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN "alt-speed-time-begin"
#define TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED "alt-speed-time-enabled"
#define TR_PREFS_KEY_ALT_SPEED_TIME_END "alt-speed-time-end"
#define TR_PREFS_KEY_ALT_SPEED_TIME_DAY "alt-speed-time-day"
#define TR_PREFS_KEY_BIND_ADDRESS_IPV4 "bind-address-ipv4"
#define TR_PREFS_KEY_BIND_ADDRESS_IPV6 "bind-address-ipv6"
#define TR_PREFS_KEY_BLOCKLIST_ENABLED "blocklist-enabled"
#define TR_PREFS_KEY_BLOCKLIST_URL "blocklist-url"
#define TR_PREFS_KEY_MAX_CACHE_SIZE_MB "cache-size-mb"
#define TR_PREFS_KEY_DHT_ENABLED "dht-enabled"
#define TR_PREFS_KEY_UTP_ENABLED "utp-enabled"
#define TR_PREFS_KEY_LPD_ENABLED "lpd-enabled"
#define TR_PREFS_KEY_PREFETCH_ENABLED "prefetch-enabled"
#define TR_PREFS_KEY_DOWNLOAD_DIR "download-dir"
#define TR_PREFS_KEY_ENCRYPTION "encryption"
#define TR_PREFS_KEY_IDLE_LIMIT "idle-seeding-limit"
#define TR_PREFS_KEY_IDLE_LIMIT_ENABLED "idle-seeding-limit-enabled"
#define TR_PREFS_KEY_INCOMPLETE_DIR "incomplete-dir"
#define TR_PREFS_KEY_INCOMPLETE_DIR_ENABLED "incomplete-dir-enabled"
#define TR_PREFS_KEY_MSGLEVEL "message-level"
#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_ON_START "peer-port-random-on-start"
#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_PEER_CONGESTION_ALGORITHM "peer-congestion-algorithm"
#define TR_PREFS_KEY_PEX_ENABLED "pex-enabled"
#define TR_PREFS_KEY_PORT_FORWARDING "port-forwarding-enabled"
#define TR_PREFS_KEY_PREALLOCATION "preallocation"
#define TR_PREFS_KEY_RATIO "ratio-limit"
#define TR_PREFS_KEY_RATIO_ENABLED "ratio-limit-enabled"
#define TR_PREFS_KEY_RENAME_PARTIAL_FILES "rename-partial-files"
#define TR_PREFS_KEY_RPC_AUTH_REQUIRED "rpc-authentication-required"
#define TR_PREFS_KEY_RPC_BIND_ADDRESS "rpc-bind-address"
#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_URL "rpc-url"
#define TR_PREFS_KEY_RPC_WHITELIST_ENABLED "rpc-whitelist-enabled"
#define TR_PREFS_KEY_SCRIPT_TORRENT_DONE_FILENAME "script-torrent-done-filename"
#define TR_PREFS_KEY_SCRIPT_TORRENT_DONE_ENABLED "script-torrent-done-enabled"
#define TR_PREFS_KEY_RPC_WHITELIST "rpc-whitelist"
#define TR_PREFS_KEY_DSPEED_KBps "speed-limit-down"
#define TR_PREFS_KEY_DSPEED_ENABLED "speed-limit-down-enabled"
#define TR_PREFS_KEY_USPEED_KBps "speed-limit-up"
#define TR_PREFS_KEY_USPEED_ENABLED "speed-limit-up-enabled"
#define TR_PREFS_KEY_UMASK "umask"
#define TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT "upload-slots-per-torrent"
#define TR_PREFS_KEY_START "start-added-torrents"
#define TR_PREFS_KEY_TRASH_ORIGINAL "trash-original-torrent-files"
/**
* Add libtransmission's default settings to the benc dictionary.
*
* Example:
* @code
* tr_benc settings;
* int64_t i;
*
* 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 initme pointer to a tr_benc dictionary
* @see tr_sessionLoadSettings()
* @see tr_sessionInit()
* @see tr_getDefaultConfigDir()
*/
void tr_sessionGetDefaultSettings( struct tr_benc * dictionary );
/**
* Add the session's current 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 );
/**
* 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 dictionary pointer to an uninitialized tr_benc
* @param configDir the configuration directory to find settings.json
* @param appName if configDir is empty, appName is used to find the default dir.
* @return success true if the settings were loaded, false otherwise
* @see tr_sessionGetDefaultSettings()
* @see tr_sessionInit()
* @see tr_sessionSaveSettings()
*/
bool 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,
const struct tr_benc * dictonary );
/**
* @brief 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 );
* @endcode
*
* @param tag "gtk", "macosx", "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,
bool messageQueueingEnabled,
struct tr_benc * settings );
/** @brief Update a session's settings from a benc dictionary
like to the one used in tr_sessionInit() */
void tr_sessionSet( tr_session * session,
struct tr_benc * settings );
/** @brief Rescan the blocklists directory and
reload whatever blocklist files are found there */
void tr_sessionReloadBlocklists( tr_session * session );
/** @brief End a libtransmission session
@see tr_sessionInit() */
void tr_sessionClose( tr_session * );
/**
* @brief Return the session's configuration directory.
*
* This is where transmission stores its .torrent files, .resume files,
* blocklists, etc. It's set in tr_transmissionInit() and is immutable
* during the session.
*/
const char * tr_sessionGetConfigDir( const tr_session * );
/**
* @brief Set the per-session default download folder for new torrents.
* @see tr_sessionInit()
* @see tr_sessionGetDownloadDir()
* @see tr_ctorSetDownloadDir()
*/
void tr_sessionSetDownloadDir( tr_session * session, const char * downloadDir );
/**
* @brief Get the default download folder for new torrents.
*
* 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 );
/**
* @brief Get available disk space (in bytes) for the default download folder.
* @return zero or positive integer on success, -1 in case of error.
*/
int64_t tr_sessionGetDownloadDirFreeSpace( const tr_session * session );
/**
* @brief Set the torrent's bandwidth priority.
*/
void tr_ctorSetBandwidthPriority( tr_ctor * ctor, tr_priority_t priority );
/**
* @brief Get the torrent's bandwidth priority.
*/
tr_priority_t tr_ctorGetBandwidthPriority( const tr_ctor * ctor );
/**
* @brief set the per-session incomplete download folder.
*
* When you add a new torrent and the session's incomplete directory is enabled,
* the new torrent will start downloading into that directory, and then be moved
* to tr_torrent.downloadDir when the torrent is finished downloading.
*
* Torrents aren't moved as a result of changing the session's incomplete dir --
* it's applied to new torrents, not existing ones.
*
* tr_torrentSetLocation() overrules the incomplete dir: when a user specifies
* a new location, that becomes the torrent's new downloadDir and the torrent
* is moved there immediately regardless of whether or not it's complete.
*
* @see tr_sessionInit()
* @see tr_sessionGetIncompleteDir()
* @see tr_sessionSetIncompleteDirEnabled()
* @see tr_sessionGetIncompleteDirEnabled()
*/
void tr_sessionSetIncompleteDir( tr_session * session, const char * dir );
/** @brief get the per-session incomplete download folder */
const char* tr_sessionGetIncompleteDir( const tr_session * session );
/** @brief enable or disable use of the incomplete download folder */
void tr_sessionSetIncompleteDirEnabled( tr_session * session, bool );
/** @brief get whether or not the incomplete download folder is enabled */
bool tr_sessionIsIncompleteDirEnabled( const tr_session * session );
/**
* @brief When enabled, newly-created files will have ".part" appended
* to their filename until the file is fully downloaded
*
* This is not retroactive -- toggling this will not rename existing files.
* It only applies to new files created by Transmission after this API call.
*
* @see tr_sessionIsIncompleteFileNamingEnabled()
*/
void tr_sessionSetIncompleteFileNamingEnabled( tr_session * session, bool );
/** @brief return true if files will end in ".part" until they're complete */
bool tr_sessionIsIncompleteFileNamingEnabled( const tr_session * session );
/**
* @brief Set whether or not RPC calls are allowed in this 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_sessionInit() and can be
* queried by tr_sessionIsRPCEnabled().
*/
void tr_sessionSetRPCEnabled( tr_session * session,
bool isEnabled );
/** @brief Get whether or not RPC calls are allowed in this session.
@see tr_sessionInit()
@see tr_sessionSetRPCEnabled() */
bool tr_sessionIsRPCEnabled( const tr_session * session );
/** @brief Specify which port to listen for RPC requests on.
@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_sessionInit()
@see tr_sessionSetRPCPort */
tr_port tr_sessionGetRPCPort( const tr_session * session );
/**
* @brief Specify which base URL to use.
*
* @detail The RPC API is accessible under <url>/rpc, the web interface under
* <url>/web.
*
* @see tr_sessionGetRPCUrl
*/
void tr_sessionSetRPCUrl( tr_session * session,
const char * url );
/**
* @brief Get the base URL.
* @see tr_sessionInit()
* @see tr_sessionSetRPCUrl
*/
const char* tr_sessionGetRPCUrl( const tr_session * session );
/**
* @brief Specify a whitelist for remote RPC access
*
* The whitelist is a comma-separated list of dotted-quad IP addresses
* to be allowed. Wildmat notation is supported, meaning that
* '?' is interpreted as a single-character wildcard and
* '*' is interprted as a multi-character wildcard.
*/
void tr_sessionSetRPCWhitelist( tr_session * session,
const char * whitelist );
/** @brief get the Access Control List for allowing/denying RPC requests.
@return a comma-separated string of whitelist domains.
@see tr_sessionInit
@see tr_sessionSetRPCWhitelist */
const char* tr_sessionGetRPCWhitelist( const tr_session * );
void tr_sessionSetRPCWhitelistEnabled( tr_session * session,
bool isEnabled );
bool tr_sessionGetRPCWhitelistEnabled( const tr_session * session );
void tr_sessionSetRPCPassword( tr_session * session,
const char * password );
void tr_sessionSetRPCUsername( tr_session * session,
const char * username );
/** @brief get the password used to restrict RPC requests.
@return the password string.
@see tr_sessionInit()
@see tr_sessionSetRPCPassword() */
const char* tr_sessionGetRPCPassword( const tr_session * session );
const char* tr_sessionGetRPCUsername( const tr_session * session );
void tr_sessionSetRPCPasswordEnabled( tr_session * session,
bool isEnabled );
bool tr_sessionIsRPCPasswordEnabled( const tr_session * session );
const char* tr_sessionGetRPCBindAddress( const tr_session * session );
typedef enum
{
TR_RPC_TORRENT_ADDED,
TR_RPC_TORRENT_STARTED,
TR_RPC_TORRENT_STOPPED,
TR_RPC_TORRENT_REMOVING,
TR_RPC_TORRENT_TRASHING, /* _REMOVING + delete local data */
TR_RPC_TORRENT_CHANGED, /* catch-all for the "torrent-set" rpc method */
TR_RPC_TORRENT_MOVED,
TR_RPC_SESSION_CHANGED,
TR_RPC_SESSION_CLOSE
}
tr_rpc_callback_type;
typedef enum
{
/* no special handling is needed by the caller */
TR_RPC_OK = 0,
/* indicates to the caller that the client will take care of
* removing the torrent itself. For example the client may
* need to keep the torrent alive long enough to cleanly close
* some resources in another thread. */
TR_RPC_NOREMOVE = ( 1 << 1 )
}
tr_rpc_callback_status;
typedef tr_rpc_callback_status (*tr_rpc_func)(tr_session * session,
tr_rpc_callback_type type,
struct tr_torrent * tor_or_null,
void * user_data );
/**
* Register to be notified whenever something is changed via RPC,
* such as a torrent being added, removed, started, stopped, etc.
*
* func is invoked FROM LIBTRANSMISSION'S THREAD!
* This means func must be fast (to avoid blocking peers),
* shouldn't call libtransmission functions (to avoid deadlock),
* and shouldn't modify client-level memory without using a mutex!
*/
void tr_sessionSetRPCCallback( tr_session * session,
tr_rpc_func func,
void * user_data );
/**
***
**/
/** @brief Used by tr_sessionGetStats() and tr_sessionGetCumulativeStats() */
typedef struct tr_session_stats
{
float ratio; /* TR_RATIO_INF, TR_RATIO_NA, or total up/down */
uint64_t uploadedBytes; /* total up */
uint64_t downloadedBytes; /* total down */
uint64_t filesAdded; /* number of files added */
uint64_t sessionCount; /* program started N times */
uint64_t secondsActive; /* how long Transmisson's been running */
}
tr_session_stats;
/** @brief Get bandwidth use statistics for the current session */
void tr_sessionGetStats( const tr_session * session,
tr_session_stats * setme );
/** @brief Get cumulative bandwidth statistics for current and past sessions */
void tr_sessionGetCumulativeStats( const tr_session * session,
tr_session_stats * setme );
void tr_sessionClearStats( tr_session * session );
/**
* @brief Set whether or not torrents are allowed to do peer exchanges.
*
* PEX is always disabled in private torrents regardless of this.
* In public torrents, PEX is enabled by default.
*/
void tr_sessionSetPexEnabled( tr_session * session, bool isEnabled );
bool tr_sessionIsPexEnabled( const tr_session * session );
bool tr_sessionIsDHTEnabled( const tr_session * session );
void tr_sessionSetDHTEnabled( tr_session * session, bool );
bool tr_sessionIsUTPEnabled( const tr_session * session );
void tr_sessionSetUTPEnabled( tr_session * session, bool );
bool tr_sessionIsLPDEnabled( const tr_session * session );
void tr_sessionSetLPDEnabled( tr_session * session, bool enabled );
void tr_sessionSetCacheLimit_MB( tr_session * session, int mb );
int tr_sessionGetCacheLimit_MB( const tr_session * session );
tr_encryption_mode tr_sessionGetEncryption( tr_session * session );
void tr_sessionSetEncryption( tr_session * session,
tr_encryption_mode mode );
/***********************************************************************
** Incoming Peer Connections Port
*/
void tr_sessionSetPortForwardingEnabled( tr_session * session,
bool enabled );
bool tr_sessionIsPortForwardingEnabled( const tr_session * session );
void tr_sessionSetPeerPort( tr_session * session,
tr_port port);
tr_port tr_sessionGetPeerPort( const tr_session * session );
tr_port tr_sessionSetPeerPortRandom( tr_session * session );
void tr_sessionSetPeerPortRandomOnStart( tr_session * session, bool random );
bool tr_sessionGetPeerPortRandomOnStart( tr_session * session );
typedef enum
{
TR_PORT_ERROR,
TR_PORT_UNMAPPED,
TR_PORT_UNMAPPING,
TR_PORT_MAPPING,
TR_PORT_MAPPED
}
tr_port_forwarding;
tr_port_forwarding tr_sessionGetPortForwarding( const tr_session * session );
typedef enum
{
TR_CLIENT_TO_PEER = 0, TR_UP = 0,
TR_PEER_TO_CLIENT = 1, TR_DOWN = 1
}
tr_direction;
/***
****
***/
/***
**** Primary session speed limits
***/
void tr_sessionSetSpeedLimit_KBps ( tr_session *, tr_direction, int KBps );
int tr_sessionGetSpeedLimit_KBps ( const tr_session *, tr_direction );
void tr_sessionLimitSpeed ( tr_session *, tr_direction, bool );
bool tr_sessionIsSpeedLimited ( const tr_session *, tr_direction );
/***
**** Alternative speed limits that are used during scheduled times
***/
void tr_sessionSetAltSpeed_KBps ( tr_session *, tr_direction, int Bps );
int tr_sessionGetAltSpeed_KBps ( const tr_session *, tr_direction );
void tr_sessionUseAltSpeed ( tr_session *, bool );
bool tr_sessionUsesAltSpeed ( const tr_session * );
void tr_sessionUseAltSpeedTime ( tr_session *, bool );
bool tr_sessionUsesAltSpeedTime ( const tr_session * );
void tr_sessionSetAltSpeedBegin ( tr_session *, int minsSinceMidnight );
int tr_sessionGetAltSpeedBegin ( const tr_session * );
void tr_sessionSetAltSpeedEnd ( tr_session *, int minsSinceMidnight );
int tr_sessionGetAltSpeedEnd ( const tr_session * );
typedef enum
{
TR_SCHED_SUN = (1<<0),
TR_SCHED_MON = (1<<1),
TR_SCHED_TUES = (1<<2),
TR_SCHED_WED = (1<<3),
TR_SCHED_THURS = (1<<4),
TR_SCHED_FRI = (1<<5),
TR_SCHED_SAT = (1<<6),
TR_SCHED_WEEKDAY = (TR_SCHED_MON|TR_SCHED_TUES|TR_SCHED_WED|
TR_SCHED_THURS|TR_SCHED_FRI),
TR_SCHED_WEEKEND = (TR_SCHED_SUN|TR_SCHED_SAT),
TR_SCHED_ALL = (TR_SCHED_WEEKDAY|TR_SCHED_WEEKEND)
}
tr_sched_day;
void tr_sessionSetAltSpeedDay ( tr_session *, tr_sched_day day );
tr_sched_day tr_sessionGetAltSpeedDay ( const tr_session * );
typedef void ( tr_altSpeedFunc )( tr_session *,
bool active,
bool userDriven,
void * );
void tr_sessionClearAltSpeedFunc ( tr_session * );
void tr_sessionSetAltSpeedFunc ( tr_session *, tr_altSpeedFunc *, void * );
bool tr_sessionGetActiveSpeedLimit_KBps( const tr_session * session,
tr_direction dir,
double * setme );
/***
****
***/
double tr_sessionGetRawSpeed_KBps ( const tr_session *, tr_direction );
void tr_sessionSetRatioLimited ( tr_session *, bool isLimited );
bool tr_sessionIsRatioLimited ( const tr_session * );
void tr_sessionSetRatioLimit ( tr_session *, double desiredRatio );
double tr_sessionGetRatioLimit ( const tr_session * );
void tr_sessionSetIdleLimited ( tr_session *, bool isLimited );
bool tr_sessionIsIdleLimited ( const tr_session * );
void tr_sessionSetIdleLimit ( tr_session *, uint16_t idleMinutes );
uint16_t tr_sessionGetIdleLimit ( const tr_session * );
void tr_sessionSetPeerLimit( tr_session *, uint16_t maxGlobalPeers );
uint16_t tr_sessionGetPeerLimit( const tr_session * );
void tr_sessionSetPeerLimitPerTorrent( tr_session *, uint16_t maxPeers );
uint16_t tr_sessionGetPeerLimitPerTorrent( const tr_session * );
void tr_sessionSetPaused ( tr_session *, bool isPaused );
bool tr_sessionGetPaused ( const tr_session * );
void tr_sessionSetDeleteSource ( tr_session *, bool deleteSource );
bool tr_sessionGetDeleteSource ( const tr_session * );
tr_priority_t tr_torrentGetPriority( const tr_torrent * );
void tr_torrentSetPriority( tr_torrent *, tr_priority_t );
/**
* Load all the torrents in tr_getTorrentDir().
* This can be used at startup to kickstart all the torrents
* from the previous session.
*/
tr_torrent ** tr_sessionLoadTorrents( tr_session * session,
tr_ctor * ctor,
int * setmeCount );
/**
***
**/
bool tr_sessionIsTorrentDoneScriptEnabled( const tr_session * );
void tr_sessionSetTorrentDoneScriptEnabled( tr_session *, bool isEnabled );
const char * tr_sessionGetTorrentDoneScript( const tr_session * );
void tr_sessionSetTorrentDoneScript( tr_session *, const char * scriptFilename );
/** @} */
/**
***
**/
/***********************************************************************
** Message Logging
*/
typedef enum
{
TR_MSG_ERR = 1,
TR_MSG_INF = 2,
TR_MSG_DBG = 3
}
tr_msg_level;
void tr_setMessageLevel( tr_msg_level );
typedef struct tr_msg_list
{
/* TR_MSG_ERR, TR_MSG_INF, or TR_MSG_DBG */
tr_msg_level level;
/* The line number in the source file where this message originated */
int line;
/* Time the message was generated */
time_t when;
/* The torrent associated with this message,
* or a module name such as "Port Forwarding" for non-torrent messages,
* or NULL. */
char * name;
/* The message */
char * message;
/* The source file where this message originated */
const char * file;
/* linked list of messages */
struct tr_msg_list * next;
}
tr_msg_list;
void tr_setMessageQueuing( bool isEnabled );
bool tr_getMessageQueuing( void );
tr_msg_list * tr_getQueuedMessages( void );
void tr_freeMessageList( tr_msg_list * freeme );
/** @addtogroup Blocklists
@{ */
/**
* Specify a range of IPs for Transmission to block.
*
* Filename must be an uncompressed ascii file.
*
* libtransmission does not keep a handle to `filename'
* after this call returns, so the caller is free to
* keep or delete `filename' as it wishes.
* libtransmission makes its own copy of the file
* massaged into a binary format easier to search.
*
* The caller only needs to invoke this when the blocklist
* has changed.
*
* Passing NULL for a filename will clear the blocklist.
*/
int tr_blocklistSetContent ( tr_session * session,
const char * filename );
int tr_blocklistGetRuleCount ( const tr_session * session );
bool tr_blocklistExists ( const tr_session * session );
bool tr_blocklistIsEnabled ( const tr_session * session );
void tr_blocklistSetEnabled ( tr_session * session,
bool isEnabled );
/** @brief The blocklist that ges updated when an RPC client
invokes the "blocklist-update" method */
void tr_blocklistSetURL ( tr_session *, const char * url );
const char * tr_blocklistGetURL ( const tr_session * );
/** @brief the file in the $config/blocklists/ directory that's
used by tr_blocklistSetContent() and "blocklist-update" */
#define DEFAULT_BLOCKLIST_FILENAME "blocklist.bin"
/** @} */
/** @addtogroup tr_ctor Torrent Constructors
@{
Instantiating a tr_torrent had gotten more complicated as features were
added. At one point there were four functions to check metainfo and five
to create a tr_torrent object.
To remedy this, a Torrent Constructor (struct tr_ctor) has been introduced:
- Simplifies the API to two functions: tr_torrentParse() and tr_torrentNew()
- You can set the fields you want; the system sets defaults for the rest.
- You can specify whether or not your fields should supercede resume's.
- We can add new features to tr_ctor without breaking tr_torrentNew()'s API.
All the tr_ctor{Get,Set}*() functions with a return value return
an error number, or zero if no error occurred.
You must call one of the SetMetainfo() functions before creating
a torrent with a tr_ctor. The other functions are optional.
You can reuse a single tr_ctor to create a batch of torrents --
just call one of the SetMetainfo() functions between each
tr_torrentNew() call.
Every call to tr_ctorSetMetainfo*() frees the previous metainfo.
*/
typedef enum
{
TR_FALLBACK, /* indicates the ctor value should be used only
in case of missing resume settings */
TR_FORCE, /* indicates the ctor value should be used
regardless of what's in the resume settings */
}
tr_ctorMode;
struct tr_benc;
/** @brief Create a torrent constructor object used to instantiate a tr_torrent
@param session the tr_session. This is required if you're going to call
tr_torrentNew(), but you can use NULL for tr_torrentParse().
@see tr_torrentNew(), tr_torrentParse() */
tr_ctor* tr_ctorNew( const tr_session * session_or_NULL );
/** @brief Free a torrent constructor object */
void tr_ctorFree( tr_ctor * ctor );
/** @brief Set whether or not to delete the source .torrent file
when the torrent is added. (Default: False) */
void tr_ctorSetDeleteSource( tr_ctor * ctor, bool doDelete );
/** @brief Set the constructor's metainfo from a magnet link */
int tr_ctorSetMetainfoFromMagnetLink( tr_ctor * ctor, const char * magnet );
/** @brief Set the constructor's metainfo from a raw benc already in memory */
int tr_ctorSetMetainfo( tr_ctor * ctor, const uint8_t * metainfo, size_t len );
/** @brief Set the constructor's metainfo from a local .torrent file */
int tr_ctorSetMetainfoFromFile( tr_ctor * ctor, const char * filename );
/**
* @brief Set the metainfo from an existing file in tr_getTorrentDir().
*
* This is used by the Mac client on startup to pick and choose which
* torrents to load
*/
int tr_ctorSetMetainfoFromHash( tr_ctor * ctor, const char * hashString );
/** @brief Set how many peers this torrent can connect to. (Default: 50) */
void tr_ctorSetPeerLimit( tr_ctor * ctor, tr_ctorMode mode, uint16_t limit );
/** @brief Set the download folder for the torrent being added with this ctor.
@see tr_ctorSetDownloadDir()
@see tr_sessionInit() */
void tr_ctorSetDownloadDir( tr_ctor * ctor,
tr_ctorMode mode,
const char * directory );
/**
* @brief Set the incompleteDir for this torrent.
*
* This is not a supported API call.
* It only exists so the mac client can migrate
* its older incompleteDir settings, and that's
* the only place where it should be used.
*/
void tr_ctorSetIncompleteDir( tr_ctor * ctor, const char * directory );
/** Set whether or not the torrent begins downloading/seeding when created.
(Default: not paused) */
void tr_ctorSetPaused( tr_ctor * ctor,
tr_ctorMode mode,
bool isPaused );
/** @brief Set the priorities for files in a torrent */
void tr_ctorSetFilePriorities( tr_ctor * ctor,
const tr_file_index_t * files,
tr_file_index_t fileCount,
tr_priority_t priority );
/** @brief Set the download flag for files in a torrent */
void tr_ctorSetFilesWanted( tr_ctor * ctor,
const tr_file_index_t * fileIndices,
tr_file_index_t fileCount,
bool wanted );
/** @brief Get this peer constructor's peer limit */
int tr_ctorGetPeerLimit( const tr_ctor * ctor,
tr_ctorMode mode,
uint16_t * setmeCount );
/** @brief Get the "isPaused" flag from this peer constructor */
int tr_ctorGetPaused( const tr_ctor * ctor,
tr_ctorMode mode,
bool * setmeIsPaused );
/** @brief Get the download path from this peer constructor */
int tr_ctorGetDownloadDir( const tr_ctor * ctor,
tr_ctorMode mode,
const char ** setmeDownloadDir );
/** @brief Get the incomplete directory from this peer constructor */
int tr_ctorGetIncompleteDir( const tr_ctor * ctor,
const char ** setmeIncompleteDir );
/** @brief Get the metainfo from this peer constructor */
int tr_ctorGetMetainfo( const tr_ctor * ctor,
const struct tr_benc ** setme );
/** @brief Get the "delete .torrent file" flag from this peer constructor */
int tr_ctorGetDeleteSource( const tr_ctor * ctor,
bool * setmeDoDelete );
/** @brief Get the tr_session poiner from this peer constructor */
tr_session* tr_ctorGetSession( const tr_ctor * ctor );
/** @brief Get the .torrent file that this ctor's metainfo came from,
or NULL if tr_ctorSetMetainfoFromFile() wasn't used */
const char* tr_ctorGetSourceFile( const tr_ctor * ctor );
typedef enum
{
TR_PARSE_OK,
TR_PARSE_ERR,
TR_PARSE_DUPLICATE
}
tr_parse_result;
/**
* @brief Parses the specified metainfo
*
* @return TR_PARSE_ERR if parsing failed;
* TR_PARSE_OK if parsing succeeded and it's not a duplicate;
* TR_PARSE_DUPLICATE if parsing succeeded but it's a duplicate.
*
* @param setme_info If parsing is successful and setme_info is non-NULL,
* the parsed metainfo is stored there and sould be freed
* by calling tr_metainfoFree() when no longer needed.
*
* Notes:
*
* 1. tr_torrentParse() won't be able to check for duplicates -- and therefore
* won't return TR_PARSE_DUPLICATE -- unless ctor's "download-dir" and
* session variable is set.
*
* 2. setme_info->torrent's value can't be set unless ctor's session variable
* is set.
*/
tr_parse_result tr_torrentParse( const tr_ctor * ctor,
tr_info * setme_info_or_NULL );
/** @brief free a metainfo
@see tr_torrentParse */
void tr_metainfoFree( tr_info * inf );
/** Instantiate a single torrent.
@return 0 on success,
TR_EINVALID if the torrent couldn't be parsed, or
TR_EDUPLICATE if there's already a matching torrent object. */
tr_torrent * tr_torrentNew( const tr_ctor * ctor,
int * setmeError );
/** @} */
/***********************************************************************
***
*** TORRENTS
**/
/** @addtogroup tr_torrent Torrents
@{ */
/** @brief Frees memory allocated by tr_torrentNew().
Running torrents are stopped first. */
void tr_torrentFree( tr_torrent * torrent );
typedef int tr_fileFunc( const char * filename );
/** @brief Removes our .torrent and .resume files for
this torrent, then calls tr_torrentFree(). */
void tr_torrentRemove( tr_torrent * torrent,
bool removeLocalData,
tr_fileFunc removeFunc );
/** @brief Start a torrent */
void tr_torrentStart( tr_torrent * torrent );
/** @brief Stop (pause) a torrent */
void tr_torrentStop( tr_torrent * torrent );
enum
{
TR_LOC_MOVING,
TR_LOC_DONE,
TR_LOC_ERROR
};
/**
* @brief Tell transmsision where to find this torrent's local data.
*
* if move_from_previous_location is `true', the torrent's incompleteDir
* will be clobberred s.t. additional files being added will be saved
* to the torrent's downloadDir.
*/
void tr_torrentSetLocation( tr_torrent * torrent,
const char * location,
bool move_from_previous_location,
volatile double * setme_progress,
volatile int * setme_state );
uint64_t tr_torrentGetBytesLeftToAllocate( const tr_torrent * torrent );
/**
* @brief Returns this torrent's unique ID.
*
* IDs are good as simple lookup keys, but are not persistent
* between sessions. If you need that, use tr_info.hash or
* tr_info.hashString.
*/
int tr_torrentId( const tr_torrent * torrent );
tr_torrent* tr_torrentFindFromId( tr_session * session, int id );
tr_torrent* tr_torrentFindFromHash( tr_session * session,
const uint8_t * hash );
/** @brief Convenience function similar to tr_torrentFindFromHash() */
tr_torrent* tr_torrentFindFromMagnetLink( tr_session * session,
const char * link );
/**
* @return this torrent's name.
*/
const char* tr_torrentName( const tr_torrent * );
/**
* @brief find the location of a torrent's file by looking with and without
* the ".part" suffix, looking in downloadDir and incompleteDir, etc.
* @return a newly-allocated string (that must be tr_freed() by the caller
* when done) that gives the location of this file on disk,
* or NULL if no file exists yet.
* @param tor the torrent whose file we're looking for
* @param fileNum the fileIndex, in [0...tr_info.fileCount)
*/
char* tr_torrentFindFile( const tr_torrent * tor, tr_file_index_t fileNo );
/***
**** Torrent speed limits
****
***/
void tr_torrentSetSpeedLimit_KBps ( tr_torrent *, tr_direction, int KBps );
int tr_torrentGetSpeedLimit_KBps ( const tr_torrent *, tr_direction );
void tr_torrentUseSpeedLimit ( tr_torrent *, tr_direction, bool );
bool tr_torrentUsesSpeedLimit ( const tr_torrent *, tr_direction );
void tr_torrentUseSessionLimits ( tr_torrent *, bool );
bool tr_torrentUsesSessionLimits ( const tr_torrent * );
/****
***** Ratio Limits
****/
typedef enum
{
/* follow the global settings */
TR_RATIOLIMIT_GLOBAL = 0,
/* override the global settings, seeding until a certain ratio */
TR_RATIOLIMIT_SINGLE = 1,
/* override the global settings, seeding regardless of ratio */
TR_RATIOLIMIT_UNLIMITED = 2
}
tr_ratiolimit;
void tr_torrentSetRatioMode( tr_torrent * tor,
tr_ratiolimit mode );
tr_ratiolimit tr_torrentGetRatioMode( const tr_torrent * tor );
void tr_torrentSetRatioLimit( tr_torrent * tor,
double ratio );
double tr_torrentGetRatioLimit( const tr_torrent * tor );
bool tr_torrentGetSeedRatio( const tr_torrent *, double * ratio );
/****
***** Idle Time Limits
****/
typedef enum
{
/* follow the global settings */
TR_IDLELIMIT_GLOBAL = 0,
/* override the global settings, seeding until a certain idle time */
TR_IDLELIMIT_SINGLE = 1,
/* override the global settings, seeding regardless of activity */
TR_IDLELIMIT_UNLIMITED = 2
}
tr_idlelimit;
void tr_torrentSetIdleMode ( tr_torrent * tor,
tr_idlelimit mode );
tr_idlelimit tr_torrentGetIdleMode ( const tr_torrent * tor );
void tr_torrentSetIdleLimit( tr_torrent * tor,
uint16_t idleMinutes );
uint16_t tr_torrentGetIdleLimit( const tr_torrent * tor );
bool tr_torrentGetSeedIdle( const tr_torrent *, uint16_t * minutes );
/****
***** Peer Limits
****/
void tr_torrentSetPeerLimit( tr_torrent * tor, uint16_t peerLimit );
uint16_t tr_torrentGetPeerLimit( const tr_torrent * tor );
/****
***** File Priorities
****/
enum
{
TR_PRI_LOW = -1,
TR_PRI_NORMAL = 0, /* since NORMAL is 0, memset initializes nicely */
TR_PRI_HIGH = 1
};
/**
* @brief Set a batch of files to a particular priority.
*
* @param priority must be one of TR_PRI_NORMAL, _HIGH, or _LOW
*/
void tr_torrentSetFilePriorities( tr_torrent * torrent,
const tr_file_index_t * files,
tr_file_index_t fileCount,
tr_priority_t priority );
/**
* @brief Get this torrent's file priorities.
*
* @return A malloc()ed array of tor->info.fileCount items,
* each holding a TR_PRI_NORMAL, TR_PRI_HIGH, or TR_PRI_LOW.
* It's the caller's responsibility to free() this.
*/
tr_priority_t* tr_torrentGetFilePriorities( const tr_torrent * torrent );
/** @brief Set a batch of files to be downloaded or not. */
void tr_torrentSetFileDLs( tr_torrent * torrent,
const tr_file_index_t * files,
tr_file_index_t fileCount,
bool do_download );
const tr_info * tr_torrentInfo( const tr_torrent * torrent );
/* Raw function to change the torrent's downloadDir field.
This should only be used by libtransmission or to bootstrap
a newly-instantiated tr_torrent object. */
void tr_torrentSetDownloadDir( tr_torrent * torrent, const char * path );
const char * tr_torrentGetDownloadDir( const tr_torrent * torrent );
/**
* Returns the root directory of where the torrent is.
*
* This will usually be the downloadDir. However if the torrent
* has an incompleteDir enabled and hasn't finished downloading
* yet, that will be returned instead.
*/
const char * tr_torrentGetCurrentDir( const tr_torrent * tor );
/**
* Returns a newly-allocated string with a magnet link of the torrent.
* Use tr_free() to free the string when done.
*/
char* tr_torrentGetMagnetLink( const tr_torrent * tor );
/**
***
**/
/** @brief a part of tr_info that represents a single tracker */
typedef struct tr_tracker_info
{
int tier;
char * announce;
char * scrape;
uint32_t id; /* unique identifier used to match to a tr_tracker_stat */
}
tr_tracker_info;
/**
* @brief Modify a torrent's tracker list.
*
* This updates both the `torrent' object's tracker list
* and the metainfo file in tr_sessionGetConfigDir()'s torrent subdirectory.
*
* @param torrent The torrent whose tracker list is to be modified
* @param trackers An array of trackers, sorted by tier from first to last.
* NOTE: only the `tier' and `announce' fields are used.
* libtransmission derives `scrape' from `announce'
* and reassigns 'id'.
* @param trackerCount size of the `trackers' array
*/
bool
tr_torrentSetAnnounceList( tr_torrent * torrent,
const tr_tracker_info * trackers,
int trackerCount );
/**
***
**/
typedef enum
{
TR_LEECH, /* doesn't have all the desired pieces */
TR_SEED, /* has the entire torrent */
TR_PARTIAL_SEED /* has the desired pieces, but not the entire torrent */
}
tr_completeness;
/**
* @param wasRunning whether or not the torrent was running when
* it changed its completeness state
*/
typedef void ( tr_torrent_completeness_func )( tr_torrent * torrent,
tr_completeness completeness,
bool wasRunning,
void * user_data );
typedef void ( tr_torrent_ratio_limit_hit_func )( tr_torrent * torrent,
void * user_data );
typedef void ( tr_torrent_idle_limit_hit_func )( tr_torrent * torrent,
void * user_data );
/**
* Register to be notified whenever a torrent's "completeness"
* changes. This will be called, for example, when a torrent
* finishes downloading and changes from TR_LEECH to
* either TR_SEED or TR_PARTIAL_SEED.
*
* func is invoked FROM LIBTRANSMISSION'S THREAD!
* This means func must be fast (to avoid blocking peers),
* shouldn't call libtransmission functions (to avoid deadlock),
* and shouldn't modify client-level memory without using a mutex!
*
* @see tr_completeness
*/
void tr_torrentSetCompletenessCallback(
tr_torrent * torrent,
tr_torrent_completeness_func func,
void * user_data );
void tr_torrentClearCompletenessCallback( tr_torrent * torrent );
typedef void ( tr_torrent_metadata_func )( tr_torrent * torrent,
void * user_data );
/**
* Register to be notified whenever a torrent changes from
* having incomplete metadata to having complete metadata.
* This happens when a magnet link finishes downloading
* metadata from its peers.
*/
void tr_torrentSetMetadataCallback (
tr_torrent * tor,
tr_torrent_metadata_func func,
void * user_data );
/**
* Register to be notified whenever a torrent's ratio limit
* has been hit. This will be called when the torrent's
* ul/dl ratio has met or exceeded the designated ratio limit.
*
* Has the same restrictions as tr_torrentSetCompletenessCallback
*/
void tr_torrentSetRatioLimitHitCallback(
tr_torrent * torrent,
tr_torrent_ratio_limit_hit_func func,
void * user_data );
void tr_torrentClearRatioLimitHitCallback( tr_torrent * torrent );
/**
* Register to be notified whenever a torrent's idle limit
* has been hit. This will be called when the seeding torrent's
* idle time has met or exceeded the designated idle limit.
*
* Has the same restrictions as tr_torrentSetCompletenessCallback
*/
void tr_torrentSetIdleLimitHitCallback(
tr_torrent * torrent,
tr_torrent_idle_limit_hit_func func,
void * user_data );
void tr_torrentClearIdleLimitHitCallback( tr_torrent * torrent );
/**
* MANUAL ANNOUNCE
*
* Trackers usually set an announce interval of 15 or 30 minutes.
* Users can send one-time announce requests that override this
* interval by calling tr_torrentManualUpdate().
*
* The wait interval for tr_torrentManualUpdate() is much smaller.
* You can test whether or not a manual update is possible
* (for example, to desensitize the button) by calling
* tr_torrentCanManualUpdate().
*/
void tr_torrentManualUpdate( tr_torrent * torrent );
bool tr_torrentCanManualUpdate( const tr_torrent * torrent );
/***
**** tr_peer_stat
***/
typedef struct tr_peer_stat
{
bool isUTP;
bool isEncrypted;
bool isDownloadingFrom;
bool isUploadingTo;
bool isSeed;
bool peerIsChoked;
bool peerIsInterested;
bool clientIsChoked;
bool clientIsInterested;
bool isIncoming;
uint8_t from;
tr_port port;
char addr[TR_INET6_ADDRSTRLEN];
char client[80];
char flagStr[32];
float progress;
double rateToPeer_KBps;
double rateToClient_KBps;
/***
**** THESE NEXT FOUR FIELDS ARE EXPERIMENTAL.
**** Don't rely on them; they'll probably go away
***/
/* how many blocks we've sent to this peer in the last 120 seconds */
uint32_t blocksToPeer;
/* how many blocks this client's sent to us in the last 120 seconds */
uint32_t blocksToClient;
/* how many requests to this peer that we've cancelled in the last 120 seconds */
uint32_t cancelsToPeer;
/* how many requests this peer made of us, then cancelled, in the last 120 seconds */
uint32_t cancelsToClient;
/* how many requests the peer has made that we haven't responded to yet */
int pendingReqsToClient;
/* how many requests we've made and are currently awaiting a response for */
int pendingReqsToPeer;
}
tr_peer_stat;
tr_peer_stat * tr_torrentPeers( const tr_torrent * torrent,
int * peerCount );
void tr_torrentPeersFree( tr_peer_stat * peerStats,
int peerCount );
/***
**** tr_tracker_stat
***/
typedef enum
{
/* we won't (announce,scrape) this torrent to this tracker because
* the torrent is stopped, or because of an error, or whatever */
TR_TRACKER_INACTIVE = 0,
/* we will (announce,scrape) this torrent to this tracker, and are
* waiting for enough time to pass to satisfy the tracker's interval */
TR_TRACKER_WAITING = 1,
/* it's time to (announce,scrape) this torrent, and we're waiting on a
* a free slot to open up in the announce manager */
TR_TRACKER_QUEUED = 2,
/* we're (announcing,scraping) this torrent right now */
TR_TRACKER_ACTIVE = 3
}
tr_tracker_state;
typedef struct
{
/* how many downloads this tracker knows of (-1 means it does not know) */
int downloadCount;
/* whether or not we've ever sent this tracker an announcement */
bool hasAnnounced;
/* whether or not we've ever scraped to this tracker */
bool hasScraped;
/* human-readable string identifying the tracker */
char host[1024];
/* the full announce URL */
char announce[1024];
/* the full scrape URL */
char scrape[1024];
/* Transmission uses one tracker per tier,
* and the others are kept as backups */
bool isBackup;
/* is the tracker announcing, waiting, queued, etc */
tr_tracker_state announceState;
/* is the tracker scraping, waiting, queued, etc */
tr_tracker_state scrapeState;
/* number of peers the tracker told us about last time.
* if "lastAnnounceSucceeded" is false, this field is undefined */
int lastAnnouncePeerCount;
/* human-readable string with the result of the last announce.
if "hasAnnounced" is false, this field is undefined */
char lastAnnounceResult[128];
/* when the last announce was sent to the tracker.
* if "hasAnnounced" is false, this field is undefined */
time_t lastAnnounceStartTime;
/* whether or not the last announce was a success.
if "hasAnnounced" is false, this field is undefined */
bool lastAnnounceSucceeded;
/* whether or not the last announce timed out. */
bool lastAnnounceTimedOut;
/* when the last announce was completed.
if "hasAnnounced" is false, this field is undefined */
time_t lastAnnounceTime;
/* human-readable string with the result of the last scrape.
* if "hasScraped" is false, this field is undefined */
char lastScrapeResult[128];
/* when the last scrape was sent to the tracker.
* if "hasScraped" is false, this field is undefined */
time_t lastScrapeStartTime;
/* whether or not the last scrape was a success.
if "hasAnnounced" is false, this field is undefined */
bool lastScrapeSucceeded;
/* whether or not the last scrape timed out. */
bool lastScrapeTimedOut;
/* when the last scrape was completed.
if "hasScraped" is false, this field is undefined */
time_t lastScrapeTime;
/* number of leechers this tracker knows of (-1 means it does not know) */
int leecherCount;
/* when the next periodic announce message will be sent out.
if announceState isn't TR_TRACKER_WAITING, this field is undefined */
time_t nextAnnounceTime;
/* when the next periodic scrape message will be sent out.
if scrapeState isn't TR_TRACKER_WAITING, this field is undefined */
time_t nextScrapeTime;
/* number of seeders this tracker knows of (-1 means it does not know) */
int seederCount;
/* which tier this tracker is in */
int tier;
/* used to match to a tr_tracker_info */
uint32_t id;
}
tr_tracker_stat;
tr_tracker_stat * tr_torrentTrackers( const tr_torrent * torrent,
int * setmeTrackerCount );
void tr_torrentTrackersFree( tr_tracker_stat * trackerStats,
int trackerCount );
/**
* @brief get the download speeds for each of this torrent's webseed sources.
*
* @return an array of tor->info.webseedCount floats giving download speeds.
* Each speed in the array corresponds to the webseed at the same
* array index in tor->info.webseeds.
* To differentiate "idle" and "stalled" status, idle webseeds will
* return -1 instead of 0 KiB/s.
* NOTE: always free this array with tr_free() when you're done with it.
*/
double* tr_torrentWebSpeeds_KBps( const tr_torrent * torrent );
typedef struct tr_file_stat
{
uint64_t bytesCompleted;
float progress;
}
tr_file_stat;
tr_file_stat * tr_torrentFiles( const tr_torrent * torrent,
tr_file_index_t * fileCount );
void tr_torrentFilesFree( tr_file_stat * files,
tr_file_index_t fileCount );
/***********************************************************************
* tr_torrentAvailability
***********************************************************************
* Use this to draw an advanced progress bar which is 'size' pixels
* wide. Fills 'tab' which you must have allocated: each byte is set
* to either -1 if we have the piece, otherwise it is set to the number
* of connected peers who have the piece.
**********************************************************************/
void tr_torrentAvailability( const tr_torrent * torrent,
int8_t * tab,
int size );
void tr_torrentAmountFinished( const tr_torrent * torrent,
float * tab,
int size );
void tr_torrentVerify( tr_torrent * torrent );
/***********************************************************************
* tr_info
**********************************************************************/
/** @brief a part of tr_info that represents a single file of the torrent's content */
typedef struct tr_file
{
uint64_t length; /* Length of the file, in bytes */
char * name; /* Path to the file */
int8_t priority; /* TR_PRI_HIGH, _NORMAL, or _LOW */
int8_t dnd; /* "do not download" flag */
tr_piece_index_t firstPiece; /* We need pieces [firstPiece... */
tr_piece_index_t lastPiece; /* ...lastPiece] to dl this file */
uint64_t offset; /* file begins at the torrent's nth byte */
}
tr_file;
/** @brief a part of tr_info that represents a single piece of the torrent's content */
typedef struct tr_piece
{
time_t timeChecked; /* the last time we tested this piece */
uint8_t hash[SHA_DIGEST_LENGTH]; /* pieces hash */
int8_t priority; /* TR_PRI_HIGH, _NORMAL, or _LOW */
int8_t dnd; /* "do not download" flag */
}
tr_piece;
/** @brief information about a torrent that comes from its metainfo file */
struct tr_info
{
/* total size of the torrent, in bytes */
uint64_t totalSize;
/* the torrent's name */
char * name;
/* Path to torrent Transmission's internal copy of the .torrent file. */
char * torrent;
char ** webseeds;
char * comment;
char * creator;
tr_file * files;
tr_piece * pieces;
/* these trackers are sorted by tier */
tr_tracker_info * trackers;
/* Torrent info */
time_t dateCreated;
int trackerCount;
int webseedCount;
tr_file_index_t fileCount;
uint32_t pieceSize;
tr_piece_index_t pieceCount;
/* General info */
uint8_t hash[SHA_DIGEST_LENGTH];
char hashString[2 * SHA_DIGEST_LENGTH + 1];
/* Flags */
bool isPrivate;
bool isMultifile;
};
static inline bool tr_torrentHasMetadata( const tr_torrent * tor )
{
return tr_torrentInfo( tor )->fileCount > 0;
}
/**
* What the torrent is doing right now.
*
* Note: these values will become a straight enum at some point in the future.
* Do not rely on their current `bitfield' implementation
*/
typedef enum
{
TR_STATUS_CHECK_WAIT = ( 1 << 0 ), /* Waiting in queue to check files */
TR_STATUS_CHECK = ( 1 << 1 ), /* Checking files */
TR_STATUS_DOWNLOAD = ( 1 << 2 ), /* Downloading */
TR_STATUS_SEED = ( 1 << 3 ), /* Seeding */
TR_STATUS_STOPPED = ( 1 << 4 ) /* Torrent is stopped */
}
tr_torrent_activity;
enum
{
TR_PEER_FROM_INCOMING = 0, /* connections made to the listening port */
TR_PEER_FROM_LPD, /* peers found by local announcements */
TR_PEER_FROM_TRACKER, /* peers found from a tracker */
TR_PEER_FROM_DHT, /* peers found from the DHT */
TR_PEER_FROM_PEX, /* peers found from PEX */
TR_PEER_FROM_RESUME, /* peers found in the .resume file */
TR_PEER_FROM_LTEP, /* peer address provided in an LTEP handshake */
TR_PEER_FROM__MAX
};
typedef enum
{
/* everything's fine */
TR_STAT_OK = 0,
/* when we anounced to the tracker, we got a warning in the response */
TR_STAT_TRACKER_WARNING = 1,
/* when we anounced to the tracker, we got an error in the response */
TR_STAT_TRACKER_ERROR = 2,
/* local trouble, such as disk full or permissions error */
TR_STAT_LOCAL_ERROR = 3
}
tr_stat_errtype;
/** @brief Used by tr_torrentStat() to tell clients about a torrent's state and statistics */
typedef struct tr_stat
{
/** The torrent's unique Id.
@see tr_torrentId() */
int id;
/** What is this torrent doing right now? */
tr_torrent_activity activity;
/** Defines what kind of text is in errorString.
@see errorString */
tr_stat_errtype error;
/** A warning or error message regarding the torrent.
@see error */
char errorString[512];
/** When tr_stat.activity is TR_STATUS_CHECK or TR_STATUS_CHECK_WAIT,
this is the percentage of how much of the files has been
verified. When it gets to 1, the verify process is done.
Range is [0..1]
@see tr_stat.activity */
float recheckProgress;
/** How much has been downloaded of the entire torrent.
Range is [0..1] */
float percentComplete;
/** How much of the metadata the torrent has.
For torrents added from a .torrent this will always be 1.
For magnet links, this number will from from 0 to 1 as the metadata is downloaded.
Range is [0..1] */
float metadataPercentComplete;
/** How much has been downloaded of the files the user wants. This differs
from percentComplete if the user wants only some of the torrent's files.
Range is [0..1]
@see tr_stat.leftUntilDone */
float percentDone;
/** How much has been uploaded to satisfy the seed ratio.
This is 1 if the ratio is reached or the torrent is set to seed forever.
Range is [0..1] */
float seedRatioPercentDone;
/** Speed all data being sent for this torrent.
This includes piece data, protocol messages, and TCP overhead */
float rawUploadSpeed_KBps;
/** Speed all data being received for this torrent.
This includes piece data, protocol messages, and TCP overhead */
float rawDownloadSpeed_KBps;
/** Speed all piece being sent for this torrent.
This ONLY counts piece data. */
float pieceUploadSpeed_KBps;
/** Speed all piece being received for this torrent.
This ONLY counts piece data. */
float pieceDownloadSpeed_KBps;
#define TR_ETA_NOT_AVAIL -1
#define TR_ETA_UNKNOWN -2
/** If downloading, estimated number of seconds left until the torrent is done.
If seeding, estimated number of seconds left until seed ratio is reached. */
int eta;
/** If seeding, number of seconds left until the idle time limit is reached. */
int etaIdle;
/** Number of peers that we're connected to */
int peersConnected;
/** How many peers we found out about from the tracker, or from pex,
or from incoming connections, or from our resume file. */
int peersFrom[TR_PEER_FROM__MAX];
/** Number of peers that are sending data to us. */
int peersSendingToUs;
/** Number of peers that we're sending data to */
int peersGettingFromUs;
/** Number of webseeds that are sending data to us. */
int webseedsSendingToUs;
/** Byte count of all the piece data we'll have downloaded when we're done,
whether or not we have it yet. This may be less than tr_info.totalSize
if only some of the torrent's files are wanted.
[0...tr_info.totalSize] */
uint64_t sizeWhenDone;
/** Byte count of how much data is left to be downloaded until we've got
all the pieces that we want. [0...tr_info.sizeWhenDone] */
uint64_t leftUntilDone;
/** Byte count of all the piece data we want and don't have yet,
but that a connected peer does have. [0...leftUntilDone] */
uint64_t desiredAvailable;
/** Byte count of all the corrupt data you've ever downloaded for
this torrent. If you're on a poisoned torrent, this number can
grow very large. */
uint64_t corruptEver;
/** Byte count of all data you've ever uploaded for this torrent. */
uint64_t uploadedEver;
/** Byte count of all the non-corrupt data you've ever downloaded
for this torrent. If you deleted the files and downloaded a second
time, this will be 2*totalSize.. */
uint64_t downloadedEver;
/** Byte count of all the checksum-verified data we have for this torrent.
*/
uint64_t haveValid;
/** Byte count of all the partial piece data we have for this torrent.
As pieces become complete, this value may decrease as portions of it
are moved to `corrupt' or `haveValid'. */
uint64_t haveUnchecked;
/** time when one or more of the torrent's trackers will
allow you to manually ask for more peers,
or 0 if you can't */
time_t manualAnnounceTime;
#define TR_RATIO_NA -1
#define TR_RATIO_INF -2
/** TR_RATIO_INF, TR_RATIO_NA, or a regular ratio */
float ratio;
/** When the torrent was first added. */
time_t addedDate;
/** When the torrent finished downloading. */
time_t doneDate;
/** When the torrent was last started. */
time_t startDate;
/** The last time we uploaded or downloaded piece data on this torrent. */
time_t activityDate;
/** Number of seconds since the last activity (or since started).
-1 if activity is not seeding or downloading. */
int idleSecs;
/** Cumulative seconds the torrent's ever spent downloading */
int secondsDownloading;
/** Cumulative seconds the torrent's ever spent seeding */
int secondsSeeding;
/** A torrent is considered finished if it has met its seed ratio.
As a result, only paused torrents can be finished. */
bool finished;
}
tr_stat;
/** Return a pointer to an tr_stat structure with updated information
on the torrent. This is typically called by the GUI clients every
second or so to get a new snapshot of the torrent's status. */
const tr_stat * tr_torrentStat( tr_torrent * torrent );
/** Like tr_torrentStat(), but only recalculates the statistics if it's
been longer than a second since they were last calculated. This can
reduce the CPU load if you're calling tr_torrentStat() frequently. */
const tr_stat * tr_torrentStatCached( tr_torrent * torrent );
/** @deprecated */
void tr_torrentSetAddedDate( tr_torrent * torrent,
time_t addedDate );
/** @deprecated */
void tr_torrentSetActivityDate( tr_torrent * torrent,
time_t activityDate );
/** @deprecated */
void tr_torrentSetDoneDate( tr_torrent * torrent, time_t doneDate );
/** @} */
/** @brief Sanity checker to test that the direction is TR_UP or TR_DOWN */
static inline bool tr_isDirection( tr_direction d ) { return d==TR_UP || d==TR_DOWN; }
/** @brief Sanity checker to test that a bool is true or false */
static inline bool tr_isBool( bool b ) { return b==1 || b==0; }
#ifdef __cplusplus
}
#endif
#endif