1/****************************************************************************** 2 * $Id: transmission.h 13397 2012-07-23 15:28:27Z jordan $ 3 * 4 * Copyright (c) Transmission authors and contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 *****************************************************************************/ 24 25/* 26 * This file defines the public API for the libtransmission library. 27 * 28 * Other headers with a public API are bencode.h and utils.h. 29 * Most of the remaining headers in libtransmission are private. 30 */ 31#ifndef TR_TRANSMISSION_H 32#define TR_TRANSMISSION_H 1 33 34#ifdef __cplusplus 35extern "C" { 36#endif 37 38/*** 39**** 40**** Basic Types 41**** 42***/ 43 44#include <inttypes.h> /* uintN_t */ 45#include <time.h> /* time_t */ 46 47#if !defined(__cplusplus) 48 #ifdef HAVE_STDBOOL_H 49 #include <stdbool.h> 50 #elif !defined(__bool_true_false_are_defined) 51 #define bool uint8_t 52 #define true 1 53 #define false 0 54 #endif 55#endif 56 57#ifndef PRId64 58 #define PRId64 "lld" 59#endif 60#ifndef PRIu64 61 #define PRIu64 "llu" 62#endif 63#ifndef PRIu32 64 #define PRIu32 "lu" 65#endif 66 67#if defined(WIN32) && defined(_MSC_VER) 68 #define inline __inline 69#endif 70 71#define SHA_DIGEST_LENGTH 20 72#define TR_INET6_ADDRSTRLEN 46 73 74typedef uint32_t tr_file_index_t; 75typedef uint32_t tr_piece_index_t; 76/* assuming a 16 KiB block, a 32-bit block index gives us a maximum torrent size of 63 TiB. 77 * if we ever need to grow past that, change this to uint64_t ;) */ 78typedef uint32_t tr_block_index_t; 79typedef uint16_t tr_port; 80 81typedef struct tr_ctor tr_ctor; 82typedef struct tr_info tr_info; 83typedef struct tr_torrent tr_torrent; 84typedef struct tr_session tr_session; 85 86struct tr_benc; 87 88typedef int8_t tr_priority_t; 89 90#define TR_RPC_SESSION_ID_HEADER "X-Transmission-Session-Id" 91 92typedef enum 93{ 94 TR_PREALLOCATE_NONE = 0, 95 TR_PREALLOCATE_SPARSE = 1, 96 TR_PREALLOCATE_FULL = 2 97} 98tr_preallocation_mode; 99 100typedef enum 101{ 102 TR_CLEAR_PREFERRED, 103 TR_ENCRYPTION_PREFERRED, 104 TR_ENCRYPTION_REQUIRED 105} 106tr_encryption_mode; 107 108 109/*** 110**** 111**** Startup & Shutdown 112**** 113***/ 114 115/** 116 * @addtogroup tr_session Session 117 * 118 * A libtransmission session is created by calling tr_sessionInit(). 119 * libtransmission creates a thread for itself so that it can operate 120 * independently of the caller's event loop. The session will continue 121 * until tr_sessionClose() is called. 122 * 123 * @{ 124 */ 125 126/** 127 * @brief returns Transmission's default configuration file directory. 128 * 129 * The default configuration directory is determined this way: 130 * -# If the TRANSMISSION_HOME environment variable is set, its value is used. 131 * -# On Darwin, "${HOME}/Library/Application Support/${appname}" is used. 132 * -# On Windows, "${CSIDL_APPDATA}/${appname}" is used. 133 * -# If XDG_CONFIG_HOME is set, "${XDG_CONFIG_HOME}/${appname}" is used. 134 * -# ${HOME}/.config/${appname}" is used as a last resort. 135 */ 136const char* tr_getDefaultConfigDir( const char * appname ); 137 138/** 139 * @brief returns Transmisson's default download directory. 140 * 141 * The default download directory is determined this way: 142 * -# If the HOME environment variable is set, "${HOME}/Downloads" is used. 143 * -# On Windows, "${CSIDL_MYDOCUMENTS}/Downloads" is used. 144 * -# Otherwise, getpwuid(getuid())->pw_dir + "/Downloads" is used. 145 */ 146const char* tr_getDefaultDownloadDir( void ); 147 148 149#define TR_DEFAULT_BIND_ADDRESS_IPV4 "0.0.0.0" 150#define TR_DEFAULT_BIND_ADDRESS_IPV6 "::" 151#define TR_DEFAULT_RPC_WHITELIST "127.0.0.1" 152#define TR_DEFAULT_RPC_PORT_STR "9091" 153#define TR_DEFAULT_RPC_URL_STR "/transmission/" 154#define TR_DEFAULT_PEER_PORT_STR "51413" 155#define TR_DEFAULT_PEER_SOCKET_TOS_STR "default" 156#define TR_DEFAULT_PEER_LIMIT_GLOBAL_STR "240" 157#define TR_DEFAULT_PEER_LIMIT_TORRENT_STR "60" 158 159#define TR_PREFS_KEY_ALT_SPEED_ENABLED "alt-speed-enabled" 160#define TR_PREFS_KEY_ALT_SPEED_UP_KBps "alt-speed-up" 161#define TR_PREFS_KEY_ALT_SPEED_DOWN_KBps "alt-speed-down" 162#define TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN "alt-speed-time-begin" 163#define TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED "alt-speed-time-enabled" 164#define TR_PREFS_KEY_ALT_SPEED_TIME_END "alt-speed-time-end" 165#define TR_PREFS_KEY_ALT_SPEED_TIME_DAY "alt-speed-time-day" 166#define TR_PREFS_KEY_BIND_ADDRESS_IPV4 "bind-address-ipv4" 167#define TR_PREFS_KEY_BIND_ADDRESS_IPV6 "bind-address-ipv6" 168#define TR_PREFS_KEY_BLOCKLIST_ENABLED "blocklist-enabled" 169#define TR_PREFS_KEY_BLOCKLIST_URL "blocklist-url" 170#define TR_PREFS_KEY_MAX_CACHE_SIZE_MB "cache-size-mb" 171#define TR_PREFS_KEY_DHT_ENABLED "dht-enabled" 172#define TR_PREFS_KEY_UTP_ENABLED "utp-enabled" 173#define TR_PREFS_KEY_LPD_ENABLED "lpd-enabled" 174#define TR_PREFS_KEY_DOWNLOAD_QUEUE_SIZE "download-queue-size" 175#define TR_PREFS_KEY_DOWNLOAD_QUEUE_ENABLED "download-queue-enabled" 176#define TR_PREFS_KEY_PREFETCH_ENABLED "prefetch-enabled" 177#define TR_PREFS_KEY_DOWNLOAD_DIR "download-dir" 178#define TR_PREFS_KEY_ENCRYPTION "encryption" 179#define TR_PREFS_KEY_IDLE_LIMIT "idle-seeding-limit" 180#define TR_PREFS_KEY_IDLE_LIMIT_ENABLED "idle-seeding-limit-enabled" 181#define TR_PREFS_KEY_INCOMPLETE_DIR "incomplete-dir" 182#define TR_PREFS_KEY_INCOMPLETE_DIR_ENABLED "incomplete-dir-enabled" 183#define TR_PREFS_KEY_MSGLEVEL "message-level" 184#define TR_PREFS_KEY_PEER_LIMIT_GLOBAL "peer-limit-global" 185#define TR_PREFS_KEY_PEER_LIMIT_TORRENT "peer-limit-per-torrent" 186#define TR_PREFS_KEY_PEER_PORT "peer-port" 187#define TR_PREFS_KEY_PEER_PORT_RANDOM_ON_START "peer-port-random-on-start" 188#define TR_PREFS_KEY_PEER_PORT_RANDOM_LOW "peer-port-random-low" 189#define TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH "peer-port-random-high" 190#define TR_PREFS_KEY_PEER_SOCKET_TOS "peer-socket-tos" 191#define TR_PREFS_KEY_PEER_CONGESTION_ALGORITHM "peer-congestion-algorithm" 192#define TR_PREFS_KEY_PEX_ENABLED "pex-enabled" 193#define TR_PREFS_KEY_PORT_FORWARDING "port-forwarding-enabled" 194#define TR_PREFS_KEY_PREALLOCATION "preallocation" 195#define TR_PREFS_KEY_RATIO "ratio-limit" 196#define TR_PREFS_KEY_RATIO_ENABLED "ratio-limit-enabled" 197#define TR_PREFS_KEY_RENAME_PARTIAL_FILES "rename-partial-files" 198#define TR_PREFS_KEY_RPC_AUTH_REQUIRED "rpc-authentication-required" 199#define TR_PREFS_KEY_RPC_BIND_ADDRESS "rpc-bind-address" 200#define TR_PREFS_KEY_RPC_ENABLED "rpc-enabled" 201#define TR_PREFS_KEY_RPC_PASSWORD "rpc-password" 202#define TR_PREFS_KEY_RPC_PORT "rpc-port" 203#define TR_PREFS_KEY_RPC_USERNAME "rpc-username" 204#define TR_PREFS_KEY_RPC_URL "rpc-url" 205#define TR_PREFS_KEY_RPC_WHITELIST_ENABLED "rpc-whitelist-enabled" 206#define TR_PREFS_KEY_SCRAPE_PAUSED_TORRENTS "scrape-paused-torrents-enabled" 207#define TR_PREFS_KEY_SCRIPT_TORRENT_DONE_FILENAME "script-torrent-done-filename" 208#define TR_PREFS_KEY_SCRIPT_TORRENT_DONE_ENABLED "script-torrent-done-enabled" 209#define TR_PREFS_KEY_SEED_QUEUE_SIZE "seed-queue-size" 210#define TR_PREFS_KEY_SEED_QUEUE_ENABLED "seed-queue-enabled" 211#define TR_PREFS_KEY_RPC_WHITELIST "rpc-whitelist" 212#define TR_PREFS_KEY_QUEUE_STALLED_ENABLED "queue-stalled-enabled" 213#define TR_PREFS_KEY_QUEUE_STALLED_MINUTES "queue-stalled-minutes" 214#define TR_PREFS_KEY_DSPEED_KBps "speed-limit-down" 215#define TR_PREFS_KEY_DSPEED_ENABLED "speed-limit-down-enabled" 216#define TR_PREFS_KEY_USPEED_KBps "speed-limit-up" 217#define TR_PREFS_KEY_USPEED_ENABLED "speed-limit-up-enabled" 218#define TR_PREFS_KEY_UMASK "umask" 219#define TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT "upload-slots-per-torrent" 220#define TR_PREFS_KEY_START "start-added-torrents" 221#define TR_PREFS_KEY_TRASH_ORIGINAL "trash-original-torrent-files" 222 223 224/** 225 * Add libtransmission's default settings to the benc dictionary. 226 * 227 * Example: 228 * @code 229 * tr_benc settings; 230 * int64_t i; 231 * 232 * tr_bencInitDict( &settings, 0 ); 233 * tr_sessionGetDefaultSettings( &settings ); 234 * if( tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT, &i ) ) 235 * fprintf( stderr, "the default peer port is %d\n", (int)i ); 236 * tr_bencFree( &settings ); 237 * @endcode 238 * 239 * @param initme pointer to a tr_benc dictionary 240 * @see tr_sessionLoadSettings() 241 * @see tr_sessionInit() 242 * @see tr_getDefaultConfigDir() 243 */ 244void tr_sessionGetDefaultSettings( struct tr_benc * dictionary ); 245 246/** 247 * Add the session's current configuration settings to the benc dictionary. 248 * 249 * FIXME: this probably belongs in libtransmissionapp 250 * 251 * @param session 252 * @param dictionary 253 * @see tr_sessionGetDefaultSettings() 254 */ 255void tr_sessionGetSettings( tr_session *, struct tr_benc * dictionary ); 256 257/** 258 * Load settings from the configuration directory's settings.json file, 259 * using libtransmission's default settings as fallbacks for missing keys. 260 * 261 * FIXME: this belongs in libtransmissionapp 262 * 263 * @param dictionary pointer to an uninitialized tr_benc 264 * @param configDir the configuration directory to find settings.json 265 * @param appName if configDir is empty, appName is used to find the default dir. 266 * @return success true if the settings were loaded, false otherwise 267 * @see tr_sessionGetDefaultSettings() 268 * @see tr_sessionInit() 269 * @see tr_sessionSaveSettings() 270 */ 271bool tr_sessionLoadSettings( struct tr_benc * dictionary, 272 const char * configDir, 273 const char * appName ); 274 275/** 276 * Add the session's configuration settings to the benc dictionary 277 * and save it to the configuration directory's settings.json file. 278 * 279 * FIXME: this belongs in libtransmissionapp 280 * 281 * @param session 282 * @param dictionary 283 * @see tr_sessionLoadSettings() 284 */ 285void tr_sessionSaveSettings( tr_session * session, 286 const char * configDir, 287 const struct tr_benc * dictonary ); 288 289/** 290 * @brief Initialize a libtransmission session. 291 * 292 * For example, this will instantiate a session with all the default values: 293 * @code 294 * tr_benc settings; 295 * tr_session * session; 296 * const char * configDir; 297 * 298 * tr_bencInitDict( &settings, 0 ); 299 * tr_sessionGetDefaultSettings( &settings ); 300 * configDir = tr_getDefaultConfigDir( "Transmission" ); 301 * session = tr_sessionInit( "mac", configDir, true, &settings ); 302 * 303 * tr_bencFree( &settings ); 304 * @endcode 305 * 306 * @param tag "gtk", "macosx", "daemon", etc... this is only for pre-1.30 resume files 307 * @param configDir where Transmission will look for resume files, blocklists, etc. 308 * @param messageQueueingEnabled if false, messages will be dumped to stderr 309 * @param settings libtransmission settings 310 * @see tr_sessionGetDefaultSettings() 311 * @see tr_sessionLoadSettings() 312 * @see tr_getDefaultConfigDir() 313 */ 314tr_session * tr_sessionInit( const char * tag, 315 const char * configDir, 316 bool messageQueueingEnabled, 317 struct tr_benc * settings ); 318 319/** @brief Update a session's settings from a benc dictionary 320 like to the one used in tr_sessionInit() */ 321void tr_sessionSet( tr_session * session, 322 struct tr_benc * settings ); 323 324/** @brief Rescan the blocklists directory and 325 reload whatever blocklist files are found there */ 326void tr_sessionReloadBlocklists( tr_session * session ); 327 328 329/** @brief End a libtransmission session 330 @see tr_sessionInit() */ 331void tr_sessionClose( tr_session * ); 332 333/** 334 * @brief Return the session's configuration directory. 335 * 336 * This is where transmission stores its .torrent files, .resume files, 337 * blocklists, etc. It's set in tr_transmissionInit() and is immutable 338 * during the session. 339 */ 340const char * tr_sessionGetConfigDir( const tr_session * ); 341 342/** 343 * @brief Set the per-session default download folder for new torrents. 344 * @see tr_sessionInit() 345 * @see tr_sessionGetDownloadDir() 346 * @see tr_ctorSetDownloadDir() 347 */ 348void tr_sessionSetDownloadDir( tr_session * session, const char * downloadDir ); 349 350/** 351 * @brief Get the default download folder for new torrents. 352 * 353 * This is set by tr_sessionInit() or tr_sessionSetDownloadDir(), 354 * and can be overridden on a per-torrent basis by tr_ctorSetDownloadDir(). 355 */ 356const char * tr_sessionGetDownloadDir( const tr_session * session ); 357 358/** 359 * @brief Get available disk space (in bytes) for the default download folder. 360 * @return zero or positive integer on success, -1 in case of error. 361 */ 362int64_t tr_sessionGetDownloadDirFreeSpace( const tr_session * session ); 363 364/** 365 * @brief Set the torrent's bandwidth priority. 366 */ 367void tr_ctorSetBandwidthPriority( tr_ctor * ctor, tr_priority_t priority ); 368 369/** 370 * @brief Get the torrent's bandwidth priority. 371 */ 372tr_priority_t tr_ctorGetBandwidthPriority( const tr_ctor * ctor ); 373 374 375/** 376 * @brief set the per-session incomplete download folder. 377 * 378 * When you add a new torrent and the session's incomplete directory is enabled, 379 * the new torrent will start downloading into that directory, and then be moved 380 * to tr_torrent.downloadDir when the torrent is finished downloading. 381 * 382 * Torrents aren't moved as a result of changing the session's incomplete dir -- 383 * it's applied to new torrents, not existing ones. 384 * 385 * tr_torrentSetLocation() overrules the incomplete dir: when a user specifies 386 * a new location, that becomes the torrent's new downloadDir and the torrent 387 * is moved there immediately regardless of whether or not it's complete. 388 * 389 * @see tr_sessionInit() 390 * @see tr_sessionGetIncompleteDir() 391 * @see tr_sessionSetIncompleteDirEnabled() 392 * @see tr_sessionGetIncompleteDirEnabled() 393 */ 394void tr_sessionSetIncompleteDir( tr_session * session, const char * dir ); 395 396/** @brief get the per-session incomplete download folder */ 397const char* tr_sessionGetIncompleteDir( const tr_session * session ); 398 399/** @brief enable or disable use of the incomplete download folder */ 400void tr_sessionSetIncompleteDirEnabled( tr_session * session, bool ); 401 402/** @brief get whether or not the incomplete download folder is enabled */ 403bool tr_sessionIsIncompleteDirEnabled( const tr_session * session ); 404 405 406/** 407 * @brief When enabled, newly-created files will have ".part" appended 408 * to their filename until the file is fully downloaded 409 * 410 * This is not retroactive -- toggling this will not rename existing files. 411 * It only applies to new files created by Transmission after this API call. 412 * 413 * @see tr_sessionIsIncompleteFileNamingEnabled() 414 */ 415void tr_sessionSetIncompleteFileNamingEnabled( tr_session * session, bool ); 416 417/** @brief return true if files will end in ".part" until they're complete */ 418bool tr_sessionIsIncompleteFileNamingEnabled( const tr_session * session ); 419 420/** 421 * @brief Set whether or not RPC calls are allowed in this session. 422 * 423 * @details If true, libtransmission will open a server socket to listen 424 * for incoming http RPC requests as described in docs/rpc-spec.txt. 425 * 426 * This is intially set by tr_sessionInit() and can be 427 * queried by tr_sessionIsRPCEnabled(). 428 */ 429void tr_sessionSetRPCEnabled( tr_session * session, 430 bool isEnabled ); 431 432/** @brief Get whether or not RPC calls are allowed in this session. 433 @see tr_sessionInit() 434 @see tr_sessionSetRPCEnabled() */ 435bool tr_sessionIsRPCEnabled( const tr_session * session ); 436 437/** @brief Specify which port to listen for RPC requests on. 438 @see tr_sessionInit() 439 @see tr_sessionGetRPCPort */ 440void tr_sessionSetRPCPort( tr_session * session, 441 tr_port port ); 442 443/** @brief Get which port to listen for RPC requests on. 444 @see tr_sessionInit() 445 @see tr_sessionSetRPCPort */ 446tr_port tr_sessionGetRPCPort( const tr_session * session ); 447 448/** 449 * @brief Specify which base URL to use. 450 * 451 * @detail The RPC API is accessible under <url>/rpc, the web interface under 452 * <url>/web. 453 * 454 * @see tr_sessionGetRPCUrl 455 */ 456void tr_sessionSetRPCUrl( tr_session * session, 457 const char * url ); 458 459/** 460 * @brief Get the base URL. 461 * @see tr_sessionInit() 462 * @see tr_sessionSetRPCUrl 463 */ 464const char* tr_sessionGetRPCUrl( const tr_session * session ); 465 466/** 467 * @brief Specify a whitelist for remote RPC access 468 * 469 * The whitelist is a comma-separated list of dotted-quad IP addresses 470 * to be allowed. Wildmat notation is supported, meaning that 471 * '?' is interpreted as a single-character wildcard and 472 * '*' is interprted as a multi-character wildcard. 473 */ 474void tr_sessionSetRPCWhitelist( tr_session * session, 475 const char * whitelist ); 476 477/** @brief get the Access Control List for allowing/denying RPC requests. 478 @return a comma-separated string of whitelist domains. 479 @see tr_sessionInit 480 @see tr_sessionSetRPCWhitelist */ 481const char* tr_sessionGetRPCWhitelist( const tr_session * ); 482 483void tr_sessionSetRPCWhitelistEnabled( tr_session * session, 484 bool isEnabled ); 485 486bool tr_sessionGetRPCWhitelistEnabled( const tr_session * session ); 487 488void tr_sessionSetRPCPassword( tr_session * session, 489 const char * password ); 490 491void tr_sessionSetRPCUsername( tr_session * session, 492 const char * username ); 493 494/** @brief get the password used to restrict RPC requests. 495 @return the password string. 496 @see tr_sessionInit() 497 @see tr_sessionSetRPCPassword() */ 498const char* tr_sessionGetRPCPassword( const tr_session * session ); 499 500const char* tr_sessionGetRPCUsername( const tr_session * session ); 501 502void tr_sessionSetRPCPasswordEnabled( tr_session * session, 503 bool isEnabled ); 504 505bool tr_sessionIsRPCPasswordEnabled( const tr_session * session ); 506 507const char* tr_sessionGetRPCBindAddress( const tr_session * session ); 508 509 510typedef enum 511{ 512 TR_RPC_TORRENT_ADDED, 513 TR_RPC_TORRENT_STARTED, 514 TR_RPC_TORRENT_STOPPED, 515 TR_RPC_TORRENT_REMOVING, 516 TR_RPC_TORRENT_TRASHING, /* _REMOVING + delete local data */ 517 TR_RPC_TORRENT_CHANGED, /* catch-all for the "torrent-set" rpc method */ 518 TR_RPC_TORRENT_MOVED, 519 TR_RPC_SESSION_CHANGED, 520 TR_RPC_SESSION_QUEUE_POSITIONS_CHANGED, /* catch potentially multiple torrents being moved in the queue */ 521 TR_RPC_SESSION_CLOSE 522} 523tr_rpc_callback_type; 524 525typedef enum 526{ 527 /* no special handling is needed by the caller */ 528 TR_RPC_OK = 0, 529 530 /* indicates to the caller that the client will take care of 531 * removing the torrent itself. For example the client may 532 * need to keep the torrent alive long enough to cleanly close 533 * some resources in another thread. */ 534 TR_RPC_NOREMOVE = ( 1 << 1 ) 535} 536tr_rpc_callback_status; 537 538typedef tr_rpc_callback_status (*tr_rpc_func)(tr_session * session, 539 tr_rpc_callback_type type, 540 struct tr_torrent * tor_or_null, 541 void * user_data ); 542 543/** 544 * Register to be notified whenever something is changed via RPC, 545 * such as a torrent being added, removed, started, stopped, etc. 546 * 547 * func is invoked FROM LIBTRANSMISSION'S THREAD! 548 * This means func must be fast (to avoid blocking peers), 549 * shouldn't call libtransmission functions (to avoid deadlock), 550 * and shouldn't modify client-level memory without using a mutex! 551 */ 552void tr_sessionSetRPCCallback( tr_session * session, 553 tr_rpc_func func, 554 void * user_data ); 555 556/** 557*** 558**/ 559 560/** @brief Used by tr_sessionGetStats() and tr_sessionGetCumulativeStats() */ 561typedef struct tr_session_stats 562{ 563 float ratio; /* TR_RATIO_INF, TR_RATIO_NA, or total up/down */ 564 uint64_t uploadedBytes; /* total up */ 565 uint64_t downloadedBytes; /* total down */ 566 uint64_t filesAdded; /* number of files added */ 567 uint64_t sessionCount; /* program started N times */ 568 uint64_t secondsActive; /* how long Transmisson's been running */ 569} 570tr_session_stats; 571 572/** @brief Get bandwidth use statistics for the current session */ 573void tr_sessionGetStats( const tr_session * session, 574 tr_session_stats * setme ); 575 576/** @brief Get cumulative bandwidth statistics for current and past sessions */ 577void tr_sessionGetCumulativeStats( const tr_session * session, 578 tr_session_stats * setme ); 579 580void tr_sessionClearStats( tr_session * session ); 581 582/** 583 * @brief Set whether or not torrents are allowed to do peer exchanges. 584 * 585 * PEX is always disabled in private torrents regardless of this. 586 * In public torrents, PEX is enabled by default. 587 */ 588void tr_sessionSetPexEnabled( tr_session * session, bool isEnabled ); 589bool tr_sessionIsPexEnabled( const tr_session * session ); 590 591bool tr_sessionIsDHTEnabled( const tr_session * session ); 592void tr_sessionSetDHTEnabled( tr_session * session, bool ); 593 594bool tr_sessionIsUTPEnabled( const tr_session * session ); 595void tr_sessionSetUTPEnabled( tr_session * session, bool ); 596 597bool tr_sessionIsLPDEnabled( const tr_session * session ); 598void tr_sessionSetLPDEnabled( tr_session * session, bool enabled ); 599 600void tr_sessionSetCacheLimit_MB( tr_session * session, int mb ); 601int tr_sessionGetCacheLimit_MB( const tr_session * session ); 602 603tr_encryption_mode tr_sessionGetEncryption( tr_session * session ); 604void tr_sessionSetEncryption( tr_session * session, 605 tr_encryption_mode mode ); 606 607 608/*********************************************************************** 609** Incoming Peer Connections Port 610*/ 611 612void tr_sessionSetPortForwardingEnabled( tr_session * session, 613 bool enabled ); 614 615bool tr_sessionIsPortForwardingEnabled( const tr_session * session ); 616 617void tr_sessionSetPeerPort( tr_session * session, 618 tr_port port); 619 620tr_port tr_sessionGetPeerPort( const tr_session * session ); 621 622tr_port tr_sessionSetPeerPortRandom( tr_session * session ); 623 624void tr_sessionSetPeerPortRandomOnStart( tr_session * session, bool random ); 625 626bool tr_sessionGetPeerPortRandomOnStart( tr_session * session ); 627 628typedef enum 629{ 630 TR_PORT_ERROR, 631 TR_PORT_UNMAPPED, 632 TR_PORT_UNMAPPING, 633 TR_PORT_MAPPING, 634 TR_PORT_MAPPED 635} 636tr_port_forwarding; 637 638tr_port_forwarding tr_sessionGetPortForwarding( const tr_session * session ); 639 640typedef enum 641{ 642 TR_CLIENT_TO_PEER = 0, TR_UP = 0, 643 TR_PEER_TO_CLIENT = 1, TR_DOWN = 1 644} 645tr_direction; 646 647/*** 648**** 649***/ 650 651/*** 652**** Primary session speed limits 653***/ 654 655void tr_sessionSetSpeedLimit_KBps ( tr_session *, tr_direction, unsigned int KBps ); 656unsigned int tr_sessionGetSpeedLimit_KBps ( const tr_session *, tr_direction ); 657 658void tr_sessionLimitSpeed ( tr_session *, tr_direction, bool ); 659bool tr_sessionIsSpeedLimited ( const tr_session *, tr_direction ); 660 661 662/*** 663**** Alternative speed limits that are used during scheduled times 664***/ 665 666void tr_sessionSetAltSpeed_KBps ( tr_session *, tr_direction, unsigned int Bps ); 667unsigned int tr_sessionGetAltSpeed_KBps ( const tr_session *, tr_direction ); 668 669void tr_sessionUseAltSpeed ( tr_session *, bool ); 670bool tr_sessionUsesAltSpeed ( const tr_session * ); 671 672void tr_sessionUseAltSpeedTime ( tr_session *, bool ); 673bool tr_sessionUsesAltSpeedTime ( const tr_session * ); 674 675void tr_sessionSetAltSpeedBegin ( tr_session *, int minsSinceMidnight ); 676int tr_sessionGetAltSpeedBegin ( const tr_session * ); 677 678void tr_sessionSetAltSpeedEnd ( tr_session *, int minsSinceMidnight ); 679int tr_sessionGetAltSpeedEnd ( const tr_session * ); 680 681typedef enum 682{ 683 TR_SCHED_SUN = (1<<0), 684 TR_SCHED_MON = (1<<1), 685 TR_SCHED_TUES = (1<<2), 686 TR_SCHED_WED = (1<<3), 687 TR_SCHED_THURS = (1<<4), 688 TR_SCHED_FRI = (1<<5), 689 TR_SCHED_SAT = (1<<6), 690 TR_SCHED_WEEKDAY = (TR_SCHED_MON|TR_SCHED_TUES|TR_SCHED_WED| 691 TR_SCHED_THURS|TR_SCHED_FRI), 692 TR_SCHED_WEEKEND = (TR_SCHED_SUN|TR_SCHED_SAT), 693 TR_SCHED_ALL = (TR_SCHED_WEEKDAY|TR_SCHED_WEEKEND) 694} 695tr_sched_day; 696 697void tr_sessionSetAltSpeedDay ( tr_session *, tr_sched_day day ); 698tr_sched_day tr_sessionGetAltSpeedDay ( const tr_session * ); 699 700typedef void ( tr_altSpeedFunc )( tr_session *, 701 bool active, 702 bool userDriven, 703 void * ); 704 705void tr_sessionClearAltSpeedFunc ( tr_session * ); 706void tr_sessionSetAltSpeedFunc ( tr_session *, tr_altSpeedFunc *, void * ); 707 708 709bool tr_sessionGetActiveSpeedLimit_KBps( const tr_session * session, 710 tr_direction dir, 711 double * setme ); 712 713/*** 714**** 715***/ 716 717double tr_sessionGetRawSpeed_KBps ( const tr_session *, tr_direction ); 718 719void tr_sessionSetRatioLimited ( tr_session *, bool isLimited ); 720bool tr_sessionIsRatioLimited ( const tr_session * ); 721 722void tr_sessionSetRatioLimit ( tr_session *, double desiredRatio ); 723double tr_sessionGetRatioLimit ( const tr_session * ); 724 725void tr_sessionSetIdleLimited ( tr_session *, bool isLimited ); 726bool tr_sessionIsIdleLimited ( const tr_session * ); 727 728void tr_sessionSetIdleLimit ( tr_session *, uint16_t idleMinutes ); 729uint16_t tr_sessionGetIdleLimit ( const tr_session * ); 730 731void tr_sessionSetPeerLimit( tr_session *, uint16_t maxGlobalPeers ); 732uint16_t tr_sessionGetPeerLimit( const tr_session * ); 733 734void tr_sessionSetPeerLimitPerTorrent( tr_session *, uint16_t maxPeers ); 735uint16_t tr_sessionGetPeerLimitPerTorrent( const tr_session * ); 736 737void tr_sessionSetPaused ( tr_session *, bool isPaused ); 738bool tr_sessionGetPaused ( const tr_session * ); 739 740void tr_sessionSetDeleteSource ( tr_session *, bool deleteSource ); 741bool tr_sessionGetDeleteSource ( const tr_session * ); 742 743tr_priority_t tr_torrentGetPriority( const tr_torrent * ); 744void tr_torrentSetPriority( tr_torrent *, tr_priority_t ); 745 746/*** 747**** 748**** Torrent Queueing 749**** 750**** There are independent queues for seeding (TR_UP) and leeching (TR_DOWN). 751**** 752**** If the session already has enough non-stalled seeds/leeches when 753**** tr_torrentStart() is called, the torrent will be moved into the 754**** appropriate queue and its state will be TR_STATUS_{DOWNLOAD,SEED}_WAIT. 755**** 756**** To bypass the queue and unconditionally start the torrent use 757**** tr_torrentStartNow(). 758**** 759**** Torrents can be moved in the queue using the simple functions 760**** tr_torrentQueueMove{Top,Up,Down,Bottom}. They can be moved to 761**** arbitrary points in the queue with tr_torrentSetQueuePosition(). 762**** 763***/ 764 765 766/** @brief Like tr_torrentStart(), but resumes right away regardless of the queues. */ 767void tr_torrentStartNow ( tr_torrent * ); 768 769/** @brief Return the queued torrent's position in the queue it's in. [0...n) */ 770int tr_torrentGetQueuePosition ( const tr_torrent * ); 771 772/** @brief Set the queued torrent's position in the queue it's in. 773 * Special cases: pos <= 0 moves to the front; pos >= queue length moves to the back */ 774void tr_torrentSetQueuePosition ( tr_torrent *, int queuePosition ); 775 776/** 777**/ 778 779/** @brief Convenience function for moving a batch of torrents to the front of their queue(s) */ 780void tr_torrentsQueueMoveTop ( tr_torrent ** torrents, int torrentCount ); 781 782/** @brief Convenience function for moving a batch of torrents ahead one step in their queue(s) */ 783void tr_torrentsQueueMoveUp ( tr_torrent ** torrents, int torrentCount ); 784 785/** @brief Convenience function for moving a batch of torrents back one step in their queue(s) */ 786void tr_torrentsQueueMoveDown ( tr_torrent ** torrents, int torrentCount ); 787 788/** @brief Convenience function for moving a batch of torrents to the back of their queue(s) */ 789void tr_torrentsQueueMoveBottom ( tr_torrent ** torrents, int torrentCount ); 790 791/** 792**/ 793 794/** @brief Set the number of torrents allowed to download (if direction is TR_DOWN) or seed (if direction is TR_UP) at the same time */ 795void tr_sessionSetQueueSize ( tr_session *, tr_direction, int max_simultaneous_seed_torrents ); 796 797/** @brief Return the number of torrents allowed to download (if direction is TR_DOWN) or seed (if direction is TR_UP) at the same time */ 798int tr_sessionGetQueueSize ( const tr_session *, tr_direction ); 799 800/** @brief Set whether or not to limit how many torrents can download (TR_DOWN) or seed (TR_UP) at the same time */ 801void tr_sessionSetQueueEnabled ( tr_session *, tr_direction, bool do_limit_simultaneous_seed_torrents ); 802 803/** @brief Return true if we're limiting how many torrents can concurrently download (TR_DOWN) or seed (TR_UP) at the same time */ 804bool tr_sessionGetQueueEnabled ( const tr_session *, tr_direction ); 805 806/** 807**/ 808 809/** @brief Consider torrent as 'stalled' when it's been inactive for N minutes. 810 Stalled torrents are left running but are not counted by tr_sessionGetQueueSize(). */ 811void tr_sessionSetQueueStalledMinutes( tr_session *, int minutes ); 812 813/** @return the number of minutes a torrent can be idle before being considered as stalled */ 814int tr_sessionGetQueueStalledMinutes( const tr_session * ); 815 816/** @brief Set whether or not to count torrents idle for over N minutes as 'stalled' */ 817void tr_sessionSetQueueStalledEnabled( tr_session *, bool ); 818 819/** @return true if we're torrents idle for over N minutes will be flagged as 'stalled' */ 820bool tr_sessionGetQueueStalledEnabled( const tr_session * ); 821 822/** 823**/ 824 825/** @brief Set a callback that is invoked when the queue starts a torrent */ 826void tr_torrentSetQueueStartCallback( tr_torrent * torrent, void (*callback)( tr_torrent *, void * ), void * user_data ); 827 828 829/*** 830**** 831**** 832***/ 833 834/** 835 * Load all the torrents in tr_getTorrentDir(). 836 * This can be used at startup to kickstart all the torrents 837 * from the previous session. 838 */ 839tr_torrent ** tr_sessionLoadTorrents( tr_session * session, 840 tr_ctor * ctor, 841 int * setmeCount ); 842 843/** 844*** 845**/ 846 847bool tr_sessionIsTorrentDoneScriptEnabled( const tr_session * ); 848 849void tr_sessionSetTorrentDoneScriptEnabled( tr_session *, bool isEnabled ); 850 851const char * tr_sessionGetTorrentDoneScript( const tr_session * ); 852 853void tr_sessionSetTorrentDoneScript( tr_session *, const char * scriptFilename ); 854 855 856/** @} */ 857 858/** 859*** 860**/ 861 862 863/*********************************************************************** 864** Message Logging 865*/ 866 867typedef enum 868{ 869 TR_MSG_ERR = 1, 870 TR_MSG_INF = 2, 871 TR_MSG_DBG = 3 872} 873tr_msg_level; 874 875void tr_setMessageLevel( tr_msg_level ); 876 877typedef struct tr_msg_list 878{ 879 /* TR_MSG_ERR, TR_MSG_INF, or TR_MSG_DBG */ 880 tr_msg_level level; 881 882 /* The line number in the source file where this message originated */ 883 int line; 884 885 /* Time the message was generated */ 886 time_t when; 887 888 /* The torrent associated with this message, 889 * or a module name such as "Port Forwarding" for non-torrent messages, 890 * or NULL. */ 891 char * name; 892 893 /* The message */ 894 char * message; 895 896 /* The source file where this message originated */ 897 const char * file; 898 899 /* linked list of messages */ 900 struct tr_msg_list * next; 901} 902tr_msg_list; 903 904void tr_setMessageQueuing( bool isEnabled ); 905 906bool tr_getMessageQueuing( void ); 907 908tr_msg_list * tr_getQueuedMessages( void ); 909 910void tr_freeMessageList( tr_msg_list * freeme ); 911 912/** @addtogroup Blocklists 913 @{ */ 914 915/** 916 * Specify a range of IPs for Transmission to block. 917 * 918 * Filename must be an uncompressed ascii file. 919 * 920 * libtransmission does not keep a handle to `filename' 921 * after this call returns, so the caller is free to 922 * keep or delete `filename' as it wishes. 923 * libtransmission makes its own copy of the file 924 * massaged into a binary format easier to search. 925 * 926 * The caller only needs to invoke this when the blocklist 927 * has changed. 928 * 929 * Passing NULL for a filename will clear the blocklist. 930 */ 931int tr_blocklistSetContent ( tr_session * session, 932 const char * filename ); 933 934int tr_blocklistGetRuleCount ( const tr_session * session ); 935 936bool tr_blocklistExists ( const tr_session * session ); 937 938bool tr_blocklistIsEnabled ( const tr_session * session ); 939 940void tr_blocklistSetEnabled ( tr_session * session, 941 bool isEnabled ); 942 943/** @brief The blocklist that ges updated when an RPC client 944 invokes the "blocklist-update" method */ 945void tr_blocklistSetURL ( tr_session *, const char * url ); 946 947const char * tr_blocklistGetURL ( const tr_session * ); 948 949/** @brief the file in the $config/blocklists/ directory that's 950 used by tr_blocklistSetContent() and "blocklist-update" */ 951#define DEFAULT_BLOCKLIST_FILENAME "blocklist.bin" 952 953/** @} */ 954 955 956/** @addtogroup tr_ctor Torrent Constructors 957 @{ 958 959 Instantiating a tr_torrent had gotten more complicated as features were 960 added. At one point there were four functions to check metainfo and five 961 to create a tr_torrent object. 962 963 To remedy this, a Torrent Constructor (struct tr_ctor) has been introduced: 964 - Simplifies the API to two functions: tr_torrentParse() and tr_torrentNew() 965 - You can set the fields you want; the system sets defaults for the rest. 966 - You can specify whether or not your fields should supercede resume's. 967 - We can add new features to tr_ctor without breaking tr_torrentNew()'s API. 968 969 All the tr_ctor{Get,Set}*() functions with a return value return 970 an error number, or zero if no error occurred. 971 972 You must call one of the SetMetainfo() functions before creating 973 a torrent with a tr_ctor. The other functions are optional. 974 975 You can reuse a single tr_ctor to create a batch of torrents -- 976 just call one of the SetMetainfo() functions between each 977 tr_torrentNew() call. 978 979 Every call to tr_ctorSetMetainfo*() frees the previous metainfo. 980 */ 981 982typedef enum 983{ 984 TR_FALLBACK, /* indicates the ctor value should be used only 985 in case of missing resume settings */ 986 987 TR_FORCE, /* indicates the ctor value should be used 988 regardless of what's in the resume settings */ 989} 990tr_ctorMode; 991 992struct tr_benc; 993 994/** @brief Create a torrent constructor object used to instantiate a tr_torrent 995 @param session the tr_session. This is required if you're going to call 996 tr_torrentNew(), but you can use NULL for tr_torrentParse(). 997 @see tr_torrentNew(), tr_torrentParse() */ 998tr_ctor* tr_ctorNew( const tr_session * session_or_NULL ); 999 1000/** @brief Free a torrent constructor object */ 1001void tr_ctorFree( tr_ctor * ctor ); 1002 1003/** @brief Set whether or not to delete the source .torrent file 1004 when the torrent is added. (Default: False) */ 1005void tr_ctorSetDeleteSource( tr_ctor * ctor, bool doDelete ); 1006 1007/** @brief Set the constructor's metainfo from a magnet link */ 1008int tr_ctorSetMetainfoFromMagnetLink( tr_ctor * ctor, const char * magnet ); 1009 1010/** @brief Set the constructor's metainfo from a raw benc already in memory */ 1011int tr_ctorSetMetainfo( tr_ctor * ctor, const uint8_t * metainfo, size_t len ); 1012 1013/** @brief Set the constructor's metainfo from a local .torrent file */ 1014int tr_ctorSetMetainfoFromFile( tr_ctor * ctor, const char * filename ); 1015 1016/** 1017 * @brief Set the metainfo from an existing file in tr_getTorrentDir(). 1018 * 1019 * This is used by the Mac client on startup to pick and choose which 1020 * torrents to load 1021 */ 1022int tr_ctorSetMetainfoFromHash( tr_ctor * ctor, const char * hashString ); 1023 1024/** @brief Set how many peers this torrent can connect to. (Default: 50) */ 1025void tr_ctorSetPeerLimit( tr_ctor * ctor, tr_ctorMode mode, uint16_t limit ); 1026 1027/** @brief Set the download folder for the torrent being added with this ctor. 1028 @see tr_ctorSetDownloadDir() 1029 @see tr_sessionInit() */ 1030void tr_ctorSetDownloadDir( tr_ctor * ctor, 1031 tr_ctorMode mode, 1032 const char * directory ); 1033 1034/** 1035 * @brief Set the incompleteDir for this torrent. 1036 * 1037 * This is not a supported API call. 1038 * It only exists so the mac client can migrate 1039 * its older incompleteDir settings, and that's 1040 * the only place where it should be used. 1041 */ 1042void tr_ctorSetIncompleteDir( tr_ctor * ctor, const char * directory ); 1043 1044/** Set whether or not the torrent begins downloading/seeding when created. 1045 (Default: not paused) */ 1046void tr_ctorSetPaused( tr_ctor * ctor, 1047 tr_ctorMode mode, 1048 bool isPaused ); 1049 1050/** @brief Set the priorities for files in a torrent */ 1051void tr_ctorSetFilePriorities( tr_ctor * ctor, 1052 const tr_file_index_t * files, 1053 tr_file_index_t fileCount, 1054 tr_priority_t priority ); 1055 1056/** @brief Set the download flag for files in a torrent */ 1057void tr_ctorSetFilesWanted( tr_ctor * ctor, 1058 const tr_file_index_t * fileIndices, 1059 tr_file_index_t fileCount, 1060 bool wanted ); 1061 1062 1063/** @brief Get this peer constructor's peer limit */ 1064int tr_ctorGetPeerLimit( const tr_ctor * ctor, 1065 tr_ctorMode mode, 1066 uint16_t * setmeCount ); 1067 1068/** @brief Get the "isPaused" flag from this peer constructor */ 1069int tr_ctorGetPaused( const tr_ctor * ctor, 1070 tr_ctorMode mode, 1071 bool * setmeIsPaused ); 1072 1073/** @brief Get the download path from this peer constructor */ 1074int tr_ctorGetDownloadDir( const tr_ctor * ctor, 1075 tr_ctorMode mode, 1076 const char ** setmeDownloadDir ); 1077 1078/** @brief Get the incomplete directory from this peer constructor */ 1079int tr_ctorGetIncompleteDir( const tr_ctor * ctor, 1080 const char ** setmeIncompleteDir ); 1081 1082/** @brief Get the metainfo from this peer constructor */ 1083int tr_ctorGetMetainfo( const tr_ctor * ctor, 1084 const struct tr_benc ** setme ); 1085 1086/** @brief Get the "delete .torrent file" flag from this peer constructor */ 1087int tr_ctorGetDeleteSource( const tr_ctor * ctor, 1088 bool * setmeDoDelete ); 1089 1090/** @brief Get the tr_session poiner from this peer constructor */ 1091tr_session* tr_ctorGetSession( const tr_ctor * ctor ); 1092 1093/** @brief Get the .torrent file that this ctor's metainfo came from, 1094 or NULL if tr_ctorSetMetainfoFromFile() wasn't used */ 1095const char* tr_ctorGetSourceFile( const tr_ctor * ctor ); 1096 1097typedef enum 1098{ 1099 TR_PARSE_OK, 1100 TR_PARSE_ERR, 1101 TR_PARSE_DUPLICATE 1102} 1103tr_parse_result; 1104 1105/** 1106 * @brief Parses the specified metainfo 1107 * 1108 * @return TR_PARSE_ERR if parsing failed; 1109 * TR_PARSE_OK if parsing succeeded and it's not a duplicate; 1110 * TR_PARSE_DUPLICATE if parsing succeeded but it's a duplicate. 1111 * 1112 * @param setme_info If parsing is successful and setme_info is non-NULL, 1113 * the parsed metainfo is stored there and sould be freed 1114 * by calling tr_metainfoFree() when no longer needed. 1115 * 1116 * Notes: 1117 * 1118 * 1. tr_torrentParse() won't be able to check for duplicates -- and therefore 1119 * won't return TR_PARSE_DUPLICATE -- unless ctor's "download-dir" and 1120 * session variable is set. 1121 * 1122 * 2. setme_info->torrent's value can't be set unless ctor's session variable 1123 * is set. 1124 */ 1125tr_parse_result tr_torrentParse( const tr_ctor * ctor, 1126 tr_info * setme_info_or_NULL ); 1127 1128/** @brief free a metainfo 1129 @see tr_torrentParse */ 1130void tr_metainfoFree( tr_info * inf ); 1131 1132 1133/** Instantiate a single torrent. 1134 @return 0 on success, 1135 TR_EINVALID if the torrent couldn't be parsed, or 1136 TR_EDUPLICATE if there's already a matching torrent object. */ 1137tr_torrent * tr_torrentNew( const tr_ctor * ctor, 1138 int * setmeError ); 1139 1140/** @} */ 1141 1142/*********************************************************************** 1143 *** 1144 *** TORRENTS 1145 **/ 1146 1147/** @addtogroup tr_torrent Torrents 1148 @{ */ 1149 1150/** @brief Frees memory allocated by tr_torrentNew(). 1151 Running torrents are stopped first. */ 1152void tr_torrentFree( tr_torrent * torrent ); 1153 1154typedef int tr_fileFunc( const char * filename ); 1155 1156/** @brief Removes our .torrent and .resume files for 1157 this torrent, then calls tr_torrentFree(). */ 1158void tr_torrentRemove( tr_torrent * torrent, 1159 bool removeLocalData, 1160 tr_fileFunc removeFunc ); 1161 1162/** @brief Start a torrent */ 1163void tr_torrentStart( tr_torrent * torrent ); 1164 1165/** @brief Stop (pause) a torrent */ 1166void tr_torrentStop( tr_torrent * torrent ); 1167 1168enum 1169{ 1170 TR_LOC_MOVING, 1171 TR_LOC_DONE, 1172 TR_LOC_ERROR 1173}; 1174 1175/** 1176 * @brief Tell transmsision where to find this torrent's local data. 1177 * 1178 * if move_from_previous_location is `true', the torrent's incompleteDir 1179 * will be clobberred s.t. additional files being added will be saved 1180 * to the torrent's downloadDir. 1181 */ 1182void tr_torrentSetLocation( tr_torrent * torrent, 1183 const char * location, 1184 bool move_from_previous_location, 1185 volatile double * setme_progress, 1186 volatile int * setme_state ); 1187 1188uint64_t tr_torrentGetBytesLeftToAllocate( const tr_torrent * torrent ); 1189 1190/** 1191 * @brief Returns this torrent's unique ID. 1192 * 1193 * IDs are good as simple lookup keys, but are not persistent 1194 * between sessions. If you need that, use tr_info.hash or 1195 * tr_info.hashString. 1196 */ 1197int tr_torrentId( const tr_torrent * torrent ); 1198 1199tr_torrent* tr_torrentFindFromId( tr_session * session, int id ); 1200 1201tr_torrent* tr_torrentFindFromHash( tr_session * session, 1202 const uint8_t * hash ); 1203 1204/** @brief Convenience function similar to tr_torrentFindFromHash() */ 1205tr_torrent* tr_torrentFindFromMagnetLink( tr_session * session, 1206 const char * link ); 1207 1208/** 1209 * @return this torrent's name. 1210 */ 1211const char* tr_torrentName( const tr_torrent * ); 1212 1213/** 1214 * @brief find the location of a torrent's file by looking with and without 1215 * the ".part" suffix, looking in downloadDir and incompleteDir, etc. 1216 * @return a newly-allocated string (that must be tr_freed() by the caller 1217 * when done) that gives the location of this file on disk, 1218 * or NULL if no file exists yet. 1219 * @param tor the torrent whose file we're looking for 1220 * @param fileNum the fileIndex, in [0...tr_info.fileCount) 1221 */ 1222char* tr_torrentFindFile( const tr_torrent * tor, tr_file_index_t fileNo ); 1223 1224 1225/*** 1226**** Torrent speed limits 1227**** 1228***/ 1229 1230void tr_torrentSetSpeedLimit_KBps ( tr_torrent *, tr_direction, unsigned int KBps ); 1231unsigned int tr_torrentGetSpeedLimit_KBps ( const tr_torrent *, tr_direction ); 1232 1233void tr_torrentUseSpeedLimit ( tr_torrent *, tr_direction, bool ); 1234bool tr_torrentUsesSpeedLimit ( const tr_torrent *, tr_direction ); 1235 1236void tr_torrentUseSessionLimits ( tr_torrent *, bool ); 1237bool tr_torrentUsesSessionLimits ( const tr_torrent * ); 1238 1239 1240/**** 1241***** Ratio Limits 1242****/ 1243 1244typedef enum 1245{ 1246 /* follow the global settings */ 1247 TR_RATIOLIMIT_GLOBAL = 0, 1248 1249 /* override the global settings, seeding until a certain ratio */ 1250 TR_RATIOLIMIT_SINGLE = 1, 1251 1252 /* override the global settings, seeding regardless of ratio */ 1253 TR_RATIOLIMIT_UNLIMITED = 2 1254} 1255tr_ratiolimit; 1256 1257void tr_torrentSetRatioMode( tr_torrent * tor, 1258 tr_ratiolimit mode ); 1259 1260tr_ratiolimit tr_torrentGetRatioMode( const tr_torrent * tor ); 1261 1262void tr_torrentSetRatioLimit( tr_torrent * tor, 1263 double ratio ); 1264 1265double tr_torrentGetRatioLimit( const tr_torrent * tor ); 1266 1267 1268bool tr_torrentGetSeedRatio( const tr_torrent *, double * ratio ); 1269 1270 1271/**** 1272***** Idle Time Limits 1273****/ 1274 1275typedef enum 1276{ 1277 /* follow the global settings */ 1278 TR_IDLELIMIT_GLOBAL = 0, 1279 1280 /* override the global settings, seeding until a certain idle time */ 1281 TR_IDLELIMIT_SINGLE = 1, 1282 1283 /* override the global settings, seeding regardless of activity */ 1284 TR_IDLELIMIT_UNLIMITED = 2 1285} 1286tr_idlelimit; 1287 1288void tr_torrentSetIdleMode ( tr_torrent * tor, 1289 tr_idlelimit mode ); 1290 1291tr_idlelimit tr_torrentGetIdleMode ( const tr_torrent * tor ); 1292 1293void tr_torrentSetIdleLimit( tr_torrent * tor, 1294 uint16_t idleMinutes ); 1295 1296uint16_t tr_torrentGetIdleLimit( const tr_torrent * tor ); 1297 1298 1299bool tr_torrentGetSeedIdle( const tr_torrent *, uint16_t * minutes ); 1300 1301/**** 1302***** Peer Limits 1303****/ 1304 1305void tr_torrentSetPeerLimit( tr_torrent * tor, uint16_t peerLimit ); 1306 1307uint16_t tr_torrentGetPeerLimit( const tr_torrent * tor ); 1308 1309/**** 1310***** File Priorities 1311****/ 1312 1313enum 1314{ 1315 TR_PRI_LOW = -1, 1316 TR_PRI_NORMAL = 0, /* since NORMAL is 0, memset initializes nicely */ 1317 TR_PRI_HIGH = 1 1318}; 1319 1320/** 1321 * @brief Set a batch of files to a particular priority. 1322 * 1323 * @param priority must be one of TR_PRI_NORMAL, _HIGH, or _LOW 1324 */ 1325void tr_torrentSetFilePriorities( tr_torrent * torrent, 1326 const tr_file_index_t * files, 1327 tr_file_index_t fileCount, 1328 tr_priority_t priority ); 1329 1330/** 1331 * @brief Get this torrent's file priorities. 1332 * 1333 * @return A malloc()ed array of tor->info.fileCount items, 1334 * each holding a TR_PRI_NORMAL, TR_PRI_HIGH, or TR_PRI_LOW. 1335 * It's the caller's responsibility to free() this. 1336 */ 1337tr_priority_t* tr_torrentGetFilePriorities( const tr_torrent * torrent ); 1338 1339/** @brief Set a batch of files to be downloaded or not. */ 1340void tr_torrentSetFileDLs( tr_torrent * torrent, 1341 const tr_file_index_t * files, 1342 tr_file_index_t fileCount, 1343 bool do_download ); 1344 1345 1346const tr_info * tr_torrentInfo( const tr_torrent * torrent ); 1347 1348/* Raw function to change the torrent's downloadDir field. 1349 This should only be used by libtransmission or to bootstrap 1350 a newly-instantiated tr_torrent object. */ 1351void tr_torrentSetDownloadDir( tr_torrent * torrent, const char * path ); 1352 1353const char * tr_torrentGetDownloadDir( const tr_torrent * torrent ); 1354 1355/** 1356 * Returns the root directory of where the torrent is. 1357 * 1358 * This will usually be the downloadDir. However if the torrent 1359 * has an incompleteDir enabled and hasn't finished downloading 1360 * yet, that will be returned instead. 1361 */ 1362const char * tr_torrentGetCurrentDir( const tr_torrent * tor ); 1363 1364 1365char* tr_torrentInfoGetMagnetLink( const tr_info * inf ); 1366 1367/** 1368 * Returns a newly-allocated string with a magnet link of the torrent. 1369 * Use tr_free() to free the string when done. 1370 */ 1371static inline 1372char* tr_torrentGetMagnetLink( const tr_torrent * tor ) 1373{ 1374 return tr_torrentInfoGetMagnetLink( tr_torrentInfo( tor ) ); 1375} 1376 1377/** 1378*** 1379**/ 1380 1381 1382/** @brief a part of tr_info that represents a single tracker */ 1383typedef struct tr_tracker_info 1384{ 1385 int tier; 1386 char * announce; 1387 char * scrape; 1388 uint32_t id; /* unique identifier used to match to a tr_tracker_stat */ 1389} 1390tr_tracker_info; 1391 1392/** 1393 * @brief Modify a torrent's tracker list. 1394 * 1395 * This updates both the `torrent' object's tracker list 1396 * and the metainfo file in tr_sessionGetConfigDir()'s torrent subdirectory. 1397 * 1398 * @param torrent The torrent whose tracker list is to be modified 1399 * @param trackers An array of trackers, sorted by tier from first to last. 1400 * NOTE: only the `tier' and `announce' fields are used. 1401 * libtransmission derives `scrape' from `announce' 1402 * and reassigns 'id'. 1403 * @param trackerCount size of the `trackers' array 1404 */ 1405bool 1406tr_torrentSetAnnounceList( tr_torrent * torrent, 1407 const tr_tracker_info * trackers, 1408 int trackerCount ); 1409 1410 1411/** 1412*** 1413**/ 1414 1415typedef enum 1416{ 1417 TR_LEECH, /* doesn't have all the desired pieces */ 1418 TR_SEED, /* has the entire torrent */ 1419 TR_PARTIAL_SEED /* has the desired pieces, but not the entire torrent */ 1420} 1421tr_completeness; 1422 1423/** 1424 * @param wasRunning whether or not the torrent was running when 1425 * it changed its completeness state 1426 */ 1427typedef void ( tr_torrent_completeness_func )( tr_torrent * torrent, 1428 tr_completeness completeness, 1429 bool wasRunning, 1430 void * user_data ); 1431 1432typedef void ( tr_torrent_ratio_limit_hit_func )( tr_torrent * torrent, 1433 void * user_data ); 1434 1435typedef void ( tr_torrent_idle_limit_hit_func )( tr_torrent * torrent, 1436 void * user_data ); 1437 1438 1439/** 1440 * Register to be notified whenever a torrent's "completeness" 1441 * changes. This will be called, for example, when a torrent 1442 * finishes downloading and changes from TR_LEECH to 1443 * either TR_SEED or TR_PARTIAL_SEED. 1444 * 1445 * func is invoked FROM LIBTRANSMISSION'S THREAD! 1446 * This means func must be fast (to avoid blocking peers), 1447 * shouldn't call libtransmission functions (to avoid deadlock), 1448 * and shouldn't modify client-level memory without using a mutex! 1449 * 1450 * @see tr_completeness 1451 */ 1452void tr_torrentSetCompletenessCallback( 1453 tr_torrent * torrent, 1454 tr_torrent_completeness_func func, 1455 void * user_data ); 1456 1457void tr_torrentClearCompletenessCallback( tr_torrent * torrent ); 1458 1459 1460 1461typedef void ( tr_torrent_metadata_func )( tr_torrent * torrent, 1462 void * user_data ); 1463/** 1464 * Register to be notified whenever a torrent changes from 1465 * having incomplete metadata to having complete metadata. 1466 * This happens when a magnet link finishes downloading 1467 * metadata from its peers. 1468 */ 1469void tr_torrentSetMetadataCallback ( 1470 tr_torrent * tor, 1471 tr_torrent_metadata_func func, 1472 void * user_data ); 1473 1474/** 1475 * Register to be notified whenever a torrent's ratio limit 1476 * has been hit. This will be called when the torrent's 1477 * ul/dl ratio has met or exceeded the designated ratio limit. 1478 * 1479 * Has the same restrictions as tr_torrentSetCompletenessCallback 1480 */ 1481void tr_torrentSetRatioLimitHitCallback( 1482 tr_torrent * torrent, 1483 tr_torrent_ratio_limit_hit_func func, 1484 void * user_data ); 1485 1486void tr_torrentClearRatioLimitHitCallback( tr_torrent * torrent ); 1487 1488/** 1489 * Register to be notified whenever a torrent's idle limit 1490 * has been hit. This will be called when the seeding torrent's 1491 * idle time has met or exceeded the designated idle limit. 1492 * 1493 * Has the same restrictions as tr_torrentSetCompletenessCallback 1494 */ 1495void tr_torrentSetIdleLimitHitCallback( 1496 tr_torrent * torrent, 1497 tr_torrent_idle_limit_hit_func func, 1498 void * user_data ); 1499 1500void tr_torrentClearIdleLimitHitCallback( tr_torrent * torrent ); 1501 1502 1503/** 1504 * MANUAL ANNOUNCE 1505 * 1506 * Trackers usually set an announce interval of 15 or 30 minutes. 1507 * Users can send one-time announce requests that override this 1508 * interval by calling tr_torrentManualUpdate(). 1509 * 1510 * The wait interval for tr_torrentManualUpdate() is much smaller. 1511 * You can test whether or not a manual update is possible 1512 * (for example, to desensitize the button) by calling 1513 * tr_torrentCanManualUpdate(). 1514 */ 1515 1516void tr_torrentManualUpdate( tr_torrent * torrent ); 1517 1518bool tr_torrentCanManualUpdate( const tr_torrent * torrent ); 1519 1520/*** 1521**** tr_peer_stat 1522***/ 1523 1524typedef struct tr_peer_stat 1525{ 1526 bool isUTP; 1527 1528 bool isEncrypted; 1529 bool isDownloadingFrom; 1530 bool isUploadingTo; 1531 bool isSeed; 1532 1533 bool peerIsChoked; 1534 bool peerIsInterested; 1535 bool clientIsChoked; 1536 bool clientIsInterested; 1537 bool isIncoming; 1538 1539 uint8_t from; 1540 tr_port port; 1541 1542 char addr[TR_INET6_ADDRSTRLEN]; 1543 char client[80]; 1544 char flagStr[32]; 1545 1546 float progress; 1547 double rateToPeer_KBps; 1548 double rateToClient_KBps; 1549 1550 1551/*** 1552**** THESE NEXT FOUR FIELDS ARE EXPERIMENTAL. 1553**** Don't rely on them; they'll probably go away 1554***/ 1555 /* how many blocks we've sent to this peer in the last 120 seconds */ 1556 uint32_t blocksToPeer; 1557 /* how many blocks this client's sent to us in the last 120 seconds */ 1558 uint32_t blocksToClient; 1559 /* how many requests to this peer that we've cancelled in the last 120 seconds */ 1560 uint32_t cancelsToPeer; 1561 /* how many requests this peer made of us, then cancelled, in the last 120 seconds */ 1562 uint32_t cancelsToClient; 1563 1564 /* how many requests the peer has made that we haven't responded to yet */ 1565 int pendingReqsToClient; 1566 1567 /* how many requests we've made and are currently awaiting a response for */ 1568 int pendingReqsToPeer; 1569} 1570tr_peer_stat; 1571 1572tr_peer_stat * tr_torrentPeers( const tr_torrent * torrent, 1573 int * peerCount ); 1574 1575void tr_torrentPeersFree( tr_peer_stat * peerStats, 1576 int peerCount ); 1577 1578/*** 1579**** tr_tracker_stat 1580***/ 1581 1582typedef enum 1583{ 1584 /* we won't (announce,scrape) this torrent to this tracker because 1585 * the torrent is stopped, or because of an error, or whatever */ 1586 TR_TRACKER_INACTIVE = 0, 1587 1588 /* we will (announce,scrape) this torrent to this tracker, and are 1589 * waiting for enough time to pass to satisfy the tracker's interval */ 1590 TR_TRACKER_WAITING = 1, 1591 1592 /* it's time to (announce,scrape) this torrent, and we're waiting on a 1593 * a free slot to open up in the announce manager */ 1594 TR_TRACKER_QUEUED = 2, 1595 1596 /* we're (announcing,scraping) this torrent right now */ 1597 TR_TRACKER_ACTIVE = 3 1598} 1599tr_tracker_state; 1600 1601typedef struct 1602{ 1603 /* how many downloads this tracker knows of (-1 means it does not know) */ 1604 int downloadCount; 1605 1606 /* whether or not we've ever sent this tracker an announcement */ 1607 bool hasAnnounced; 1608 1609 /* whether or not we've ever scraped to this tracker */ 1610 bool hasScraped; 1611 1612 /* human-readable string identifying the tracker */ 1613 char host[1024]; 1614 1615 /* the full announce URL */ 1616 char announce[1024]; 1617 1618 /* the full scrape URL */ 1619 char scrape[1024]; 1620 1621 /* Transmission uses one tracker per tier, 1622 * and the others are kept as backups */ 1623 bool isBackup; 1624 1625 /* is the tracker announcing, waiting, queued, etc */ 1626 tr_tracker_state announceState; 1627 1628 /* is the tracker scraping, waiting, queued, etc */ 1629 tr_tracker_state scrapeState; 1630 1631 /* number of peers the tracker told us about last time. 1632 * if "lastAnnounceSucceeded" is false, this field is undefined */ 1633 int lastAnnouncePeerCount; 1634 1635 /* human-readable string with the result of the last announce. 1636 if "hasAnnounced" is false, this field is undefined */ 1637 char lastAnnounceResult[128]; 1638 1639 /* when the last announce was sent to the tracker. 1640 * if "hasAnnounced" is false, this field is undefined */ 1641 time_t lastAnnounceStartTime; 1642 1643 /* whether or not the last announce was a success. 1644 if "hasAnnounced" is false, this field is undefined */ 1645 bool lastAnnounceSucceeded; 1646 1647 /* whether or not the last announce timed out. */ 1648 bool lastAnnounceTimedOut; 1649 1650 /* when the last announce was completed. 1651 if "hasAnnounced" is false, this field is undefined */ 1652 time_t lastAnnounceTime; 1653 1654 /* human-readable string with the result of the last scrape. 1655 * if "hasScraped" is false, this field is undefined */ 1656 char lastScrapeResult[128]; 1657 1658 /* when the last scrape was sent to the tracker. 1659 * if "hasScraped" is false, this field is undefined */ 1660 time_t lastScrapeStartTime; 1661 1662 /* whether or not the last scrape was a success. 1663 if "hasAnnounced" is false, this field is undefined */ 1664 bool lastScrapeSucceeded; 1665 1666 /* whether or not the last scrape timed out. */ 1667 bool lastScrapeTimedOut; 1668 1669 /* when the last scrape was completed. 1670 if "hasScraped" is false, this field is undefined */ 1671 time_t lastScrapeTime; 1672 1673 /* number of leechers this tracker knows of (-1 means it does not know) */ 1674 int leecherCount; 1675 1676 /* when the next periodic announce message will be sent out. 1677 if announceState isn't TR_TRACKER_WAITING, this field is undefined */ 1678 time_t nextAnnounceTime; 1679 1680 /* when the next periodic scrape message will be sent out. 1681 if scrapeState isn't TR_TRACKER_WAITING, this field is undefined */ 1682 time_t nextScrapeTime; 1683 1684 /* number of seeders this tracker knows of (-1 means it does not know) */ 1685 int seederCount; 1686 1687 /* which tier this tracker is in */ 1688 int tier; 1689 1690 /* used to match to a tr_tracker_info */ 1691 uint32_t id; 1692} 1693tr_tracker_stat; 1694 1695tr_tracker_stat * tr_torrentTrackers( const tr_torrent * torrent, 1696 int * setmeTrackerCount ); 1697 1698void tr_torrentTrackersFree( tr_tracker_stat * trackerStats, 1699 int trackerCount ); 1700 1701 1702 1703/** 1704 * @brief get the download speeds for each of this torrent's webseed sources. 1705 * 1706 * @return an array of tor->info.webseedCount floats giving download speeds. 1707 * Each speed in the array corresponds to the webseed at the same 1708 * array index in tor->info.webseeds. 1709 * To differentiate "idle" and "stalled" status, idle webseeds will 1710 * return -1 instead of 0 KiB/s. 1711 * NOTE: always free this array with tr_free() when you're done with it. 1712 */ 1713double* tr_torrentWebSpeeds_KBps( const tr_torrent * torrent ); 1714 1715typedef struct tr_file_stat 1716{ 1717 uint64_t bytesCompleted; 1718 float progress; 1719} 1720tr_file_stat; 1721 1722tr_file_stat * tr_torrentFiles( const tr_torrent * torrent, 1723 tr_file_index_t * fileCount ); 1724 1725void tr_torrentFilesFree( tr_file_stat * files, 1726 tr_file_index_t fileCount ); 1727 1728 1729/*********************************************************************** 1730 * tr_torrentAvailability 1731 *********************************************************************** 1732 * Use this to draw an advanced progress bar which is 'size' pixels 1733 * wide. Fills 'tab' which you must have allocated: each byte is set 1734 * to either -1 if we have the piece, otherwise it is set to the number 1735 * of connected peers who have the piece. 1736 **********************************************************************/ 1737void tr_torrentAvailability( const tr_torrent * torrent, 1738 int8_t * tab, 1739 int size ); 1740 1741void tr_torrentAmountFinished( const tr_torrent * torrent, 1742 float * tab, 1743 int size ); 1744 1745void tr_torrentVerify( tr_torrent * torrent ); 1746 1747/*********************************************************************** 1748 * tr_info 1749 **********************************************************************/ 1750 1751/** @brief a part of tr_info that represents a single file of the torrent's content */ 1752typedef struct tr_file 1753{ 1754 uint64_t length; /* Length of the file, in bytes */ 1755 char * name; /* Path to the file */ 1756 int8_t priority; /* TR_PRI_HIGH, _NORMAL, or _LOW */ 1757 int8_t dnd; /* "do not download" flag */ 1758 tr_piece_index_t firstPiece; /* We need pieces [firstPiece... */ 1759 tr_piece_index_t lastPiece; /* ...lastPiece] to dl this file */ 1760 uint64_t offset; /* file begins at the torrent's nth byte */ 1761} 1762tr_file; 1763 1764/** @brief a part of tr_info that represents a single piece of the torrent's content */ 1765typedef struct tr_piece 1766{ 1767 time_t timeChecked; /* the last time we tested this piece */ 1768 uint8_t hash[SHA_DIGEST_LENGTH]; /* pieces hash */ 1769 int8_t priority; /* TR_PRI_HIGH, _NORMAL, or _LOW */ 1770 int8_t dnd; /* "do not download" flag */ 1771} 1772tr_piece; 1773 1774/** @brief information about a torrent that comes from its metainfo file */ 1775struct tr_info 1776{ 1777 /* total size of the torrent, in bytes */ 1778 uint64_t totalSize; 1779 1780 /* the torrent's name */ 1781 char * name; 1782 1783 /* Path to torrent Transmission's internal copy of the .torrent file. */ 1784 char * torrent; 1785 1786 char ** webseeds; 1787 1788 char * comment; 1789 char * creator; 1790 tr_file * files; 1791 tr_piece * pieces; 1792 1793 /* these trackers are sorted by tier */ 1794 tr_tracker_info * trackers; 1795 1796 /* Torrent info */ 1797 time_t dateCreated; 1798 1799 int trackerCount; 1800 int webseedCount; 1801 tr_file_index_t fileCount; 1802 uint32_t pieceSize; 1803 tr_piece_index_t pieceCount; 1804 1805 /* General info */ 1806 uint8_t hash[SHA_DIGEST_LENGTH]; 1807 char hashString[2 * SHA_DIGEST_LENGTH + 1]; 1808 1809 /* Flags */ 1810 bool isPrivate; 1811 bool isMultifile; 1812}; 1813 1814static inline bool tr_torrentHasMetadata( const tr_torrent * tor ) 1815{ 1816 return tr_torrentInfo( tor )->fileCount > 0; 1817} 1818 1819/** 1820 * What the torrent is doing right now. 1821 * 1822 * Note: these values will become a straight enum at some point in the future. 1823 * Do not rely on their current `bitfield' implementation 1824 */ 1825typedef enum 1826{ 1827 TR_STATUS_STOPPED = 0, /* Torrent is stopped */ 1828 TR_STATUS_CHECK_WAIT = 1, /* Queued to check files */ 1829 TR_STATUS_CHECK = 2, /* Checking files */ 1830 TR_STATUS_DOWNLOAD_WAIT = 3, /* Queued to download */ 1831 TR_STATUS_DOWNLOAD = 4, /* Downloading */ 1832 TR_STATUS_SEED_WAIT = 5, /* Queued to seed */ 1833 TR_STATUS_SEED = 6 /* Seeding */ 1834} 1835tr_torrent_activity; 1836 1837enum 1838{ 1839 TR_PEER_FROM_INCOMING = 0, /* connections made to the listening port */ 1840 TR_PEER_FROM_LPD, /* peers found by local announcements */ 1841 TR_PEER_FROM_TRACKER, /* peers found from a tracker */ 1842 TR_PEER_FROM_DHT, /* peers found from the DHT */ 1843 TR_PEER_FROM_PEX, /* peers found from PEX */ 1844 TR_PEER_FROM_RESUME, /* peers found in the .resume file */ 1845 TR_PEER_FROM_LTEP, /* peer address provided in an LTEP handshake */ 1846 TR_PEER_FROM__MAX 1847}; 1848 1849typedef enum 1850{ 1851 /* everything's fine */ 1852 TR_STAT_OK = 0, 1853 1854 /* when we anounced to the tracker, we got a warning in the response */ 1855 TR_STAT_TRACKER_WARNING = 1, 1856 1857 /* when we anounced to the tracker, we got an error in the response */ 1858 TR_STAT_TRACKER_ERROR = 2, 1859 1860 /* local trouble, such as disk full or permissions error */ 1861 TR_STAT_LOCAL_ERROR = 3 1862} 1863tr_stat_errtype; 1864 1865/** @brief Used by tr_torrentStat() to tell clients about a torrent's state and statistics */ 1866typedef struct tr_stat 1867{ 1868 /** The torrent's unique Id. 1869 @see tr_torrentId() */ 1870 int id; 1871 1872 /** What is this torrent doing right now? */ 1873 tr_torrent_activity activity; 1874 1875 /** Defines what kind of text is in errorString. 1876 @see errorString */ 1877 tr_stat_errtype error; 1878 1879 /** A warning or error message regarding the torrent. 1880 @see error */ 1881 char errorString[512]; 1882 1883 /** When tr_stat.activity is TR_STATUS_CHECK or TR_STATUS_CHECK_WAIT, 1884 this is the percentage of how much of the files has been 1885 verified. When it gets to 1, the verify process is done. 1886 Range is [0..1] 1887 @see tr_stat.activity */ 1888 float recheckProgress; 1889 1890 /** How much has been downloaded of the entire torrent. 1891 Range is [0..1] */ 1892 float percentComplete; 1893 1894 /** How much of the metadata the torrent has. 1895 For torrents added from a .torrent this will always be 1. 1896 For magnet links, this number will from from 0 to 1 as the metadata is downloaded. 1897 Range is [0..1] */ 1898 float metadataPercentComplete; 1899 1900 /** How much has been downloaded of the files the user wants. This differs 1901 from percentComplete if the user wants only some of the torrent's files. 1902 Range is [0..1] 1903 @see tr_stat.leftUntilDone */ 1904 float percentDone; 1905 1906 /** How much has been uploaded to satisfy the seed ratio. 1907 This is 1 if the ratio is reached or the torrent is set to seed forever. 1908 Range is [0..1] */ 1909 float seedRatioPercentDone; 1910 1911 /** Speed all data being sent for this torrent. 1912 This includes piece data, protocol messages, and TCP overhead */ 1913 float rawUploadSpeed_KBps; 1914 1915 /** Speed all data being received for this torrent. 1916 This includes piece data, protocol messages, and TCP overhead */ 1917 float rawDownloadSpeed_KBps; 1918 1919 /** Speed all piece being sent for this torrent. 1920 This ONLY counts piece data. */ 1921 float pieceUploadSpeed_KBps; 1922 1923 /** Speed all piece being received for this torrent. 1924 This ONLY counts piece data. */ 1925 float pieceDownloadSpeed_KBps; 1926 1927#define TR_ETA_NOT_AVAIL -1 1928#define TR_ETA_UNKNOWN -2 1929 /** If downloading, estimated number of seconds left until the torrent is done. 1930 If seeding, estimated number of seconds left until seed ratio is reached. */ 1931 int eta; 1932 /** If seeding, number of seconds left until the idle time limit is reached. */ 1933 int etaIdle; 1934 1935 /** Number of peers that we're connected to */ 1936 int peersConnected; 1937 1938 /** How many peers we found out about from the tracker, or from pex, 1939 or from incoming connections, or from our resume file. */ 1940 int peersFrom[TR_PEER_FROM__MAX]; 1941 1942 /** Number of peers that are sending data to us. */ 1943 int peersSendingToUs; 1944 1945 /** Number of peers that we're sending data to */ 1946 int peersGettingFromUs; 1947 1948 /** Number of webseeds that are sending data to us. */ 1949 int webseedsSendingToUs; 1950 1951 /** Byte count of all the piece data we'll have downloaded when we're done, 1952 whether or not we have it yet. This may be less than tr_info.totalSize 1953 if only some of the torrent's files are wanted. 1954 [0...tr_info.totalSize] */ 1955 uint64_t sizeWhenDone; 1956 1957 /** Byte count of how much data is left to be downloaded until we've got 1958 all the pieces that we want. [0...tr_info.sizeWhenDone] */ 1959 uint64_t leftUntilDone; 1960 1961 /** Byte count of all the piece data we want and don't have yet, 1962 but that a connected peer does have. [0...leftUntilDone] */ 1963 uint64_t desiredAvailable; 1964 1965 /** Byte count of all the corrupt data you've ever downloaded for 1966 this torrent. If you're on a poisoned torrent, this number can 1967 grow very large. */ 1968 uint64_t corruptEver; 1969 1970 /** Byte count of all data you've ever uploaded for this torrent. */ 1971 uint64_t uploadedEver; 1972 1973 /** Byte count of all the non-corrupt data you've ever downloaded 1974 for this torrent. If you deleted the files and downloaded a second 1975 time, this will be 2*totalSize.. */ 1976 uint64_t downloadedEver; 1977 1978 /** Byte count of all the checksum-verified data we have for this torrent. 1979 */ 1980 uint64_t haveValid; 1981 1982 /** Byte count of all the partial piece data we have for this torrent. 1983 As pieces become complete, this value may decrease as portions of it 1984 are moved to `corrupt' or `haveValid'. */ 1985 uint64_t haveUnchecked; 1986 1987 /** time when one or more of the torrent's trackers will 1988 allow you to manually ask for more peers, 1989 or 0 if you can't */ 1990 time_t manualAnnounceTime; 1991 1992#define TR_RATIO_NA -1 1993#define TR_RATIO_INF -2 1994 /** TR_RATIO_INF, TR_RATIO_NA, or a regular ratio */ 1995 float ratio; 1996 1997 /** When the torrent was first added. */ 1998 time_t addedDate; 1999 2000 /** When the torrent finished downloading. */ 2001 time_t doneDate; 2002 2003 /** When the torrent was last started. */ 2004 time_t startDate; 2005 2006 /** The last time we uploaded or downloaded piece data on this torrent. */ 2007 time_t activityDate; 2008 2009 /** Number of seconds since the last activity (or since started). 2010 -1 if activity is not seeding or downloading. */ 2011 int idleSecs; 2012 2013 /** Cumulative seconds the torrent's ever spent downloading */ 2014 int secondsDownloading; 2015 2016 /** Cumulative seconds the torrent's ever spent seeding */ 2017 int secondsSeeding; 2018 2019 /** A torrent is considered finished if it has met its seed ratio. 2020 As a result, only paused torrents can be finished. */ 2021 bool finished; 2022 2023 /** This torrent's queue position. 2024 All torrents have a queue position, even if it's not queued. */ 2025 int queuePosition; 2026 2027 /** True if the torrent is running, but has been idle for long enough 2028 to be considered stalled. @see tr_sessionGetQueueStalledMinutes() */ 2029 bool isStalled; 2030} 2031tr_stat; 2032 2033/** Return a pointer to an tr_stat structure with updated information 2034 on the torrent. This is typically called by the GUI clients every 2035 second or so to get a new snapshot of the torrent's status. */ 2036const tr_stat * tr_torrentStat( tr_torrent * torrent ); 2037 2038/** Like tr_torrentStat(), but only recalculates the statistics if it's 2039 been longer than a second since they were last calculated. This can 2040 reduce the CPU load if you're calling tr_torrentStat() frequently. */ 2041const tr_stat * tr_torrentStatCached( tr_torrent * torrent ); 2042 2043/** @deprecated */ 2044void tr_torrentSetAddedDate( tr_torrent * torrent, 2045 time_t addedDate ); 2046 2047/** @deprecated */ 2048void tr_torrentSetActivityDate( tr_torrent * torrent, 2049 time_t activityDate ); 2050 2051/** @deprecated */ 2052void tr_torrentSetDoneDate( tr_torrent * torrent, time_t doneDate ); 2053 2054/** @} */ 2055 2056/** @brief Sanity checker to test that the direction is TR_UP or TR_DOWN */ 2057static inline bool tr_isDirection( tr_direction d ) { return d==TR_UP || d==TR_DOWN; } 2058 2059/** @brief Sanity checker to test that a bool is true or false */ 2060static inline bool tr_isBool( bool b ) { return b==1 || b==0; } 2061 2062#ifdef __cplusplus 2063} 2064#endif 2065 2066#endif 2067