source: trunk/libtransmission/transmission.h @ 12514

Last change on this file since 12514 was 12514, checked in by jordan, 10 years ago

(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.

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