Merge branch 'master' into rmintltool

This commit is contained in:
Mike Gelfand 2019-02-24 21:52:09 +03:00 committed by GitHub
commit dab4857f90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
510 changed files with 5406 additions and 9230 deletions

View File

@ -5,5 +5,6 @@
"indent_with_tabs": false,
"preserve_newlines": true,
"max_preserve_newlines": 2,
"end_with_newline": true,
"jslint_happy": true
}

View File

@ -44,8 +44,8 @@ set(TR_NAME ${PROJECT_NAME})
# "Z" for unsupported trunk builds,
# "0" for stable, supported releases
# these should be the only two lines you need to change
set(TR_USER_AGENT_PREFIX "2.93+")
set(TR_PEER_ID_PREFIX "-TR293Z-")
set(TR_USER_AGENT_PREFIX "2.94+")
set(TR_PEER_ID_PREFIX "-TR294Z-")
string(REGEX MATCH "^([0-9]+)\\.([0-9]+).*" TR_VERSION "${TR_USER_AGENT_PREFIX}")
set(TR_VERSION_MAJOR "${CMAKE_MATCH_1}")

View File

@ -1,4 +1,4 @@
Copyright 2005-2016. All code is copyrighted by the respective authors.
Copyright 2005-2019. All code is copyrighted by the respective authors.
Transmission can be redistributed and/or modified under the terms of
the GNU GPLv2 (http://www.gnu.org/licenses/license-list.html#GPLv2),

25
NEWS
View File

@ -1,4 +1,27 @@
=== Transmission 2.93 (2018/01/xx) ===
=== Transmission 3.00 (2019/mm/dd) ===
[https://github.com/transmission/transmission/releases/tag/3.00]
==== All Platforms ====
==== OS X Client Client ====
* Dark Mode support
* Sparkle updated to 1.21.2
* Minimum OS version updated to 10.10
==== Qt Client ====
==== Web Client ====
=== Transmission 2.94 (2018/05/01) ===
[https://github.com/transmission/transmission/releases/tag/2.94 All tickets closed by this release]
==== All Platforms ====
* Fix building against LibreSSL (#284, #486, #570)
* Fix building against mbedTLS (#115, #528)
* Fix torrents ETA calculation (#522)
* Fix cross-compilation issues caused by miniupnpc configuration test (#475)
==== Qt Client ====
* Fix bad downloaded percentage in DetailsDialog (#547)
==== Web Client ====
* Fix tracker error XSS in inspector (CVE pending)
* Fix torrent name HTML-escaping in trackers inspector tab
=== Transmission 2.93 (2018/01/23) ===
[https://github.com/transmission/transmission/releases/tag/2.93 All tickets closed by this release]
==== All Platforms ====
* Fix CVE-2018-5702 (#468)

View File

@ -29,6 +29,7 @@ For a more detailed description, and dependencies, visit: https://github.com/tra
$ tar xf transmission-2.92.tar.xz
$ cd transmission-2.92
$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install

View File

@ -136,6 +136,7 @@
A23547E211CD0B090046EAE6 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = A23547E011CD0B090046EAE6 /* cache.c */; };
A23547E311CD0B090046EAE6 /* cache.h in Headers */ = {isa = PBXBuildFile; fileRef = A23547E111CD0B090046EAE6 /* cache.h */; };
A2385DD40BFE06C800B24EF6 /* DragOverlayWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A2385DD20BFE06C800B24EF6 /* DragOverlayWindow.m */; };
A238D49F21CDA1A5006B03EA /* InfoTabMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = A238D49E21CDA1A5006B03EA /* InfoTabMatrix.m */; };
A23F29A1132A447400E9A83B /* announcer-common.h in Headers */ = {isa = PBXBuildFile; fileRef = A23F299F132A447400E9A83B /* announcer-common.h */; };
A23F29A2132A447400E9A83B /* announcer-http.c in Sources */ = {isa = PBXBuildFile; fileRef = A23F29A0132A447400E9A83B /* announcer-http.c */; };
A23F4FF20D1D98AD002FCB97 /* PrefsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = A23F4FF00D1D98AD002FCB97 /* PrefsWindow.xib */; };
@ -644,6 +645,7 @@
A22B00AF116A9E90003315FC /* connecthostport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = connecthostport.h; path = "third-party/miniupnpc/connecthostport.h"; sourceTree = "<group>"; };
A22BAE261388040500FB022F /* NSMutableArrayAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NSMutableArrayAdditions.h; path = macosx/NSMutableArrayAdditions.h; sourceTree = "<group>"; };
A22BAE271388040500FB022F /* NSMutableArrayAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = NSMutableArrayAdditions.m; path = macosx/NSMutableArrayAdditions.m; sourceTree = "<group>"; };
A22CEF9E21CDC44400C5C1BA /* Transmission.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Transmission.entitlements; path = macosx/Transmission.entitlements; sourceTree = "<group>"; };
A22CF7AC0FA3505F0009BD3E /* it */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = it; path = macosx/it.lproj/GroupRules.xib; sourceTree = "<group>"; };
A22CF7B90FA352740009BD3E /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = macosx/fr.lproj/GroupRules.xib; sourceTree = "<group>"; };
A22CF7C90FA5D3F90009BD3E /* es */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = es; path = macosx/es.lproj/GroupRules.xib; sourceTree = "<group>"; };
@ -670,6 +672,8 @@
A236D19615F6BD9C000C3DD4 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = macosx/QuickLookPlugin/it.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
A2385DD20BFE06C800B24EF6 /* DragOverlayWindow.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = DragOverlayWindow.m; path = macosx/DragOverlayWindow.m; sourceTree = "<group>"; };
A2385DD30BFE06C800B24EF6 /* DragOverlayWindow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DragOverlayWindow.h; path = macosx/DragOverlayWindow.h; sourceTree = "<group>"; };
A238D49D21CDA1A5006B03EA /* InfoTabMatrix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InfoTabMatrix.h; path = macosx/InfoTabMatrix.h; sourceTree = "<group>"; };
A238D49E21CDA1A5006B03EA /* InfoTabMatrix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = InfoTabMatrix.m; path = macosx/InfoTabMatrix.m; sourceTree = "<group>"; };
A23F299F132A447400E9A83B /* announcer-common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "announcer-common.h"; path = "libtransmission/announcer-common.h"; sourceTree = "<group>"; };
A23F29A0132A447400E9A83B /* announcer-http.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "announcer-http.c"; path = "libtransmission/announcer-http.c"; sourceTree = "<group>"; };
A23F526D0F14395900AA02E3 /* PredicateEditorRowTemplateAny.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PredicateEditorRowTemplateAny.h; path = macosx/PredicateEditorRowTemplateAny.h; sourceTree = "<group>"; };
@ -795,7 +799,7 @@
A292C9E01413BA5F00EF710F /* es */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = es; path = macosx/es.lproj/GlobalOptionsPopover.xib; sourceTree = "<group>"; };
A292C9E2141593DA00EF710F /* de */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = de; path = macosx/de.lproj/GlobalOptionsPopover.xib; sourceTree = "<group>"; };
A292C9E414163AE500EF710F /* it */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = it; path = macosx/it.lproj/GlobalOptionsPopover.xib; sourceTree = "<group>"; };
A29304EC15D7465100B1F726 /* style.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; name = style.css; path = macosx/QuickLookPlugin/style.css; sourceTree = SOURCE_ROOT; };
A29304EC15D7465100B1F726 /* style.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = style.css; sourceTree = "<group>"; };
A29443271419746A0016143A /* ru */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ru; path = macosx/ru.lproj/GlobalOptionsPopover.xib; sourceTree = "<group>"; };
A294432E141B23CD0016143A /* pt_PT */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = pt_PT; path = macosx/pt_PT.lproj/GlobalOptionsPopover.xib; sourceTree = "<group>"; };
A2963CFD1423F2BB00C497B5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = macosx/fr.lproj/GlobalOptionsPopover.xib; sourceTree = "<group>"; };
@ -908,12 +912,12 @@
A2F35BBD15C5A0A100EBF632 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; };
A2F35BBF15C5A0A100EBF632 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
A2F35BC115C5A0A100EBF632 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
A2F35BC515C5A0A100EBF632 /* QuickLookPlugin-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "QuickLookPlugin-Info.plist"; path = "macosx/QuickLookPlugin/QuickLookPlugin-Info.plist"; sourceTree = SOURCE_ROOT; };
A2F35BC515C5A0A100EBF632 /* QuickLookPlugin-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "QuickLookPlugin-Info.plist"; sourceTree = "<group>"; };
A2F35BC715C5A0A100EBF632 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
A2F35BC915C5A0A100EBF632 /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = GenerateThumbnailForURL.m; path = macosx/QuickLookPlugin/GenerateThumbnailForURL.m; sourceTree = SOURCE_ROOT; };
A2F35BCB15C5A0A100EBF632 /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = GeneratePreviewForURL.m; path = macosx/QuickLookPlugin/GeneratePreviewForURL.m; sourceTree = SOURCE_ROOT; };
A2F35BCD15C5A0A100EBF632 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = main.c; path = macosx/QuickLookPlugin/main.c; sourceTree = SOURCE_ROOT; };
A2F35BCF15C5A0A100EBF632 /* QuickLookPlugin-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "QuickLookPlugin-Prefix.pch"; path = "macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch"; sourceTree = SOURCE_ROOT; };
A2F35BC915C5A0A100EBF632 /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GenerateThumbnailForURL.m; sourceTree = "<group>"; };
A2F35BCB15C5A0A100EBF632 /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GeneratePreviewForURL.m; sourceTree = "<group>"; };
A2F35BCD15C5A0A100EBF632 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
A2F35BCF15C5A0A100EBF632 /* QuickLookPlugin-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QuickLookPlugin-Prefix.pch"; sourceTree = "<group>"; };
A2F35BE015C5A7ED00EBF632 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
A2F35BE215C5A7F900EBF632 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
A2F7CF5413035F7B0016FF10 /* URLSheetWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = URLSheetWindow.xib; path = macosx/URLSheetWindow.xib; sourceTree = "<group>"; };
@ -947,7 +951,7 @@
BE75C3490C729E9500DBEFE0 /* libevent.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libevent.a; sourceTree = BUILT_PRODUCTS_DIR; };
BEFC1C000C07750000B0BB3C /* transmission-daemon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "transmission-daemon"; sourceTree = BUILT_PRODUCTS_DIR; };
BEFC1C0E0C07756200B0BB3C /* daemon.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = daemon.c; path = daemon/daemon.c; sourceTree = "<group>"; };
BEFC1C140C07756200B0BB3C /* remote.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = remote.c; path = daemon/remote.c; sourceTree = "<group>"; };
BEFC1C140C07756200B0BB3C /* remote.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = remote.c; path = utils/remote.c; sourceTree = "<group>"; };
BEFC1CF90C07822400B0BB3C /* transmission-remote */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "transmission-remote"; sourceTree = BUILT_PRODUCTS_DIR; };
BEFC1DF00C07861A00B0BB3C /* version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = version.h; path = libtransmission/version.h; sourceTree = "<group>"; };
BEFC1DF10C07861A00B0BB3C /* utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = utils.h; path = libtransmission/utils.h; sourceTree = "<group>"; };
@ -1260,11 +1264,13 @@
29B97314FDCFA39411CA2CEA /* Transmission */ = {
isa = PBXGroup;
children = (
A22CEF9E21CDC44400C5C1BA /* Transmission.entitlements */,
4DDBB70A09E16B3200284745 /* GUI */,
A2F35BC315C5A0A100EBF632 /* QuickLookPlugin */,
4D1838DC09DEC04A0047D688 /* libtransmission */,
4DDBB71F09E16BFE00284745 /* CLI */,
BEFC1C0B0C07754700B0BB3C /* daemon */,
C15E58AC219A37C600AB292F /* utils */,
A22CFCB50FC24F630009BD3E /* dht */,
A2E384BF130DFA49001F501B /* libutp */,
BE75C3570C72A0D600DBEFE0 /* libevent */,
@ -1598,7 +1604,8 @@
A2F35BCD15C5A0A100EBF632 /* main.c */,
A2F35BC415C5A0A100EBF632 /* Supporting Files */,
);
path = QuickLookPlugin;
name = QuickLookPlugin;
path = macosx/QuickLookPlugin;
sourceTree = "<group>";
};
A2F35BC415C5A0A100EBF632 /* Supporting Files */ = {
@ -1683,11 +1690,18 @@
BEFC1C0E0C07756200B0BB3C /* daemon.c */,
C1F690FE1AD0628400D95CF0 /* daemon.h */,
C1F690FC1AD0627500D95CF0 /* daemon-posix.c */,
BEFC1C140C07756200B0BB3C /* remote.c */,
);
name = daemon;
sourceTree = "<group>";
};
C15E58AC219A37C600AB292F /* utils */ = {
isa = PBXGroup;
children = (
BEFC1C140C07756200B0BB3C /* remote.c */,
);
name = utils;
sourceTree = "<group>";
};
C1639A751A55F52800E42033 /* b64 */ = {
isa = PBXGroup;
children = (
@ -1719,6 +1733,8 @@
A257C1800CAD3003004E121C /* PeerTableView.m */,
A2E23AC30CB5E1930002BB25 /* InfoTabButtonCell.h */,
A2E23AC40CB5E1930002BB25 /* InfoTabButtonCell.m */,
A238D49D21CDA1A5006B03EA /* InfoTabMatrix.h */,
A238D49E21CDA1A5006B03EA /* InfoTabMatrix.m */,
A25BB02812F4F517004B724E /* InfoTabButtonBack.h */,
A25BB02912F4F517004B724E /* InfoTabButtonBack.m */,
A200B8390A2263BA007BBB1E /* InfoWindowController.h */,
@ -2142,6 +2158,13 @@
LastUpgradeCheck = 0420;
ORGANIZATIONNAME = "The Transmission Project";
TargetAttributes = {
8D1107260486CEB800E47090 = {
SystemCapabilities = {
com.apple.HardenedRuntime = {
enabled = 1;
};
};
};
C1639A6E1A55F4D600E42033 = {
CreatedOnToolsVersion = 6.1.1;
};
@ -2256,15 +2279,15 @@
files = (
);
inputPaths = (
"$(SRCROOT)/third-party/miniupnpc/VERSION",
"$(SRCROOT)/third-party/miniupnpc/miniupnpcstrings.h.in",
"third-party/miniupnpc/VERSION",
"third-party/miniupnpc/miniupnpcstrings.h.in",
);
outputPaths = (
"$(SRCROOT)/third-party/miniupnpc/miniupnpcstrings.h",
"third-party/miniupnpc/miniupnpcstrings.h",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cd third-party/miniupnpc\nsh updateminiupnpcstrings.sh \"$SCRIPT_INPUT_FILE_0\" \"$SCRIPT_INPUT_FILE_1\" \"$SCRIPT_OUTPUT_FILE_0\"";
shellScript = "cd third-party/miniupnpc\nsh updateminiupnpcstrings.sh \"$SCRIPT_INPUT_FILE_0\" \"$SCRIPT_INPUT_FILE_1\" \"$SCRIPT_OUTPUT_FILE_0\"\n";
};
BE75C3510C729EE100DBEFE0 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@ -2277,7 +2300,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = "if [ ! -e ./third-party/libevent/include/event2/config.h -a ! ./third-party/macosx-libevent-config.h -ef ./third-party/libevent/include/event2/config.h ]; then ln -s ../../../macosx-libevent-config.h ./third-party/libevent/include/event2/config.h; fi\n\nif [ ! -e ./third-party/libevent/include/event2/event-config.h -a ! ./third-party/macosx-libevent-event-config.h -ef ./third-party/libevent/include/event2/event-config.h ]; then ln -s ../../../macosx-libevent-event-config.h ./third-party/libevent/include/event2/event-config.h; fi";
shellScript = "cd third-party/libevent/include/event2\n\nif [ ! -e config.h -a ! ../../../macosx-libevent-config.h -ef config.h ]; then\n ln -s ../../../macosx-libevent-config.h config.h;\nfi\n\nif [ ! -e event-config.h -a ! ../../../macosx-libevent-event-config.h -ef event-config.h ]; then\n ln -s ../../../macosx-libevent-event-config.h event-config.h;\nfi\n";
};
C12F197C1E1AE55A0005E93F /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@ -2287,11 +2310,11 @@
inputPaths = (
);
outputPaths = (
"$(SRCROOT)/third-party/miniupnpc/miniupnp",
"third-party/miniupnpc/miniupnp",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cd third-party/miniupnpc && rm -f miniupnp && ln -s . miniupnp";
shellScript = "cd third-party/miniupnpc && rm -f miniupnp && ln -s . miniupnp\n";
};
C12F197D1E1AE6830005E93F /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@ -2301,11 +2324,11 @@
inputPaths = (
);
outputPaths = (
"$(SRCROOT)/third-party/libutp/libutp",
"third-party/libutp/libutp",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cd third-party/libutp && rm -f libutp && ln -s . libutp";
shellScript = "cd third-party/libutp && rm -f libutp && ln -s . libutp\n";
};
C12F197E1E1AE6D50005E93F /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@ -2315,11 +2338,11 @@
inputPaths = (
);
outputPaths = (
"$(SRCROOT)/third-party/dht/dht",
"third-party/dht/dht",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cd third-party/dht && rm -f dht && ln -s . dht";
shellScript = "cd third-party/dht && rm -f dht && ln -s . dht\n";
};
/* End PBXShellScriptBuildPhase section */
@ -2486,6 +2509,7 @@
A2B5B4E91880665E0071A66A /* ShareTorrentFileHelper.m in Sources */,
A22BAE281388040500FB022F /* NSMutableArrayAdditions.m in Sources */,
A2966E8713DAF74C007B52DF /* GlobalOptionsPopoverViewController.m in Sources */,
A238D49F21CDA1A5006B03EA /* InfoTabMatrix.m in Sources */,
A234EA541453563B000F3E97 /* NSImageAdditions.m in Sources */,
A2AB883E16A399A6008FAD50 /* VDKQueue.m in Sources */,
A2451E6916ACE4EB00586E0E /* FileRenameSheetController.m in Sources */,
@ -2887,8 +2911,7 @@
A2F35BC715C5A0A100EBF632 /* en */,
);
name = InfoPlist.strings;
path = macosx/QuickLookPlugin;
sourceTree = SOURCE_ROOT;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
@ -2916,11 +2939,6 @@
"third-party/libutp",
"third-party/miniupnpc",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/build/Development\"",
"\"$(SRCROOT)/build/Debug\"",
);
OTHER_CFLAGS = (
"$(inherited)",
"-DWITH_UTP",
@ -2942,13 +2960,14 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = macosx;
GCC_PREFIX_HEADER = macosx/Transmission_Prefix.pch;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = (
HEADER_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/third-party/curl/lib\"",
.,
);
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
PRODUCT_NAME = Transmission;
WRAPPER_EXTENSION = app;
};
@ -2959,8 +2978,9 @@
buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
HEADER_SEARCH_PATHS = (
"third-party/curl/include",
"$(inherited)",
.,
"third-party/libevent/include",
);
PRODUCT_NAME = transmissioncli;
};
@ -3039,15 +3059,15 @@
IBC_FLATTEN_NIBS = YES;
IBC_NOTICES = NO;
IBC_WARNINGS = YES;
INFOPLIST_FILE = "$(SRCROOT)/macosx/Info.plist";
INFOPLIST_OTHER_PREPROCESSOR_FLAGS = "-CC";
INFOPLIST_PREFIX_HEADER = "$(SRCROOT)/libtransmission/version.h";
INFOPLIST_FILE = macosx/Info.plist;
INFOPLIST_OTHER_PREPROCESSOR_FLAGS = "-traditional";
INFOPLIST_PREFIX_HEADER = libtransmission/version.h;
INFOPLIST_PREPROCESS = YES;
LIBRARY_SEARCH_PATHS = (
"third-party/curl/lib",
"third-party/openssl/lib",
);
MACOSX_DEPLOYMENT_TARGET = 10.9;
MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
STRIP_INSTALLED_PRODUCT = NO;
@ -3094,11 +3114,6 @@
"third-party/libutp",
"third-party/miniupnpc",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/build/Development\"",
"\"$(SRCROOT)/build/Debug\"",
);
OTHER_CFLAGS = (
"$(inherited)",
"-DWITH_UTP",
@ -3121,8 +3136,9 @@
buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
HEADER_SEARCH_PATHS = (
"third-party/curl/include",
"$(inherited)",
.,
"third-party/libevent/include",
);
PRODUCT_NAME = transmissioncli;
};
@ -3132,13 +3148,14 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = macosx;
GCC_PREFIX_HEADER = macosx/Transmission_Prefix.pch;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = (
HEADER_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/third-party/curl/lib\"",
.,
);
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
PRODUCT_NAME = Transmission;
WRAPPER_EXTENSION = app;
};
@ -3186,15 +3203,15 @@
IBC_FLATTEN_NIBS = YES;
IBC_NOTICES = NO;
IBC_WARNINGS = YES;
INFOPLIST_FILE = "$(SRCROOT)/macosx/Info.plist";
INFOPLIST_OTHER_PREPROCESSOR_FLAGS = "-CC";
INFOPLIST_PREFIX_HEADER = "$(SRCROOT)/libtransmission/version.h";
INFOPLIST_FILE = macosx/Info.plist;
INFOPLIST_OTHER_PREPROCESSOR_FLAGS = "-traditional";
INFOPLIST_PREFIX_HEADER = libtransmission/version.h;
INFOPLIST_PREPROCESS = YES;
LIBRARY_SEARCH_PATHS = (
"third-party/curl/lib",
"third-party/openssl/lib",
);
MACOSX_DEPLOYMENT_TARGET = 10.9;
MACOSX_DEPLOYMENT_TARGET = 10.10;
OTHER_CFLAGS = "-DNDEBUG";
SDKROOT = macosx;
};
@ -3267,15 +3284,15 @@
IBC_FLATTEN_NIBS = YES;
IBC_NOTICES = NO;
IBC_WARNINGS = YES;
INFOPLIST_FILE = "$(SRCROOT)/macosx/Info.plist";
INFOPLIST_OTHER_PREPROCESSOR_FLAGS = "-CC";
INFOPLIST_PREFIX_HEADER = "$(SRCROOT)/libtransmission/version.h";
INFOPLIST_FILE = macosx/Info.plist;
INFOPLIST_OTHER_PREPROCESSOR_FLAGS = "-traditional";
INFOPLIST_PREFIX_HEADER = libtransmission/version.h;
INFOPLIST_PREPROCESS = YES;
LIBRARY_SEARCH_PATHS = (
"third-party/curl/lib",
"third-party/openssl/lib",
);
MACOSX_DEPLOYMENT_TARGET = 10.9;
MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
STRIP_INSTALLED_PRODUCT = NO;
@ -3286,13 +3303,14 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = macosx;
GCC_PREFIX_HEADER = macosx/Transmission_Prefix.pch;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = (
HEADER_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/third-party/curl/lib\"",
.,
);
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
PRODUCT_NAME = Transmission;
WRAPPER_EXTENSION = app;
};
@ -3303,8 +3321,9 @@
buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
HEADER_SEARCH_PATHS = (
"third-party/curl/include",
"$(inherited)",
.,
"third-party/libevent/include",
);
PRODUCT_NAME = transmissioncli;
};
@ -3323,11 +3342,6 @@
"third-party/libutp",
"third-party/miniupnpc",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/build/Development\"",
"\"$(SRCROOT)/build/Debug\"",
);
OTHER_CFLAGS = (
"$(inherited)",
"-DWITH_UTP",
@ -3419,8 +3433,12 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
GCC_PREFIX_HEADER = "$(SRCROOT)/macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch";
INFOPLIST_FILE = "$(SRCROOT)/macosx/QuickLookPlugin/QuickLookPlugin-Info.plist";
GCC_PREFIX_HEADER = "macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch";
HEADER_SEARCH_PATHS = (
"$(inherited)",
.,
);
INFOPLIST_FILE = "macosx/QuickLookPlugin/QuickLookPlugin-Info.plist";
INSTALL_PATH = /Library/QuickLook;
OTHER_LDFLAGS = "";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -3432,8 +3450,12 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
GCC_PREFIX_HEADER = "$(SRCROOT)/macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch";
INFOPLIST_FILE = "$(SRCROOT)/macosx/QuickLookPlugin/QuickLookPlugin-Info.plist";
GCC_PREFIX_HEADER = "macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch";
HEADER_SEARCH_PATHS = (
"$(inherited)",
.,
);
INFOPLIST_FILE = "macosx/QuickLookPlugin/QuickLookPlugin-Info.plist";
INSTALL_PATH = /Library/QuickLook;
OTHER_LDFLAGS = "";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -3445,8 +3467,12 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
GCC_PREFIX_HEADER = "$(SRCROOT)/macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch";
INFOPLIST_FILE = "$(SRCROOT)/macosx/QuickLookPlugin/QuickLookPlugin-Info.plist";
GCC_PREFIX_HEADER = "macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch";
HEADER_SEARCH_PATHS = (
"$(inherited)",
.,
);
INFOPLIST_FILE = "macosx/QuickLookPlugin/QuickLookPlugin-Info.plist";
INSTALL_PATH = /Library/QuickLook;
OTHER_LDFLAGS = "";
PRODUCT_NAME = "$(TARGET_NAME)";

View File

@ -1,31 +1,28 @@
#!/bin/sh
srcdir=`dirname $0`
srcdir=$(dirname "$0")
test -z "$srcdir" && srcdir=.
ORIGDIR=`pwd`
cd "$srcdir"
ORIGDIR=$(pwd)
cd "$srcdir" || exit 1
PROJECT=Transmission
GETTEXTIZE="glib-gettextize"
$GETTEXTIZE --version < /dev/null > /dev/null 2>&1
if test $? -ne 0; then
GETTEXTIZE=""
GETTEXTIZE=""
fi
LIBTOOLIZE=libtoolize
if libtoolize --help >/dev/null 2>&1
then
if libtoolize --help > /dev/null 2>&1; then
:
elif glibtoolize --help >/dev/null 2>&1
then
elif glibtoolize --help > /dev/null 2>&1; then
LIBTOOLIZE=glibtoolize
fi
export LIBTOOLIZE
./update-version-h.sh
autoreconf -fi || exit 1;
autoreconf -fi || exit 1
if test "$GETTEXTIZE"; then
echo "Creating aclocal.m4 ..."
@ -41,10 +38,9 @@ fi
cd "$ORIGDIR" || exit $?
if test -z "$AUTOGEN_SUBDIR_MODE"; then
echo Running $srcdir/configure "$@"
$srcdir/configure "$@"
echo Running $srcdir/configure "$@"
$srcdir/configure "$@"
echo
echo "Now type 'make' to compile $PROJECT."
echo
echo "Now type 'make' to compile $PROJECT."
fi

View File

@ -99,8 +99,8 @@ static struct tr_option const options[] =
static char const* getUsage(void)
{
return "A fast and easy BitTorrent client\n"
"\n"
"Usage: " MY_READABLE_NAME " [options] <file|url|magnet>";
"\n"
"Usage: " MY_READABLE_NAME " [options] <file|url|magnet>";
}
static int parseCommandLine(tr_variant*, int argc, char const** argv);

View File

@ -50,7 +50,7 @@ The options are as follows:
Enable peer blocklists. Transmission understands the bluetack blocklist file format.
New blocklists can be added by copying them into the config-dir's "blocklists" subdirectory.
.It Fl B Fl -no-blocklist
Disble blocklists.
Disable blocklists.
.It Fl d, -downlimit Ar number
Set the maximum download speed in KB/s
.It Fl D, -no-downlimit

View File

@ -32,7 +32,7 @@ BEGIN
VALUE "FileDescription", "${TR_FILE_DESCRIPTION}"
VALUE "FileVersion", LONG_VERSION_STRING
VALUE "InternalName", "${TR_INTERNAL_NAME}"
VALUE "LegalCopyright", "2005-2016 Transmission Project"
VALUE "LegalCopyright", "2005-2019 Transmission Project"
VALUE "OriginalFilename", "${TR_ORIGINAL_FILENAME}"
VALUE "ProductName", "Transmission"
VALUE "ProductVersion", LONG_VERSION_STRING

View File

@ -3,8 +3,8 @@ dnl STATUS: "X" for prerelease beta builds,
dnl "Z" for unsupported trunk builds,
dnl "0" for stable, supported releases
dnl these should be the only two lines you need to change
m4_define([user_agent_prefix],[2.93+])
m4_define([peer_id_prefix],[-TR293Z-])
m4_define([user_agent_prefix],[2.94+])
m4_define([peer_id_prefix],[-TR294Z-])
AC_INIT([transmission],[user_agent_prefix],[https://github.com/transmission/transmission])
AC_SUBST(USERAGENT_PREFIX,[user_agent_prefix])

View File

@ -46,19 +46,7 @@ if(WITH_SYSTEMD)
target_link_libraries(${TR_NAME}-daemon ${SYSTEMD_LIBRARIES})
endif()
tr_win32_app_info(${PROJECT_NAME}_remote_WIN32_RC_FILE
"Transmission Utility ('remote')"
"${TR_NAME}-remote"
"${TR_NAME}-remote.exe")
add_executable(${TR_NAME}-remote remote.c ${${PROJECT_NAME}_remote_WIN32_RC_FILE})
target_link_libraries(${TR_NAME}-remote
${TR_NAME}
${CURL_LIBRARIES}
)
foreach(P daemon remote)
foreach(P daemon)
install(TARGETS ${TR_NAME}-${P} DESTINATION ${CMAKE_INSTALL_BINDIR})
if(INSTALL_DOC)

View File

@ -11,12 +11,10 @@ EXTRA_DIST = \
transmission-daemon.service
dist_man_MANS = \
transmission-daemon.1 \
transmission-remote.1
transmission-daemon.1
bin_PROGRAMS = \
transmission-daemon \
transmission-remote
transmission-daemon
LDADD = \
$(top_builddir)/libtransmission/libtransmission.a \
@ -37,7 +35,6 @@ LDADD = \
noinst_HEADERS = daemon.h
transmission_daemon_SOURCES = daemon.c
transmission_remote_SOURCES = remote.c
if WIN32
transmission_daemon_SOURCES += daemon-win32.c

View File

@ -87,13 +87,13 @@ static struct event_base* ev_base = NULL;
static char const* getUsage(void)
{
return "Transmission " LONG_VERSION_STRING " https://transmissionbt.com/\n"
"A fast and easy BitTorrent client\n"
"\n"
MY_NAME " is a headless Transmission session\n"
"that can be controlled via transmission-remote\n"
"or the web interface.\n"
"\n"
"Usage: " MY_NAME " [options]";
"A fast and easy BitTorrent client\n"
"\n"
MY_NAME " is a headless Transmission session\n"
"that can be controlled via transmission-remote\n"
"or the web interface.\n"
"\n"
"Usage: " MY_NAME " [options]";
}
static struct tr_option const options[] =
@ -129,16 +129,20 @@ static struct tr_option const options[] =
{ 'P', "peerport", "Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")", "P", 1, "<port>" },
{ 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP", "m", 0, NULL },
{ 'M', "no-portmap", "Disable portmapping", "M", 0, NULL },
{ 'L', "peerlimit-global", "Maximum overall number of peers (Default: " TR_DEFAULT_PEER_LIMIT_GLOBAL_STR ")", "L", 1, "<limit>" },
{ 'l', "peerlimit-torrent", "Maximum number of peers per torrent (Default: " TR_DEFAULT_PEER_LIMIT_TORRENT_STR ")", "l", 1, "<limit>" },
{ 'L', "peerlimit-global", "Maximum overall number of peers (Default: " TR_DEFAULT_PEER_LIMIT_GLOBAL_STR ")", "L", 1,
"<limit>" },
{ 'l', "peerlimit-torrent", "Maximum number of peers per torrent (Default: " TR_DEFAULT_PEER_LIMIT_TORRENT_STR ")", "l", 1,
"<limit>" },
{ 910, "encryption-required", "Encrypt all peer connections", "er", 0, NULL },
{ 911, "encryption-preferred", "Prefer encrypted peer connections", "ep", 0, NULL },
{ 912, "encryption-tolerated", "Prefer unencrypted peer connections", "et", 0, NULL },
{ 'i', "bind-address-ipv4", "Where to listen for peer connections", "i", 1, "<ipv4 addr>" },
{ 'I', "bind-address-ipv6", "Where to listen for peer connections", "I", 1, "<ipv6 addr>" },
{ 'r', "rpc-bind-address", "Where to listen for RPC connections", "r", 1, "<ip addr>" },
{ 953, "global-seedratio", "All torrents, unless overridden by a per-torrent setting, should seed until a specific ratio", "gsr", 1, "ratio" },
{ 954, "no-global-seedratio", "All torrents, unless overridden by a per-torrent setting, should seed regardless of ratio", "GSR", 0, NULL },
{ 953, "global-seedratio", "All torrents, unless overridden by a per-torrent setting, should seed until a specific ratio",
"gsr", 1, "ratio" },
{ 954, "no-global-seedratio", "All torrents, unless overridden by a per-torrent setting, should seed regardless of ratio",
"GSR", 0, NULL },
{ 'x', "pid-file", "Enable PID file", "x", 1, "<pid-file>" },
{ 0, NULL, NULL, NULL, 0, NULL }
};
@ -147,8 +151,8 @@ static bool reopen_log_file(char const* filename)
{
tr_error* error = NULL;
tr_sys_file_t const old_log_file = logfile;
tr_sys_file_t const new_log_file = tr_sys_file_open(filename, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_APPEND, 0666,
&error);
tr_sys_file_t const new_log_file = tr_sys_file_open(filename, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_APPEND,
0666, &error);
if (new_log_file == TR_BAD_SYS_FILE)
{
@ -648,7 +652,8 @@ static int daemon_start(void* raw_arg, bool foreground)
if (pid_filename != NULL && *pid_filename != '\0')
{
tr_error* error = NULL;
tr_sys_file_t fp = tr_sys_file_open(pid_filename, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0666, &error);
tr_sys_file_t fp = tr_sys_file_open(pid_filename, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0666,
&error);
if (fp != TR_BAD_SYS_FILE)
{

View File

@ -1,4 +1,4 @@
#/bin/sh
#!/bin/sh
export G_SLICE=always-malloc
export G_DEBUG=gc-friendly
export GLIBCXX_FORCE_NEW=1

View File

@ -7,6 +7,7 @@ User=transmission
Type=notify
ExecStart=/usr/bin/transmission-daemon -f --log-error
ExecReload=/bin/kill -s HUP $MAINPID
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target

View File

@ -117,6 +117,7 @@
"files-unwanted" | array indices of file(s) to not download
"honorsSessionLimits" | boolean true if session upload limits are honored
"ids" | array torrent list, as described in 3.1
"labels" | array array of string labels
"location" | string new location of the torrent's content
"peer-limit" | number maximum number of peers
"priority-high" | array indices of high-priority file(s)
@ -189,6 +190,7 @@
isFinished | boolean | tr_stat
isPrivate | boolean | tr_torrent
isStalled | boolean | tr_stat
labels | array (see below) | tr_torrent
leftUntilDone | number | tr_stat
magnetLink | string | n/a
manualAnnounceTime | number | tr_stat
@ -247,6 +249,10 @@
| wanted | boolean | tr_info
| priority | number | tr_info
-------------------+--------------------------------------+
labels | an array of strings: |
+-------------------------+------------+
| label | string | tr_torrent
-------------------+--------------------------------------+
peers | array of objects, each containing: |
+-------------------------+------------+
| address | string | tr_peer_stat
@ -784,6 +790,9 @@
------+---------+-----------+----------------------+-------------------------------
16 | 3.00 | yes | session-get | new request arg "fields"
| | yes | session-get | new arg "session-id"
| | yes | torrent-get | new arg "labels"
| | yes | torrent-set | new arg "labels"
5.1. Upcoming Breakage

View File

@ -47,7 +47,7 @@ SMTP_SERVER=your.smtp.server
SUBJECT="Torrent Done!"
FROM_ADDR="transmission@localhost.localdomain"
TMPFILE=`mktemp -t transmission.XXXXXXXXXX`
echo "Transmission finished downloading \"$TR_TORRENT_NAME\" on $TR_TIME_LOCALTIME" >$TMPFILE
$NAIL -v -S from="$FROM_ADDR" -S smtp -s "$SUBJECT" -S smtp=$SMTP_SERVER "$TO_ADDR" < $TMPFILE
rm $TMPFILE
TMPFILE=$(mktemp -t transmission.XXXXXXXXXX)
echo "Transmission finished downloading \"$TR_TORRENT_NAME\" on $TR_TIME_LOCALTIME" > "$TMPFILE"
$NAIL -v -S from="$FROM_ADDR" -S smtp -s "$SUBJECT" -S smtp=$SMTP_SERVER "$TO_ADDR" < "$TMPFILE"
rm "$TMPFILE"

View File

@ -86,7 +86,8 @@ static GtkActionEntry entries[] =
{ "open-torrent-toolbar", GTK_STOCK_OPEN, NULL, NULL, N_("Open a torrent"), G_CALLBACK(action_cb) },
{ "open-torrent-menu", GTK_STOCK_OPEN, NULL, NULL, N_("Open a torrent"), G_CALLBACK(action_cb) },
{ "torrent-start", GTK_STOCK_MEDIA_PLAY, N_("_Start"), "<control>S", N_("Start torrent"), G_CALLBACK(action_cb) },
{ "torrent-start-now", GTK_STOCK_MEDIA_PLAY, N_("Start _Now"), "<shift><control>S", N_("Start torrent now"), G_CALLBACK(action_cb) },
{ "torrent-start-now", GTK_STOCK_MEDIA_PLAY, N_("Start _Now"), "<shift><control>S", N_("Start torrent now"),
G_CALLBACK(action_cb) },
{ "show-stats", NULL, N_("_Statistics"), NULL, NULL, G_CALLBACK(action_cb) },
{ "donate", NULL, N_("_Donate"), NULL, NULL, G_CALLBACK(action_cb) },
{ "torrent-verify", NULL, N_("_Verify Local Data"), "<control>V", NULL, G_CALLBACK(action_cb) },
@ -206,14 +207,16 @@ void gtr_actions_init(GtkUIManager* ui_manager, gpointer callback_user_data)
gtk_action_group_add_radio_actions(action_group, sort_radio_entries, G_N_ELEMENTS(sort_radio_entries), active,
G_CALLBACK(sort_changed_cb), NULL);
gtk_action_group_add_toggle_actions(action_group, show_toggle_entries, G_N_ELEMENTS(show_toggle_entries), callback_user_data);
gtk_action_group_add_toggle_actions(action_group, show_toggle_entries, G_N_ELEMENTS(show_toggle_entries),
callback_user_data);
for (size_t i = 0; i < G_N_ELEMENTS(pref_toggle_entries); ++i)
{
pref_toggle_entries[i].is_active = gtr_pref_flag_get(tr_quark_new(pref_toggle_entries[i].name, TR_BAD_SIZE));
}
gtk_action_group_add_toggle_actions(action_group, pref_toggle_entries, G_N_ELEMENTS(pref_toggle_entries), callback_user_data);
gtk_action_group_add_toggle_actions(action_group, pref_toggle_entries, G_N_ELEMENTS(pref_toggle_entries),
callback_user_data);
gtk_action_group_add_actions(action_group, entries, n_entries, callback_user_data);

View File

@ -135,7 +135,7 @@ static gboolean refreshFilesForeach(GtkTreeModel* model, GtkTreePath* path UNUSE
(refresh_data->sort_column_id == FC_ENABLED && enabled != old_enabled)))
{
refresh_data->resort_needed = TRUE;
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE( data->model),
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(data->model),
GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
}
}

View File

@ -493,7 +493,7 @@ static gboolean test_torrent_activity(tr_torrent* tor, int type)
case ACTIVITY_FILTER_ACTIVE:
return st->peersSendingToUs > 0 || st->peersGettingFromUs > 0 || st->webseedsSendingToUs > 0 ||
st->activity == TR_STATUS_CHECK;
st->activity == TR_STATUS_CHECK;
case ACTIVITY_FILTER_PAUSED:
return st->activity == TR_STATUS_STOPPED;
@ -779,7 +779,7 @@ static gboolean is_row_visible(GtkTreeModel* model, GtkTreeIter* iter, gpointer
text = (char const*)g_object_get_qdata(o, TEXT_KEY);
return tor != NULL && test_tracker(tor, data->active_tracker_type, data->active_tracker_host) &&
test_torrent_activity(tor, data->active_activity_type) && testText(tor, text);
test_torrent_activity(tor, data->active_activity_type) && testText(tor, text);
}
static void selection_changed_cb(GtkComboBox* combo, gpointer vdata)

View File

@ -59,7 +59,7 @@
#define SHOW_LICENSE
static char const* LICENSE =
"Copyright 2005-2016. All code is copyrighted by the respective authors.\n"
"Copyright 2005-2019. All code is copyrighted by the respective authors.\n"
"\n"
"Transmission can be redistributed and/or modified under the terms of the "
"GNU GPL versions 2 or 3 or by any future license endorsed by Mnemosyne LLC.\n"

View File

@ -1,4 +1,4 @@
#/bin/sh
#!/bin/sh
export G_SLICE=always-malloc
export G_DEBUG=gc-friendly
export GLIBCXX_FORCE_NEW=1

View File

@ -568,7 +568,8 @@ static void gtr_cell_renderer_render(GtkCellRenderer* renderer, GtrDrawable* dra
}
static void render_compact(TorrentCellRenderer* cell, GtrDrawable* window, GtkWidget* widget,
GdkRectangle const* background_area, GdkRectangle const* cell_area UNUSED, GtkCellRendererState flags)
GdkRectangle const* background_area, GdkRectangle const* cell_area UNUSED,
GtkCellRendererState flags)
{
int xpad;
int ypad;
@ -754,7 +755,8 @@ static void render_full(TorrentCellRenderer* cell, GtrDrawable* window, GtkWidge
}
static void torrent_cell_renderer_render(GtkCellRenderer* cell, GtrDrawable* window, GtkWidget* widget,
GdkRectangle const* background_area, GdkRectangle const* cell_area, GtkCellRendererState flags)
GdkRectangle const* background_area, GdkRectangle const* cell_area,
GtkCellRendererState flags)
{
TorrentCellRenderer* self = TORRENT_CELL_RENDERER(cell);

View File

@ -206,7 +206,7 @@ void gtr_get_host_from_url(char* buf, size_t buflen, char const* url)
static gboolean gtr_is_supported_url(char const* str)
{
return str != NULL && (g_str_has_prefix(str, "ftp://") || g_str_has_prefix(str, "http://") ||
g_str_has_prefix(str, "https://"));
g_str_has_prefix(str, "https://"));
}
gboolean gtr_is_magnet_link(char const* str)

View File

@ -25,8 +25,12 @@ enum
* - ocelot has no upper bound
* - opentracker has an upper bound of 64
* - udp protocol has an upper bound of 74
* - xbtt has no upper bound */
TR_MULTISCRAPE_MAX = 64
* - xbtt has no upper bound
*
* This is only an upper bound: if the tracker complains about
* length, announcer will incrementally lower the batch size.
*/
TR_MULTISCRAPE_MAX = 100
};
typedef struct

View File

@ -59,7 +59,10 @@ enum
/* */
UPKEEP_INTERVAL_SECS = 1,
/* this is how often to call the UDP tracker upkeep */
TAU_UPKEEP_INTERVAL_SECS = 5
TAU_UPKEEP_INTERVAL_SECS = 5,
/* how many infohashes to remove when we get a scrape-too-long error */
TR_MULTISCRAPE_STEP = 5
};
/***
@ -130,7 +133,7 @@ static int compareStops(void const* va, void const* vb)
return i;
}
/* tertiary key: the tracker's announec url */
/* tertiary key: the tracker's announce url */
return tr_strcmp0(a->url, b->url);
}
@ -138,12 +141,35 @@ static int compareStops(void const* va, void const* vb)
****
***/
struct tr_scrape_info
{
char* url;
int multiscrape_max;
};
static void scrapeInfoFree(void* va)
{
struct tr_scrape_info* a = va;
tr_free(a->url);
tr_free(a);
}
static int compareScrapeInfo(void const* va, void const* vb)
{
struct tr_scrape_info const* a = va;
struct tr_scrape_info const* b = vb;
return tr_strcmp0(a->url, b->url);
}
/**
* "global" (per-tr_session) fields
*/
typedef struct tr_announcer
{
tr_ptrArray stops; /* tr_announce_request */
tr_ptrArray scrape_info; /* struct tr_scrape_info */
tr_session* session;
struct event* upkeepTimer;
@ -153,6 +179,31 @@ typedef struct tr_announcer
}
tr_announcer;
static struct tr_scrape_info* tr_announcerGetScrapeInfo(struct tr_announcer* announcer, char const* url)
{
struct tr_scrape_info* info = NULL;
if (url != NULL && *url != '\0')
{
bool found;
struct tr_scrape_info const key = { .url = (char*)url };
int const pos = tr_ptrArrayLowerBound(&announcer->scrape_info, &key, compareScrapeInfo, &found);
if (found)
{
info = tr_ptrArrayNth(&announcer->scrape_info, pos);
}
else
{
info = tr_new0(struct tr_scrape_info, 1);
info->url = tr_strdup(url);
info->multiscrape_max = TR_MULTISCRAPE_MAX;
tr_ptrArrayInsert(&announcer->scrape_info, info, pos);
}
}
return info;
}
bool tr_announcerHasBacklog(struct tr_announcer const* announcer)
{
return announcer->slotsAvailable < 1;
@ -189,6 +240,7 @@ void tr_announcerClose(tr_session* session)
announcer->upkeepTimer = NULL;
tr_ptrArrayDestruct(&announcer->stops, NULL);
tr_ptrArrayDestruct(&announcer->scrape_info, scrapeInfoFree);
session->announcer = NULL;
tr_free(announcer);
@ -203,7 +255,7 @@ typedef struct
{
char* key;
char* announce;
char* scrape;
struct tr_scrape_info* scrape_info;
char* tracker_id_str;
@ -234,12 +286,12 @@ static char* getKey(char const* url)
return ret;
}
static void trackerConstruct(tr_tracker* tracker, tr_tracker_info const* inf)
static void trackerConstruct(tr_announcer* announcer, tr_tracker* tracker, tr_tracker_info const* inf)
{
memset(tracker, 0, sizeof(tr_tracker));
tracker->key = getKey(inf->announce);
tracker->announce = tr_strdup(inf->announce);
tracker->scrape = tr_strdup(inf->scrape);
tracker->scrape_info = tr_announcerGetScrapeInfo(announcer, inf->scrape);
tracker->id = inf->id;
tracker->seederCount = -1;
tracker->leecherCount = -1;
@ -249,7 +301,6 @@ static void trackerConstruct(tr_tracker* tracker, tr_tracker_info const* inf)
static void trackerDestruct(tr_tracker* tracker)
{
tr_free(tracker->tracker_id_str);
tr_free(tracker->scrape);
tr_free(tracker->announce);
tr_free(tracker->key);
}
@ -681,7 +732,7 @@ static void addTorrentToTier(tr_torrent_tiers* tt, tr_torrent* tor)
for (int i = 0; i < n; ++i)
{
trackerConstruct(&tt->trackers[i], &infos[i]);
trackerConstruct(tor->session->announcer, &tt->trackers[i], &infos[i]);
}
/* count how many tiers there are */
@ -1195,7 +1246,7 @@ static void on_announce_done(tr_announce_response const* response, void* vdata)
/* if the tracker included scrape fields in its announce response,
then a separate scrape isn't needed */
if (scrape_fields >= 3 || (scrape_fields >= 1 && tracker->scrape == NULL))
if (scrape_fields >= 3 || (scrape_fields >= 1 && tracker->scrape_info == NULL))
{
tr_logAddTorDbg(tier->tor, "Announce response contained scrape info; "
"rescheduling next scrape to %d seconds from now.", tier->scrapeIntervalSec);
@ -1303,6 +1354,33 @@ static void tierAnnounce(tr_announcer* announcer, tr_tier* tier)
****
***/
static bool multiscrape_too_big(char const* errmsg)
{
/* Found a tracker that returns some bespoke string for this case?
Add your patch here and open a PR */
static char const* const too_long_errors[] =
{
"Bad Request",
"GET string too long",
"Request-URI Too Long"
};
if (errmsg == NULL)
{
return false;
}
for (size_t i = 0; i < TR_N_ELEMENTS(too_long_errors); ++i)
{
if (strstr(errmsg, too_long_errors[i]) != NULL)
{
return true;
}
}
return false;
}
static void on_scrape_error(tr_session* session, tr_tier* tier, char const* errmsg)
{
int interval;
@ -1337,7 +1415,9 @@ static tr_tier* find_tier(tr_torrent* tor, char const* scrape)
{
tr_tracker const* const tracker = tt->tiers[i].currentTracker;
if (tracker != NULL && tr_strcmp0(scrape, tracker->scrape) == 0)
if (tracker != NULL &&
tracker->scrape_info != NULL &&
tr_strcmp0(scrape, tracker->scrape_info->url) == 0)
{
return &tt->tiers[i];
}
@ -1434,6 +1514,38 @@ static void on_scrape_done(tr_scrape_response const* response, void* vsession)
}
}
/* Maybe reduce the number of torrents in a multiscrape req */
if (multiscrape_too_big(response->errmsg))
{
char const* url = response->url;
int* multiscrape_max = &tr_announcerGetScrapeInfo(announcer, url)->multiscrape_max;
/* Lower the max only if it hasn't already lowered for a similar error.
For example if N parallel multiscrapes all have the same `max` and
error out, lower the value once for that batch, not N times. */
if (*multiscrape_max >= response->row_count)
{
int const n = MAX(1, *multiscrape_max - TR_MULTISCRAPE_STEP);
if (*multiscrape_max != n)
{
char* scheme = NULL;
char* host = NULL;
int port;
if (tr_urlParse(url, strlen(url), &scheme, &host, &port, NULL))
{
/* don't log the full URL, since that might have a personal announce id */
char* sanitized_url = tr_strdup_printf("%s://%s:%d", scheme, host, port);
tr_logAddNamedInfo(sanitized_url, "Reducing multiscrape max to %d", n);
tr_free(sanitized_url);
tr_free(host);
tr_free(scheme);
}
*multiscrape_max = n;
}
}
}
if (announcer)
{
++announcer->slotsAvailable;
@ -1471,23 +1583,23 @@ static void multiscrape(tr_announcer* announcer, tr_ptrArray* tiers)
for (int i = 0; i < tier_count; ++i)
{
tr_tier* tier = tr_ptrArrayNth(tiers, i);
char* url = tier->currentTracker->scrape;
struct tr_scrape_info* const scrape_info = tier->currentTracker->scrape_info;
uint8_t const* hash = tier->tor->info.hash;
bool found = false;
TR_ASSERT(url != NULL);
TR_ASSERT(scrape_info != NULL);
/* if there's a request with this scrape URL and a free slot, use it */
for (int j = 0; !found && j < request_count; ++j)
{
tr_scrape_request* req = &requests[j];
if (req->info_hash_count >= TR_MULTISCRAPE_MAX)
if (req->info_hash_count >= scrape_info->multiscrape_max)
{
continue;
}
if (tr_strcmp0(req->url, url) != 0)
if (tr_strcmp0(req->url, scrape_info->url) != 0)
{
continue;
}
@ -1502,7 +1614,7 @@ static void multiscrape(tr_announcer* announcer, tr_ptrArray* tiers)
if (!found && request_count < max_request_count)
{
tr_scrape_request* req = &requests[request_count++];
req->url = url;
req->url = scrape_info->url;
tier_build_log_name(tier, req->log_name, sizeof(req->log_name));
memcpy(req->info_hash[req->info_hash_count++], hash, SHA_DIGEST_LENGTH);
@ -1534,13 +1646,13 @@ static void flushCloseMessages(tr_announcer* announcer)
static bool tierNeedsToAnnounce(tr_tier const* tier, time_t const now)
{
return !tier->isAnnouncing && !tier->isScraping && tier->announceAt != 0 && tier->announceAt <= now &&
tier->announce_event_count > 0;
tier->announce_event_count > 0;
}
static bool tierNeedsToScrape(tr_tier const* tier, time_t const now)
{
return !tier->isScraping && tier->scrapeAt != 0 && tier->scrapeAt <= now && tier->currentTracker != NULL &&
tier->currentTracker->scrape != NULL;
tier->currentTracker->scrape_info != NULL;
}
static int compareTiers(void const* va, void const* vb)
@ -1691,9 +1803,9 @@ tr_tracker_stat* tr_announcerStats(tr_torrent const* torrent, int* setmeTrackerC
st->isBackup = tracker != tier->currentTracker;
st->lastScrapeStartTime = tier->lastScrapeStartTime;
if (tracker->scrape != NULL)
if (tracker->scrape_info != NULL)
{
tr_strlcpy(st->scrape, tracker->scrape, sizeof(st->scrape));
tr_strlcpy(st->scrape, tracker->scrape_info->url, sizeof(st->scrape));
}
else
{

View File

@ -19,12 +19,14 @@
#include "libtransmission-test.h"
static char const* contents1 =
"10.5.6.7/8\n"
"Austin Law Firm:216.16.1.144-216.16.1.151\n"
"Sargent Controls and Aerospace:216.19.18.0-216.19.18.255\n"
"Corel Corporation:216.21.157.192-216.21.157.223\n"
"Fox Speed Channel:216.79.131.192-216.79.131.223\n";
static char const* contents2 =
"10.5.6.7/8\n"
"Austin Law Firm:216.16.1.144-216.16.1.151\n"
"Sargent Controls and Aerospace:216.19.18.0-216.19.18.255\n"
"Corel Corporation:216.21.157.192-216.21.157.223\n"
@ -70,7 +72,7 @@ static int test_parsing(void)
tr_free(path);
tr_sessionReloadBlocklists(session);
check(tr_blocklistExists(session));
check_int(tr_blocklistGetRuleCount(session), ==, 4);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
/* enable the blocklist */
check(!tr_blocklistIsEnabled(session));
@ -78,6 +80,8 @@ static int test_parsing(void)
check(tr_blocklistIsEnabled(session));
/* test blocked addresses */
check(!address_is_blocked(session, "0.0.0.1"));
check(address_is_blocked(session, "10.1.2.3"));
check(!address_is_blocked(session, "216.16.1.143"));
check(address_is_blocked(session, "216.16.1.144"));
check(address_is_blocked(session, "216.16.1.145"));
@ -116,22 +120,22 @@ static int test_updating(void)
/* test that updated source files will get loaded */
create_text_file(path, contents1);
tr_sessionReloadBlocklists(session);
check_int(tr_blocklistGetRuleCount(session), ==, 4);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
/* test that updated source files will get loaded */
create_text_file(path, contents2);
tr_sessionReloadBlocklists(session);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
check_int(tr_blocklistGetRuleCount(session), ==, 6);
/* test that updated source files will get loaded */
create_text_file(path, contents1);
tr_sessionReloadBlocklists(session);
check_int(tr_blocklistGetRuleCount(session), ==, 4);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
/* ensure that new files, if bad, get skipped */
create_text_file(path, "# nothing useful\n");
tr_sessionReloadBlocklists(session);
check_int(tr_blocklistGetRuleCount(session), ==, 4);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
/* cleanup */
libttest_session_close(session);

View File

@ -301,9 +301,41 @@ static bool parseLine2(char const* line, struct tr_ipv4_range* range)
return true;
}
/*
* CIDR notation: "0.0.0.0/8", IPv4 only
* https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation
*/
static bool parseLine3(char const* line, struct tr_ipv4_range* range)
{
unsigned int ip[4];
unsigned int pflen;
uint32_t ip_u;
uint32_t mask = 0xffffffff;
if (sscanf(line, "%u.%u.%u.%u/%u", &ip[0], &ip[1], &ip[2], &ip[3], &pflen) != 5)
{
return false;
}
if (pflen > 32 || ip[0] > 0xff || ip[1] > 0xff || ip[2] > 0xff || ip[3] > 0xff)
{
return false;
}
/* this is host order */
mask <<= 32 - pflen;
ip_u = ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3];
/* fill the non-prefix bits the way we need it */
range->begin = ip_u & mask;
range->end = ip_u | (~mask);
return true;
}
static bool parseLine(char const* line, struct tr_ipv4_range* range)
{
return parseLine1(line, range) || parseLine2(line, range);
return parseLine1(line, range) || parseLine2(line, range) || parseLine3(line, range);
}
static int compareAddressRangesByFirstAddress(void const* va, void const* vb)

View File

@ -6,6 +6,7 @@
*
*/
/* *INDENT-OFF* */
#if defined(CYASSL_IS_WOLFSSL)
#define API_HEADER(x) <wolfssl/x>
#define API_HEADER_CRYPT(x) API_HEADER(wolfcrypt/x)
@ -24,6 +25,7 @@
#include API_HEADER_CRYPT(random.h)
#include API_HEADER_CRYPT(sha.h)
#include API_HEADER(version.h)
/* *INDENT-ON* */
#include "transmission.h"
#include "crypto-utils.h"

View File

@ -6,6 +6,7 @@
*
*/
/* *INDENT-OFF* */
#if defined(POLARSSL_IS_MBEDTLS)
#define API_HEADER(x) <mbedtls/x>
#define API(x) mbedtls_ ## x
@ -15,6 +16,7 @@
#define API(x) x
#define API_VERSION_NUMBER POLARSSL_VERSION_NUMBER
#endif
/* *INDENT-ON* */
#include API_HEADER(arc4.h)
#include API_HEADER(base64.h)
@ -40,6 +42,11 @@
#define MY_NAME "tr_crypto_utils"
typedef API (ctr_drbg_context) api_ctr_drbg_context;
typedef API (sha1_context) api_sha1_context;
typedef API (arc4_context) api_arc4_context;
typedef API (dhm_context) api_dhm_context;
static void log_polarssl_error(int error_code, char const* file, int line)
{
if (tr_logLevelIsActive(TR_LOG_ERROR))
@ -89,9 +96,9 @@ static int my_rand(void* context UNUSED, unsigned char* buffer, size_t buffer_si
return 0;
}
static API(ctr_drbg_context)* get_rng(void)
static api_ctr_drbg_context* get_rng(void)
{
static API(ctr_drbg_context) rng;
static api_ctr_drbg_context rng;
static bool rng_initialized = false;
if (!rng_initialized)
@ -132,7 +139,7 @@ static tr_lock* get_rng_lock(void)
tr_sha1_ctx_t tr_sha1_init(void)
{
API(sha1_context)* handle = tr_new0(API(sha1_context), 1);
api_sha1_context* handle = tr_new0(api_sha1_context, 1);
#if API_VERSION_NUMBER >= 0x01030800
API(sha1_init)(handle);
@ -180,7 +187,7 @@ bool tr_sha1_final(tr_sha1_ctx_t handle, uint8_t* hash)
tr_rc4_ctx_t tr_rc4_new(void)
{
API(arc4_context)* handle = tr_new0(API(arc4_context), 1);
api_arc4_context* handle = tr_new0(api_arc4_context, 1);
#if API_VERSION_NUMBER >= 0x01030800
API(arc4_init)(handle);
@ -231,7 +238,7 @@ tr_dh_ctx_t tr_dh_new(uint8_t const* prime_num, size_t prime_num_length, uint8_t
TR_ASSERT(prime_num != NULL);
TR_ASSERT(generator_num != NULL);
API(dhm_context)* handle = tr_new0(API(dhm_context), 1);
api_dhm_context* handle = tr_new0(api_dhm_context, 1);
#if API_VERSION_NUMBER >= 0x01030800
API(dhm_init)(handle);
@ -264,7 +271,7 @@ bool tr_dh_make_key(tr_dh_ctx_t raw_handle, size_t private_key_length, uint8_t*
TR_ASSERT(raw_handle != NULL);
TR_ASSERT(public_key != NULL);
API(dhm_context)* handle = raw_handle;
api_dhm_context* handle = raw_handle;
if (public_key_length != NULL)
{
@ -279,7 +286,7 @@ tr_dh_secret_t tr_dh_agree(tr_dh_ctx_t raw_handle, uint8_t const* other_public_k
TR_ASSERT(raw_handle != NULL);
TR_ASSERT(other_public_key != NULL);
API(dhm_context)* handle = raw_handle;
api_dhm_context* handle = raw_handle;
struct tr_dh_secret* ret;
size_t secret_key_length;

View File

@ -1,7 +1,8 @@
#!/bin/sh
err=0
count=0
while [ $err -eq 0 ]; do
count=$((count+1))
count=$((count + 1))
echo starting run number $count
make check
err=$?

View File

@ -243,10 +243,12 @@ static int test_get_info(void)
tr_sys_file_close(fd, NULL);
tr_sys_path_remove(path2, NULL);
tr_sys_path_remove(path1, NULL);
/* Good directory info */
t = time(NULL);
tr_sys_dir_create(path2, 0, 0777, NULL);
check(create_symlink(path1, path2, true)); /* Win32: directory and file symlinks differ :( */
clear_path_info(&info);
check(tr_sys_path_get_info(path1, 0, &info, &err));
check_ptr(err, ==, NULL);
@ -310,9 +312,11 @@ static int test_path_exists(void)
check_ptr(err, ==, NULL);
tr_sys_path_remove(path2, NULL);
tr_sys_path_remove(path1, NULL);
/* Create directory and see that it exists (via symlink) */
tr_sys_dir_create(path2, 0, 0777, NULL);
check(create_symlink(path1, path2, true)); /* Win32: directory and file symlinks differ :( */
check(tr_sys_path_exists(path1, &err));
check_ptr(err, ==, NULL);
@ -615,9 +619,11 @@ static int test_path_resolve(void)
check(path_contains_no_symlinks(tmp));
tr_free(tmp);
tr_sys_path_remove(path2, NULL);
tr_sys_path_remove(path1, NULL);
tr_sys_dir_create(path1, 0, 0755, NULL);
tr_sys_dir_create(path1, 0, 0755, NULL);
check(create_symlink(path2, path1, true)); /* Win32: directory and file symlinks differ :( */
tmp = tr_sys_path_resolve(path2, &err);
check_str(tmp, !=, NULL);
check_ptr(err, ==, NULL);
@ -984,7 +990,7 @@ static int test_path_remove(void)
static int test_path_native_separators(void)
{
check_str(tr_sys_path_native_separators(NULL), == , NULL);
check_str(tr_sys_path_native_separators(NULL), ==, NULL);
char path1[] = "";
char path2[] = "a";

View File

@ -89,7 +89,7 @@ static int readOrWriteBytes(tr_session* session, tr_torrent* tor, int ioMode, tr
int const prealloc = (file->dnd || !doWrite) ? TR_PREALLOCATE_NONE : tor->session->preallocationMode;
if ((fd = tr_fdFileCheckout(session, tor->uniqueId, fileIndex, filename, doWrite, prealloc,
file->length)) == TR_BAD_SYS_FILE)
file->length)) == TR_BAD_SYS_FILE)
{
err = errno;
tr_logAddTorErr(tor, "tr_fdFileCheckout failed for \"%s\": %s", filename, tr_strerror(err));

View File

@ -54,7 +54,7 @@ bool libtest_check(char const* file, int line, bool pass, bool condition, char c
{
if (should_print(pass))
{
fprintf(stderr, "%s %s:%d: %s (%s)\n", pass ? "PASS" : "FAIL", file, line, condition_str, condition ? "true": "false");
fprintf(stderr, "%s %s:%d: %s (%s)\n", pass ? "PASS" : "FAIL", file, line, condition_str, condition ? "true" : "false");
}
return pass;

View File

@ -59,11 +59,12 @@ bool libtest_check_ptr(char const* file, int line, bool pass, void const* lhs, v
{ \
++current_test; \
\
bool const check_bool_lhs = (lhs); \
bool const check_bool_rhs = (rhs); \
bool const check_lhs = (lhs); \
bool const check_rhs = (rhs); \
\
if (!libtest_check_bool(__FILE__, __LINE__, check_bool_lhs op check_bool_rhs, check_bool_lhs, check_bool_rhs, #lhs, \
#op, #rhs)) \
bool const check_result = check_lhs op check_rhs; \
\
if (!libtest_check_bool(__FILE__, __LINE__, check_result, check_lhs, check_rhs, #lhs, #op, #rhs)) \
{ \
return current_test; \
} \
@ -75,11 +76,12 @@ bool libtest_check_ptr(char const* file, int line, bool pass, void const* lhs, v
{ \
++current_test; \
\
char const* const check_str_lhs = (lhs); \
char const* const check_str_rhs = (rhs); \
char const* const check_lhs = (lhs); \
char const* const check_rhs = (rhs); \
\
if (!libtest_check_str(__FILE__, __LINE__, tr_strcmp0(check_str_lhs, check_str_rhs) op 0, check_str_lhs, \
check_str_rhs, #lhs, #op, #rhs)) \
bool const check_result = tr_strcmp0(check_lhs, check_rhs) op 0; \
\
if (!libtest_check_str(__FILE__, __LINE__, check_result, check_lhs, check_rhs, #lhs, #op, #rhs)) \
{ \
return current_test; \
} \
@ -91,12 +93,13 @@ bool libtest_check_ptr(char const* file, int line, bool pass, void const* lhs, v
{ \
++current_test; \
\
void const* const check_mem_lhs = (lhs); \
void const* const check_mem_rhs = (rhs); \
size_t const check_mem_size = (size);\
void const* const check_lhs = (lhs); \
void const* const check_rhs = (rhs); \
size_t const check_mem_size = (size); \
\
if (!libtest_check_mem(__FILE__, __LINE__, tr_memcmp0(check_mem_lhs, check_mem_rhs, check_mem_size) op 0, \
check_mem_lhs, check_mem_rhs, check_mem_size, #lhs, #op, #rhs)) \
bool const check_result = tr_memcmp0(check_lhs, check_rhs, check_mem_size) op 0; \
\
if (!libtest_check_mem(__FILE__, __LINE__, check_result, check_lhs, check_rhs, check_mem_size, #lhs, #op, #rhs)) \
{ \
return current_test; \
} \
@ -108,11 +111,12 @@ bool libtest_check_ptr(char const* file, int line, bool pass, void const* lhs, v
{ \
++current_test; \
\
intmax_t const check_int_lhs = (lhs); \
intmax_t const check_int_rhs = (rhs); \
intmax_t const check_lhs = (lhs); \
intmax_t const check_rhs = (rhs); \
\
if (!libtest_check_int(__FILE__, __LINE__, check_int_lhs op check_int_rhs, check_int_lhs, check_int_rhs, #lhs, #op, \
#rhs)) \
bool const check_result = check_lhs op check_rhs; \
\
if (!libtest_check_int(__FILE__, __LINE__, check_result, check_lhs, check_rhs, #lhs, #op, #rhs)) \
{ \
return current_test; \
} \
@ -124,11 +128,12 @@ bool libtest_check_ptr(char const* file, int line, bool pass, void const* lhs, v
{ \
++current_test; \
\
uintmax_t const check_uint_lhs = (lhs); \
uintmax_t const check_uint_rhs = (rhs); \
uintmax_t const check_lhs = (lhs); \
uintmax_t const check_rhs = (rhs); \
\
if (!libtest_check_uint(__FILE__, __LINE__, check_uint_lhs op check_uint_rhs, check_uint_lhs, check_uint_rhs, #lhs, \
#op, #rhs)) \
bool const check_result = check_lhs op check_rhs; \
\
if (!libtest_check_uint(__FILE__, __LINE__, check_result, check_lhs, check_rhs, #lhs, #op, #rhs)) \
{ \
return current_test; \
} \
@ -140,11 +145,12 @@ bool libtest_check_ptr(char const* file, int line, bool pass, void const* lhs, v
{ \
++current_test; \
\
void const* const check_ptr_lhs = (lhs); \
void const* const check_ptr_rhs = (rhs); \
void const* const check_lhs = (lhs); \
void const* const check_rhs = (rhs); \
\
if (!libtest_check_ptr(__FILE__, __LINE__, check_ptr_lhs op check_ptr_rhs, check_ptr_lhs, check_ptr_rhs, #lhs, #op, \
#rhs)) \
bool const check_result = check_lhs op check_rhs; \
\
if (!libtest_check_ptr(__FILE__, __LINE__, check_result, check_lhs, check_rhs, #lhs, #op, #rhs)) \
{ \
return current_test; \
} \

View File

@ -28,7 +28,7 @@ typedef struct tr_list
}
tr_list;
typedef int (* TrListCompareFunc)(void const* a, void const* b);
typedef tr_voidptr_compare_func TrListCompareFunc;
typedef void (* TrListForeachFunc)(void*);
/**

View File

@ -27,7 +27,7 @@ static inline bool tr_logLevelIsActive(tr_log_level level)
return tr_logGetLevel() >= level;
}
void tr_logAddMessage(char const* file, int line, tr_log_level level, char const* torrent, char const* fmt, ...)
void tr_logAddMessage(char const* file, int line, tr_log_level level, char const* torrent, char const* fmt, ...) \
TR_GNUC_PRINTF(5, 6);
#define tr_logAddNamed(level, name, ...) \
@ -61,7 +61,7 @@ tr_sys_file_t tr_logGetFile(void);
/** @brief return true if deep logging has been enabled by the user; false otherwise */
bool tr_logGetDeepEnabled(void);
void tr_logAddDeep(char const* file, int line, char const* name, char const* fmt, ...) TR_GNUC_PRINTF(4, 5)
void tr_logAddDeep(char const* file, int line, char const* name, char const* fmt, ...) TR_GNUC_PRINTF(4, 5) \
TR_GNUC_NONNULL(1, 4);
#define tr_logAddDeepNamed(name, ...) \

View File

@ -111,7 +111,8 @@ static int test_single_file(void)
}
static int test_single_directory_impl(tr_tracker_info const* trackers, size_t const trackerCount, void const** payloads,
size_t const* payloadSizes, size_t const payloadCount, char const* comment, bool const isPrivate)
size_t const* payloadSizes, size_t const payloadCount, char const* comment,
bool const isPrivate)
{
char* sandbox;
char* torrent_file;
@ -211,7 +212,8 @@ static int test_single_directory_impl(tr_tracker_info const* trackers, size_t co
}
static int test_single_directory_random_payload_impl(tr_tracker_info const* trackers, size_t const trackerCount,
size_t const maxFileCount, size_t const maxFileSize, char const* comment, bool const isPrivate)
size_t const maxFileCount, size_t const maxFileSize, char const* comment,
bool const isPrivate)
{
void** payloads;
size_t* payloadSizes;

View File

@ -56,7 +56,7 @@ static int test_metainfo(void)
{
int expected_benc_err;
int expected_parse_result;
const void* benc;
void const* benc;
}
const metainfo[] =
{

View File

@ -89,7 +89,7 @@ static char* getTorrentFilename(tr_session const* session, tr_info const* inf, e
static bool path_component_is_suspicious(char const* component)
{
return component == NULL || strpbrk(component, PATH_DELIMITER_CHARS) != NULL || strcmp(component, ".") == 0 ||
strcmp(component, "..") == 0;
strcmp(component, "..") == 0;
}
static bool getfile(char** setme, char const* root, tr_variant* path, struct evbuffer* buf)
@ -626,7 +626,8 @@ static char const* tr_metainfoParseImpl(tr_session const* session, tr_info* inf,
/* files */
if (!isMagnet)
{
if ((str = parseFiles(inf, tr_variantDictFind(infoDict, TR_KEY_files), tr_variantDictFind(infoDict, TR_KEY_length))) != NULL)
if ((str = parseFiles(inf, tr_variantDictFind(infoDict, TR_KEY_files), tr_variantDictFind(infoDict,
TR_KEY_length))) != NULL)
{
return str;
}

View File

@ -375,7 +375,8 @@ struct tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const
return ret;
}
struct tr_peer_socket tr_netOpenPeerUTPSocket(tr_session* session, tr_address const* addr, tr_port port, bool clientIsSeed UNUSED)
struct tr_peer_socket tr_netOpenPeerUTPSocket(tr_session* session, tr_address const* addr, tr_port port,
bool clientIsSeed UNUSED)
{
struct tr_peer_socket ret = TR_PEER_SOCKET_INIT;
@ -776,5 +777,5 @@ static bool isMartianAddr(struct tr_address const* a)
bool tr_address_is_valid_for_peers(tr_address const* addr, tr_port port)
{
return port != 0 && tr_address_is_valid(addr) && !isIPv6LinkLocalAddress(addr) && !isIPv4MappedAddress(addr) &&
!isMartianAddr(addr);
!isMartianAddr(addr);
}

View File

@ -128,7 +128,7 @@ void tr_peerIoUnrefImpl(char const* file, int line, tr_peerIo* io);
static inline bool tr_isPeerIo(tr_peerIo const* io)
{
return io != NULL && io->magicNumber == PEER_IO_MAGIC_NUMBER && io->refCount >= 0 && tr_isBandwidth(&io->bandwidth) &&
tr_address_is_valid(&io->addr);
tr_address_is_valid(&io->addr);
}
/**

View File

@ -149,7 +149,7 @@ struct peer_atom
static bool tr_isAtom(struct peer_atom const* atom)
{
return atom != NULL && atom->fromFirst < TR_PEER_FROM__MAX && atom->fromBest < TR_PEER_FROM__MAX &&
tr_address_is_valid(&atom->addr);
tr_address_is_valid(&atom->addr);
}
#endif
@ -411,7 +411,7 @@ static bool peerIsInUse(tr_swarm const* cs, struct peer_atom const* atom)
TR_ASSERT(swarmIsLocked(s));
return atom->peer != NULL || getExistingHandshake(&s->outgoingHandshakes, &atom->addr) ||
getExistingHandshake(&s->manager->incomingHandshakes, &atom->addr);
getExistingHandshake(&s->manager->incomingHandshakes, &atom->addr);
}
static inline bool replicationExists(tr_swarm const* s)
@ -2639,7 +2639,7 @@ void tr_peerMgrTorrentAvailability(tr_torrent const* tor, int8_t* tab, unsigned
if (tr_torrentHasMetadata(tor))
{
int const peerCount = tr_ptrArraySize(&tor->swarm->peers);
tr_peer const** peers = (const tr_peer**)tr_ptrArrayBase(&tor->swarm->peers);
tr_peer const** peers = (tr_peer const**)tr_ptrArrayBase(&tor->swarm->peers);
float const interval = tor->info.pieceCount / (float)tabCount;
bool const isSeed = tr_torrentGetCompleteness(tor) == TR_SEED;
@ -3643,8 +3643,7 @@ static int comparePeerLiveliness(void const* va, void const* vb)
return 0;
}
static void sortPeersByLivelinessImpl(tr_peer** peers, void** clientData, int n, uint64_t now, int (* compare)(void const* va,
void const* vb))
static void sortPeersByLivelinessImpl(tr_peer** peers, void** clientData, int n, uint64_t now, tr_voidptr_compare_func compare)
{
struct peer_liveliness* lives;
struct peer_liveliness* l;

View File

@ -1086,9 +1086,9 @@ static void parseUtMetadata(tr_peerMsgs* msgs, uint32_t msglen, struct evbuffer*
if (tr_variantFromBencFull(&dict, tmp, msglen, NULL, &benc_end) == 0)
{
tr_variantDictFindInt(&dict, TR_KEY_msg_type, &msg_type);
tr_variantDictFindInt(&dict, TR_KEY_piece, &piece);
tr_variantDictFindInt(&dict, TR_KEY_total_size, &total_size);
(void)tr_variantDictFindInt(&dict, TR_KEY_msg_type, &msg_type);
(void)tr_variantDictFindInt(&dict, TR_KEY_piece, &piece);
(void)tr_variantDictFindInt(&dict, TR_KEY_total_size, &total_size);
tr_variantFree(&dict);
}
@ -1159,10 +1159,15 @@ static void parseUtPex(tr_peerMsgs* msgs, uint32_t msglen, struct evbuffer* inbu
{
tr_pex* pex;
size_t n;
size_t added_f_len = 0;
uint8_t const* added_f = NULL;
size_t added_f_len;
uint8_t const* added_f;
if (!tr_variantDictFindRaw(&val, TR_KEY_added_f, &added_f, &added_f_len))
{
added_f_len = 0;
added_f = NULL;
}
tr_variantDictFindRaw(&val, TR_KEY_added_f, &added_f, &added_f_len);
pex = tr_peerMgrCompactToPex(added, added_len, added_f, added_f_len, &n);
n = MIN(n, MAX_PEX_PEER_COUNT);
@ -1186,10 +1191,15 @@ static void parseUtPex(tr_peerMsgs* msgs, uint32_t msglen, struct evbuffer* inbu
{
tr_pex* pex;
size_t n;
size_t added_f_len = 0;
uint8_t const* added_f = NULL;
size_t added_f_len;
uint8_t const* added_f;
if (!tr_variantDictFindRaw(&val, TR_KEY_added6_f, &added_f, &added_f_len))
{
added_f_len = 0;
added_f = NULL;
}
tr_variantDictFindRaw(&val, TR_KEY_added6_f, &added_f, &added_f_len);
pex = tr_peerMgrCompact6ToPex(added, added_len, added_f, added_f_len, &n);
n = MIN(n, MAX_PEX_PEER_COUNT);
@ -2316,8 +2326,8 @@ typedef void (* tr_set_func)(void* element, void* userData);
* @param in_both called for items that are in both sets
* @param userData user data passed along to in_a, in_b, and in_both
*/
static void tr_set_compare(void const* va, size_t aCount, void const* vb, size_t bCount, int (* compare)(void const* a,
void const* b), size_t elementSize, tr_set_func in_a_cb, tr_set_func in_b_cb, tr_set_func in_both_cb, void* userData)
static void tr_set_compare(void const* va, size_t aCount, void const* vb, size_t bCount, tr_voidptr_compare_func compare,
size_t elementSize, tr_set_func in_a_cb, tr_set_func in_b_cb, tr_set_func in_both_cb, void* userData)
{
uint8_t const* a = va;
uint8_t const* b = vb;

View File

@ -386,7 +386,7 @@ static int64_t getquota(char const* device)
#ifdef __APPLE__
return freespace < 0 ? 0 : freespace;
#else
return freespace < 0 ? 0 : freespace * 1024;
return freespace < 0 ? 0 : (freespace * 1024);
#endif
}
@ -426,7 +426,7 @@ static int64_t getxfsquota(char* device)
}
freespace = limit - (dq.d_bcount >> 1);
return freespace < 0 ? 0 : freespace * 1024;
return freespace < 0 ? 0 : (freespace * 1024);
}
/* something went wrong */

View File

@ -101,7 +101,7 @@ void tr_ptrArrayErase(tr_ptrArray* t, int begin, int end)
***
**/
int tr_ptrArrayLowerBound(tr_ptrArray const* t, void const* ptr, int (* compare)(void const*, void const*), bool* exact_match)
int tr_ptrArrayLowerBound(tr_ptrArray const* t, void const* ptr, tr_voidptr_compare_func compare, bool* exact_match)
{
int pos = -1;
bool match = false;
@ -168,7 +168,7 @@ int tr_ptrArrayLowerBound(tr_ptrArray const* t, void const* ptr, int (* compare)
#else
static void assertArrayIsSortedAndUnique(tr_ptrArray const* t, int (* compare)(void const*, void const*))
static void assertArrayIsSortedAndUnique(tr_ptrArray const* t, tr_voidptr_compare_func compare)
{
for (int i = 0; i < t->n_items - 2; ++i)
{
@ -176,7 +176,7 @@ static void assertArrayIsSortedAndUnique(tr_ptrArray const* t, int (* compare)(v
}
}
static void assertIndexIsSortedAndUnique(tr_ptrArray const* t, int pos, int (* compare)(void const*, void const*))
static void assertIndexIsSortedAndUnique(tr_ptrArray const* t, int pos, tr_voidptr_compare_func compare)
{
if (pos > 0)
{
@ -191,7 +191,7 @@ static void assertIndexIsSortedAndUnique(tr_ptrArray const* t, int pos, int (* c
#endif
int tr_ptrArrayInsertSorted(tr_ptrArray* t, void* ptr, int (* compare)(void const*, void const*))
int tr_ptrArrayInsertSorted(tr_ptrArray* t, void* ptr, tr_voidptr_compare_func compare)
{
int pos;
int ret;
@ -204,14 +204,14 @@ int tr_ptrArrayInsertSorted(tr_ptrArray* t, void* ptr, int (* compare)(void cons
return ret;
}
void* tr_ptrArrayFindSorted(tr_ptrArray* t, void const* ptr, int (* compare)(void const*, void const*))
void* tr_ptrArrayFindSorted(tr_ptrArray* t, void const* ptr, tr_voidptr_compare_func compare)
{
bool match = false;
int const pos = tr_ptrArrayLowerBound(t, ptr, compare, &match);
return match ? t->items[pos] : NULL;
}
static void* tr_ptrArrayRemoveSortedValue(tr_ptrArray* t, void const* ptr, int (* compare)(void const*, void const*))
static void* tr_ptrArrayRemoveSortedValue(tr_ptrArray* t, void const* ptr, tr_voidptr_compare_func compare)
{
int pos;
bool match;
@ -232,7 +232,7 @@ static void* tr_ptrArrayRemoveSortedValue(tr_ptrArray* t, void const* ptr, int (
return ret;
}
void tr_ptrArrayRemoveSortedPointer(tr_ptrArray* t, void const* ptr, int (* compare)(void const*, void const*))
void tr_ptrArrayRemoveSortedPointer(tr_ptrArray* t, void const* ptr, tr_voidptr_compare_func compare)
{
void* removed = tr_ptrArrayRemoveSortedValue(t, ptr, compare);

View File

@ -31,7 +31,7 @@ typedef struct tr_ptrArray
}
tr_ptrArray;
typedef int (* PtrArrayCompareFunc)(void const* a, void const* b);
typedef tr_voidptr_compare_func PtrArrayCompareFunc;
typedef void (* PtrArrayForeachFunc)(void*);
@ -113,18 +113,17 @@ static inline bool tr_ptrArrayEmpty(tr_ptrArray const* a)
return tr_ptrArraySize(a) == 0;
}
int tr_ptrArrayLowerBound(tr_ptrArray const* array, void const* key, int (* compare)(void const* arrayItem, void const* key),
bool* exact_match);
int tr_ptrArrayLowerBound(tr_ptrArray const* array, void const* key, tr_voidptr_compare_func compare, bool* exact_match);
/** @brief Insert a pointer into the array at the position determined by the sort function
@return the index of the stored pointer */
int tr_ptrArrayInsertSorted(tr_ptrArray* array, void* value, int (* compare)(void const*, void const*));
int tr_ptrArrayInsertSorted(tr_ptrArray* array, void* value, tr_voidptr_compare_func compare);
/** @brief Remove this specific pointer from a sorted ptrarray */
void tr_ptrArrayRemoveSortedPointer(tr_ptrArray* t, void const* ptr, int (* compare)(void const*, void const*));
void tr_ptrArrayRemoveSortedPointer(tr_ptrArray* t, void const* ptr, tr_voidptr_compare_func compare);
/** @brief Find a pointer from an array sorted by the specified sort function
@return the matching pointer, or NULL if no match was found */
void* tr_ptrArrayFindSorted(tr_ptrArray* array, void const* key, int (* compare)(void const*, void const*));
void* tr_ptrArrayFindSorted(tr_ptrArray* array, void const* key, tr_voidptr_compare_func compare);
/* @} */

View File

@ -163,6 +163,7 @@ static struct tr_key_struct const my_static[] =
{ "isStalled", 9 },
{ "isUTP", 5 },
{ "isUploadingTo", 13 },
{ "labels", 6 },
{ "lastAnnouncePeerCount", 21 },
{ "lastAnnounceResult", 18 },
{ "lastAnnounceStartTime", 21 },

View File

@ -165,6 +165,7 @@ enum
TR_KEY_isStalled,
TR_KEY_isUTP,
TR_KEY_isUploadingTo,
TR_KEY_labels,
TR_KEY_lastAnnouncePeerCount,
TR_KEY_lastAnnounceResult,
TR_KEY_lastAnnounceStartTime,

View File

@ -111,6 +111,44 @@ static uint64_t loadPeers(tr_variant* dict, tr_torrent* tor)
****
***/
static void saveLabels(tr_variant* dict, tr_torrent const* tor)
{
int const n = tr_ptrArraySize(&tor->labels);
tr_variant* list = tr_variantDictAddList(dict, TR_KEY_labels, n);
char const* const* labels = (char const* const*)tr_ptrArrayBase(&tor->labels);
for (int i = 0; i < n; ++i)
{
tr_variantListAddStr(list, labels[i]);
}
}
static uint64_t loadLabels(tr_variant* dict, tr_torrent* tor)
{
uint64_t ret = 0;
tr_variant* list;
if (tr_variantDictFindList(dict, TR_KEY_labels, &list))
{
int const n = tr_variantListSize(list);
char const* str;
size_t str_len;
for (int i = 0; i < n; ++i)
{
if (tr_variantGetStr(tr_variantListChild(list, i), &str, &str_len) && str != NULL && str_len != 0)
{
tr_ptrArrayAppend(&tor->labels, tr_strndup(str, str_len));
}
}
ret = TR_FR_LABELS;
}
return ret;
}
/***
****
***/
static void saveDND(tr_variant* dict, tr_torrent const* tor)
{
tr_variant* list;
@ -735,6 +773,7 @@ void tr_torrentSaveResume(tr_torrent* tor)
saveIdleLimits(&top, tor);
saveFilenames(&top, tor);
saveName(&top, tor);
saveLabels(&top, tor);
filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH);
@ -943,6 +982,11 @@ static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad, bool* didRe
fieldsLoaded |= loadName(&top, tor);
}
if ((fieldsToLoad & TR_FR_LABELS) != 0)
{
fieldsLoaded |= loadLabels(&top, tor);
}
/* loading the resume file triggers of a lot of changes,
* but none of them needs to trigger a re-saving of the
* same resume information... */

View File

@ -35,7 +35,8 @@ enum
TR_FR_TIME_SEEDING = (1 << 18),
TR_FR_TIME_DOWNLOADING = (1 << 19),
TR_FR_FILENAMES = (1 << 20),
TR_FR_NAME = (1 << 21)
TR_FR_NAME = (1 << 21),
TR_FR_LABELS = (1 << 22)
};
/**

View File

@ -555,7 +555,7 @@ static bool isIPAddressWithOptionalPort(char const* host)
int address_len = sizeof(address);
/* TODO: move to net.{c,h} */
return evutil_parse_sockaddr_port(host, (struct sockaddr *) &address, &address_len) != -1;
return evutil_parse_sockaddr_port(host, (struct sockaddr*)&address, &address_len) != -1;
}
static bool isHostnameAllowed(tr_rpc_server const* server, struct evhttp_request* req)
@ -672,7 +672,8 @@ static void handle_request(struct evhttp_request* req, void* arg)
{
evhttp_add_header(req->output_headers, "WWW-Authenticate", "Basic realm=\"" MY_REALM "\"");
server->loginattempts++;
char* unauthuser = tr_strdup_printf("<p>Unauthorized User. %d unsuccessful login attempts.</p>", server->loginattempts);
char* unauthuser = tr_strdup_printf("<p>Unauthorized User. %d unsuccessful login attempts.</p>",
server->loginattempts);
send_simple_response(req, 401, unauthuser);
tr_free(unauthuser);
tr_free(user);
@ -1236,7 +1237,8 @@ tr_rpc_server* tr_rpcInit(tr_session* session, tr_variant* settings)
if (s->isEnabled)
{
tr_logAddNamedInfo(MY_NAME, _("Serving RPC and Web requests on %s:%d%s"), tr_rpcGetBindAddress(s), (int)s->port, s->url);
tr_logAddNamedInfo(MY_NAME, _("Serving RPC and Web requests on %s:%d%s"), tr_rpcGetBindAddress(s), (int)s->port,
s->url);
tr_runInEventThread(session, startServer, s);
if (s->isWhitelistEnabled)

View File

@ -397,6 +397,17 @@ static char const* torrentVerify(tr_session* session, tr_variant* args_in, tr_va
****
***/
static void addLabels(tr_torrent const* tor, tr_variant* list)
{
int const labelsCount = tr_ptrArraySize(&tor->labels);
tr_variantInitList(list, labelsCount);
char const* const* labels = (char const* const*)tr_ptrArrayBase(&tor->labels);
for (int i = 0; i < labelsCount; ++i)
{
tr_variantListAddStr(list, labels[i]);
}
}
static void addFileStats(tr_torrent const* tor, tr_variant* list)
{
tr_file_index_t n;
@ -632,6 +643,10 @@ static void addField(tr_torrent* const tor, tr_info const* const inf, tr_stat co
tr_variantDictAddBool(d, key, st->isStalled);
break;
case TR_KEY_labels:
addLabels(tor, tr_variantDictAdd(d, key));
break;
case TR_KEY_leftUntilDone:
tr_variantDictAddInt(d, key, st->leftUntilDone);
break;
@ -897,12 +912,14 @@ static char const* torrentGet(tr_session* session, tr_variant* args_in, tr_varia
while ((d = tr_variantListChild(&session->removedTorrents, n++)) != NULL)
{
int64_t intVal;
int64_t date;
int64_t id;
if (tr_variantDictFindInt(d, TR_KEY_date, &intVal) && intVal >= now - interval)
if (tr_variantDictFindInt(d, TR_KEY_date, &date) &&
date >= now - interval &&
tr_variantDictFindInt(d, TR_KEY_id, &id))
{
tr_variantDictFindInt(d, TR_KEY_id, &intVal);
tr_variantListAddInt(removed_out, intVal);
tr_variantListAddInt(removed_out, id);
}
}
}
@ -927,6 +944,67 @@ static char const* torrentGet(tr_session* session, tr_variant* args_in, tr_varia
****
***/
static char const* setLabels(tr_torrent* tor, tr_variant* list)
{
int const n = tr_variantListSize(list);
char const* errmsg = NULL;
tr_ptrArray labels = TR_PTR_ARRAY_INIT;
int labelcount = 0;
for (int i = 0; i < n; i++)
{
char const* str;
size_t str_len;
if (tr_variantGetStr(tr_variantListChild(list, i), &str, &str_len) && str != NULL)
{
char* label = tr_strndup(str, str_len);
tr_strstrip(label);
if (*label == '\0')
{
errmsg = "labels cannot be empty";
}
if (errmsg == NULL && strchr(str, ',') != NULL)
{
errmsg = "labels cannot contain comma (,) character";
}
if (errmsg == NULL)
{
bool dup = false;
for (int j = 0; j < labelcount; j++)
{
if (tr_strcmp0(label, (char*)tr_ptrArrayNth(&labels, j)) == 0)
{
dup = true;
break;
}
}
if (dup)
{
errmsg = "labels cannot contain duplicates";
}
}
tr_ptrArrayAppend(&labels, label);
labelcount++;
if (errmsg != NULL)
{
break;
}
}
}
if (errmsg == NULL)
{
tr_torrentSetLabels(tor, &labels);
}
tr_ptrArrayDestruct(&labels, tr_free);
return errmsg;
}
static char const* setFilePriorities(tr_torrent* tor, int priority, tr_variant* list)
{
int64_t tmp;
@ -1226,8 +1304,7 @@ static char const* torrentSet(tr_session* session, tr_variant* args_in, tr_varia
{
int64_t tmp;
double d;
tr_variant* files;
tr_variant* trackers;
tr_variant* tmp_variant;
bool boolVal;
tr_torrent* tor;
@ -1241,14 +1318,19 @@ static char const* torrentSet(tr_session* session, tr_variant* args_in, tr_varia
}
}
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_files_unwanted, &files))
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_labels, &tmp_variant))
{
errmsg = setFileDLs(tor, false, files);
errmsg = setLabels(tor, tmp_variant);
}
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_files_wanted, &files))
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_files_unwanted, &tmp_variant))
{
errmsg = setFileDLs(tor, true, files);
errmsg = setFileDLs(tor, false, tmp_variant);
}
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_files_wanted, &tmp_variant))
{
errmsg = setFileDLs(tor, true, tmp_variant);
}
if (tr_variantDictFindInt(args_in, TR_KEY_peer_limit, &tmp))
@ -1256,19 +1338,19 @@ static char const* torrentSet(tr_session* session, tr_variant* args_in, tr_varia
tr_torrentSetPeerLimit(tor, tmp);
}
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_priority_high, &files))
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_priority_high, &tmp_variant))
{
errmsg = setFilePriorities(tor, TR_PRI_HIGH, files);
errmsg = setFilePriorities(tor, TR_PRI_HIGH, tmp_variant);
}
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_priority_low, &files))
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_priority_low, &tmp_variant))
{
errmsg = setFilePriorities(tor, TR_PRI_LOW, files);
errmsg = setFilePriorities(tor, TR_PRI_LOW, tmp_variant);
}
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_priority_normal, &files))
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_priority_normal, &tmp_variant))
{
errmsg = setFilePriorities(tor, TR_PRI_NORMAL, files);
errmsg = setFilePriorities(tor, TR_PRI_NORMAL, tmp_variant);
}
if (tr_variantDictFindInt(args_in, TR_KEY_downloadLimit, &tmp))
@ -1321,19 +1403,19 @@ static char const* torrentSet(tr_session* session, tr_variant* args_in, tr_varia
tr_torrentSetQueuePosition(tor, tmp);
}
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_trackerAdd, &trackers))
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_trackerAdd, &tmp_variant))
{
errmsg = addTrackerUrls(tor, trackers);
errmsg = addTrackerUrls(tor, tmp_variant);
}
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_trackerRemove, &trackers))
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_trackerRemove, &tmp_variant))
{
errmsg = removeTrackers(tor, trackers);
errmsg = removeTrackers(tor, tmp_variant);
}
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_trackerReplace, &trackers))
if (errmsg == NULL && tr_variantDictFindList(args_in, TR_KEY_trackerReplace, &tmp_variant))
{
errmsg = replaceTrackers(tor, trackers);
errmsg = replaceTrackers(tor, tmp_variant);
}
notify(session, TR_RPC_TORRENT_CHANGED, tor);

View File

@ -34,10 +34,10 @@ static int test_spawn_async_missing_exe(void)
tr_error* error = NULL;
bool const ret = tr_spawn_async(args, NULL, NULL, &error);
check_bool(ret, == , false);
check_ptr(error, != , NULL);
check_int(error->code, != , 0);
check_str(error->message, != , NULL);
check_bool(ret, ==, false);
check_ptr(error, !=, NULL);
check_int(error->code, !=, 0);
check_str(error->message, !=, NULL);
tr_error_clear(&error);
@ -89,12 +89,12 @@ static int test_spawn_async_args(void)
check_str(buffer, ==, test_arg_2);
check(tr_sys_file_read_line(fd, buffer, sizeof(buffer), NULL));
check_str(buffer, == , test_arg_3);
check_str(buffer, ==, test_arg_3);
if (allow_batch_metachars)
{
check(tr_sys_file_read_line(fd, buffer, sizeof(buffer), NULL));
check_str(buffer, == , test_arg_4);
check_str(buffer, ==, test_arg_4);
}
check(!tr_sys_file_read_line(fd, buffer, sizeof(buffer), NULL));

View File

@ -509,7 +509,7 @@ static bool tr_torrentIsSeedIdleLimitDone(tr_torrent* tor)
{
uint16_t idleMinutes;
return tr_torrentGetSeedIdle(tor, &idleMinutes) &&
difftime(tr_time(), MAX(tor->startDate, tor->activityDate)) >= idleMinutes * 60u;
difftime(tr_time(), MAX(tor->startDate, tor->activityDate)) >= idleMinutes * 60u;
}
/***
@ -937,6 +937,7 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
tor->uniqueId = nextUniqueId++;
tor->magicNumber = TORRENT_MAGIC_NUMBER;
tor->queuePosition = session->torrentCount;
tor->labels = TR_PTR_ARRAY_INIT;
tr_sha1(tor->obfuscatedHash, "req2", 4, tor->info.hash, SHA_DIGEST_LENGTH, NULL);
@ -1317,7 +1318,7 @@ static time_t torrentGetIdleSecs(tr_torrent const* tor)
bool tr_torrentIsStalled(tr_torrent const* tor)
{
return tr_sessionGetQueueStalledEnabled(tor->session) &&
torrentGetIdleSecs(tor) > tr_sessionGetQueueStalledMinutes(tor->session) * 60;
torrentGetIdleSecs(tor) > tr_sessionGetQueueStalledMinutes(tor->session) * 60;
}
static double getVerifyProgress(tr_torrent const* tor)
@ -1739,6 +1740,7 @@ static void freeTorrent(tr_torrent* tor)
TR_ASSERT(queueIsSequenced(session));
tr_bandwidthDestruct(&tor->bandwidth);
tr_ptrArrayDestruct(&tor->labels, tr_free);
tr_metainfoFree(inf);
memset(tor, ~0, sizeof(tr_torrent));
@ -2318,21 +2320,21 @@ void tr_torrentRecheckCompleteness(tr_torrent* tor)
fireCompletenessChange(tor, completeness, wasRunning);
if (tr_torrentIsSeed(tor))
if (tr_torrentIsSeed(tor) && wasLeeching && wasRunning)
{
if (wasLeeching && wasRunning)
{
/* if completeness was TR_LEECH then the seed limit check will have been skipped in bandwidthPulse */
tr_torrentCheckSeedLimit(tor);
}
if (tr_sessionIsTorrentDoneScriptEnabled(tor->session))
{
torrentCallScript(tor, tr_sessionGetTorrentDoneScript(tor->session));
}
/* if completeness was TR_LEECH, the seed limit check
will have been skipped in bandwidthPulse */
tr_torrentCheckSeedLimit(tor);
}
tr_torrentSetDirty(tor);
if (tr_torrentIsSeed(tor) && tr_sessionIsTorrentDoneScriptEnabled(tor->session))
{
tr_torrentSave(tor);
torrentCallScript(tor, tr_sessionGetTorrentDoneScript(tor->session));
}
}
tr_torrentUnlock(tor);
@ -2522,6 +2524,30 @@ void tr_torrentSetFileDLs(tr_torrent* tor, tr_file_index_t const* files, tr_file
****
***/
void tr_torrentSetLabels(tr_torrent* tor, tr_ptrArray* labels)
{
TR_ASSERT(tr_isTorrent(tor));
tr_torrentLock(tor);
tr_ptrArrayDestruct(&tor->labels, tr_free);
tor->labels = TR_PTR_ARRAY_INIT;
char** l = (char**)tr_ptrArrayBase(labels);
int const n = tr_ptrArraySize(labels);
for (int i = 0; i < n; i++)
{
tr_ptrArrayAppend(&tor->labels, tr_strdup(l[i]));
}
tr_torrentSetDirty(tor);
tr_torrentUnlock(tor);
}
/***
****
***/
tr_priority_t tr_torrentGetPriority(tr_torrent const* tor)
{
TR_ASSERT(tr_isTorrent(tor));
@ -3769,7 +3795,7 @@ void tr_torrentSetQueueStartCallback(tr_torrent* torrent, void (* callback)(tr_t
static bool renameArgsAreValid(char const* oldpath, char const* newname)
{
return oldpath != NULL && *oldpath != '\0' && newname != NULL && *newname != '\0' && strcmp(newname, ".") != 0 &&
strcmp(newname, "..") != 0 && strchr(newname, TR_PATH_DELIMITER) == NULL;
strcmp(newname, "..") != 0 && strchr(newname, TR_PATH_DELIMITER) == NULL;
}
static tr_file_index_t* renameFindAffectedFiles(tr_torrent* tor, char const* oldpath, size_t* setme_n)

View File

@ -17,6 +17,7 @@
#include "session.h" /* tr_sessionLock(), tr_sessionUnlock() */
#include "tr-assert.h"
#include "utils.h" /* TR_GNUC_PRINTF */
#include "ptrarray.h"
struct tr_torrent_tiers;
struct tr_magnet_info;
@ -42,6 +43,8 @@ void tr_ctorInitTorrentWanted(tr_ctor const* ctor, tr_torrent* tor);
/* just like tr_torrentSetFileDLs but doesn't trigger a fastresume save */
void tr_torrentInitFileDLs(tr_torrent* tor, tr_file_index_t const* files, tr_file_index_t fileCount, bool do_download);
void tr_torrentSetLabels(tr_torrent* tor, tr_ptrArray* labels);
void tr_torrentRecheckCompleteness(tr_torrent*);
void tr_torrentSetHasPiece(tr_torrent* tor, tr_piece_index_t pieceIndex, bool has);
@ -240,6 +243,8 @@ struct tr_torrent
uint16_t idleLimitMinutes;
tr_idlelimit idleLimitMode;
bool finishedSeedingByIdle;
tr_ptrArray labels;
};
static inline tr_torrent* tr_torrentNext(tr_session* session, tr_torrent* current)

View File

@ -517,7 +517,8 @@ bool tr_lpdSendAnnounce(tr_torrent const* t)
/* destination address info has already been set up in tr_lpdInit(),
* so we refrain from preparing another sockaddr_in here */
int res = sendto(lpd_socket2, (void const*)query, len, 0, (struct sockaddr const*)&lpd_mcastAddr, sizeof(lpd_mcastAddr));
int res = sendto(lpd_socket2, (void const*)query, len, 0, (struct sockaddr const*)&lpd_mcastAddr,
sizeof(lpd_mcastAddr));
if (res != len)
{

View File

@ -140,7 +140,7 @@
#else
#define TR_STATIC_ASSERT(x, msg) \
{ \
typedef char __tr_static_check__[(x) ? 1 : -1] UNUSED; \
typedef char __tr_static_check__ [(x) ? 1 : -1] UNUSED; \
}
#endif

View File

@ -49,6 +49,8 @@ struct tr_variant;
typedef int8_t tr_priority_t;
typedef int (* tr_voidptr_compare_func)(void const* lhs, void const* rhs);
#define TR_RPC_SESSION_ID_HEADER "X-Transmission-Session-Id"
typedef enum

View File

@ -811,7 +811,7 @@ bool tr_urlIsValidTracker(char const* url)
size_t const url_len = strlen(url);
return isValidURLChars(url, url_len) && tr_urlParse(url, url_len, NULL, NULL, NULL, NULL) &&
(memcmp(url, "http://", 7) == 0 || memcmp(url, "https://", 8) == 0 || memcmp(url, "udp://", 6) == 0);
(memcmp(url, "http://", 7) == 0 || memcmp(url, "https://", 8) == 0 || memcmp(url, "udp://", 6) == 0);
}
bool tr_urlIsValid(char const* url, size_t url_len)
@ -827,8 +827,8 @@ bool tr_urlIsValid(char const* url, size_t url_len)
}
return isValidURLChars(url, url_len) && tr_urlParse(url, url_len, NULL, NULL, NULL, NULL) &&
(memcmp(url, "http://", 7) == 0 || memcmp(url, "https://", 8) == 0 || memcmp(url, "ftp://", 6) == 0 ||
memcmp(url, "sftp://", 7) == 0);
(memcmp(url, "http://", 7) == 0 || memcmp(url, "https://", 8) == 0 || memcmp(url, "ftp://", 6) == 0 ||
memcmp(url, "sftp://", 7) == 0);
}
bool tr_addressIsIP(char const* str)
@ -979,8 +979,8 @@ void tr_removeElementFromArray(void* array, unsigned int index_to_remove, size_t
sizeof_element * (--nmemb - index_to_remove));
}
int tr_lowerBound(void const* key, void const* base, size_t nmemb, size_t size, int (* compar)(void const* key,
void const* arrayMember), bool* exact_match)
int tr_lowerBound(void const* key, void const* base, size_t nmemb, size_t size, tr_voidptr_compare_func compar,
bool* exact_match)
{
size_t first = 0;
char const* cbase = base;
@ -1038,7 +1038,7 @@ int tr_lowerBound(void const* key, void const* base, size_t nmemb, size_t size,
} \
while (0)
static size_t quickfindPartition(char* base, size_t left, size_t right, size_t size, int (* compar)(void const*, void const*),
static size_t quickfindPartition(char* base, size_t left, size_t right, size_t size, tr_voidptr_compare_func compar,
size_t pivotIndex)
{
size_t storeIndex;
@ -1081,8 +1081,7 @@ static size_t quickfindPartition(char* base, size_t left, size_t right, size_t s
return storeIndex;
}
static void quickfindFirstK(char* base, size_t left, size_t right, size_t size, int (* compar)(void const*, void const*),
size_t k)
static void quickfindFirstK(char* base, size_t left, size_t right, size_t size, tr_voidptr_compare_func compar, size_t k)
{
if (right > left)
{
@ -1103,7 +1102,7 @@ static void quickfindFirstK(char* base, size_t left, size_t right, size_t size,
#ifdef TR_ENABLE_ASSERTS
static void checkBestScoresComeFirst(char* base, size_t nmemb, size_t size, int (* compar)(void const*, void const*), size_t k)
static void checkBestScoresComeFirst(char* base, size_t nmemb, size_t size, tr_voidptr_compare_func compar, size_t k)
{
size_t worstFirstPos = 0;
@ -1128,7 +1127,7 @@ static void checkBestScoresComeFirst(char* base, size_t nmemb, size_t size, int
#endif
void tr_quickfindFirstK(void* base, size_t nmemb, size_t size, int (* compar)(void const*, void const*), size_t k)
void tr_quickfindFirstK(void* base, size_t nmemb, size_t size, tr_voidptr_compare_func compar, size_t k)
{
if (k < nmemb)
{
@ -1163,7 +1162,7 @@ static char* strip_non_utf8(char const* in, size_t inlen)
return evbuffer_free_to_str(buf, NULL);
}
static char* to_utf8(const char* in, size_t inlen)
static char* to_utf8(char const* in, size_t inlen)
{
char* ret = NULL;

View File

@ -126,6 +126,7 @@ void tr_win32_make_args_utf8(int* argc, char*** argv);
int tr_main_win32(int argc, char** argv, int (* real_main)(int, char**));
/* *INDENT-OFF* */
#define tr_main(...) \
main_impl(__VA_ARGS__); \
int main(int argc, char* argv[]) \
@ -133,6 +134,7 @@ int tr_main_win32(int argc, char** argv, int (* real_main)(int, char**));
return tr_main_win32(argc, argv, &main_impl); \
} \
int main_impl(__VA_ARGS__)
/* *INDENT-ON* */
#else
@ -167,6 +169,7 @@ void tr_free_ptrv(void* const* p);
*/
void* tr_memdup(void const* src, size_t byteCount);
/* *INDENT-OFF* */
#define tr_new(struct_type, n_structs) \
((struct_type*)tr_malloc(sizeof(struct_type) * (size_t)(n_structs)))
@ -175,6 +178,7 @@ void* tr_memdup(void const* src, size_t byteCount);
#define tr_renew(struct_type, mem, n_structs) \
((struct_type*)tr_realloc((mem), sizeof(struct_type) * (size_t)(n_structs)))
/* *INDENT-ON* */
void* tr_valloc(size_t bufLen);
@ -206,11 +210,11 @@ int tr_memcmp0(void const* lhs, void const* rhs, size_t size);
char* evbuffer_free_to_str(struct evbuffer* buf, size_t* result_len);
/** @brief similar to bsearch() but returns the index of the lower bound */
int tr_lowerBound(void const* key, void const* base, size_t nmemb, size_t size, int (* compar)(void const* key,
void const* arrayMember), bool* exact_match) TR_GNUC_HOT TR_GNUC_NONNULL(1, 5, 6);
int tr_lowerBound(void const* key, void const* base, size_t nmemb, size_t size, tr_voidptr_compare_func compar,
bool* exact_match) TR_GNUC_HOT TR_GNUC_NONNULL(1, 5, 6);
/** @brief moves the best k items to the first slots in the array. O(n) */
void tr_quickfindFirstK(void* base, size_t nmemb, size_t size, int (* compar)(void const*, void const*), size_t k);
void tr_quickfindFirstK(void* base, size_t nmemb, size_t size, tr_voidptr_compare_func compar, size_t k);
/**
* @brief sprintf() a string into a newly-allocated buffer large enough to hold it

View File

@ -351,7 +351,12 @@ static void saveStringFunc(tr_variant const* v, void* evbuf)
{
size_t len;
char const* str;
tr_variantGetStr(v, &str, &len);
if (!tr_variantGetStr(v, &str, &len))
{
len = 0;
str = NULL;
}
evbuffer_add_printf(evbuf, "%zu:", len);
evbuffer_add(evbuf, str, len);
}

View File

@ -117,7 +117,7 @@ static bool tr_variantIsContainer(tr_variant const* v)
static bool tr_variantIsSomething(tr_variant const* v)
{
return tr_variantIsContainer(v) || tr_variantIsInt(v) || tr_variantIsString(v) || tr_variantIsReal(v) ||
tr_variantIsBool(v);
tr_variantIsBool(v);
}
void tr_variantInit(tr_variant* v, char type)

View File

@ -7,6 +7,7 @@
#define SHORT_VERSION_STRING "${TR_USER_AGENT_PREFIX}"
#define LONG_VERSION_STRING "${TR_USER_AGENT_PREFIX} (${TR_VCS_REVISION})"
#define VERSION_STRING_INFOPLIST ${TR_USER_AGENT_PREFIX}
#define BUILD_STRING_INFOPLIST 14714.${TR_VERSION_MAJOR}.${TR_VERSION_MINOR}
#define MAJOR_VERSION ${TR_VERSION_MAJOR}
#define MINOR_VERSION ${TR_VERSION_MINOR}

View File

@ -87,7 +87,7 @@ tr_watchdir_backend* tr_watchdir_generic_new(tr_watchdir_t handle)
backend->base.free_func = &tr_watchdir_generic_free;
if ((backend->event = event_new(tr_watchdir_get_event_base(handle), -1, EV_PERSIST, &tr_watchdir_generic_on_event,
handle)) == NULL)
handle)) == NULL)
{
log_error("Failed to create event: %s", tr_strerror(errno));
goto fail;

View File

@ -145,7 +145,7 @@ tr_watchdir_backend* tr_watchdir_kqueue_new(tr_watchdir_t handle)
/* Create libevent task for event descriptor */
if ((backend->event = event_new(tr_watchdir_get_event_base(handle), backend->kq, EV_READ | EV_ET | EV_PERSIST,
&tr_watchdir_kqueue_on_event, handle)) == NULL)
&tr_watchdir_kqueue_on_event, handle)) == NULL)
{
log_error("Failed to create event: %s", tr_strerror(errno));
goto fail;

View File

@ -63,7 +63,7 @@ tr_watchdir_win32;
static BOOL tr_get_overlapped_result_ex(HANDLE handle, LPOVERLAPPED overlapped, LPDWORD bytes_transferred, DWORD timeout,
BOOL alertable)
{
typedef BOOL (WINAPI * impl_t)(HANDLE, LPOVERLAPPED, LPDWORD, DWORD, BOOL);
typedef BOOL (WINAPI* impl_t)(HANDLE, LPOVERLAPPED, LPDWORD, DWORD, BOOL);
static impl_t real_impl = NULL;
static bool is_real_impl_valid = false;
@ -268,7 +268,7 @@ tr_watchdir_backend* tr_watchdir_win32_new(tr_watchdir_t handle)
}
if ((backend->fd = CreateFileW(wide_path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE)
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE)
{
log_error("Failed to open directory \"%s\"", path);
goto fail;

View File

@ -196,7 +196,10 @@ static CURL* createEasy(tr_session* s, struct tr_web* web, struct tr_web_task* t
if (web->curl_ssl_verify)
{
curl_easy_setopt(e, CURLOPT_CAINFO, web->curl_ca_bundle);
if (web->curl_ca_bundle != NULL)
{
curl_easy_setopt(e, CURLOPT_CAINFO, web->curl_ca_bundle);
}
}
else
{
@ -265,7 +268,8 @@ static void task_finish_func(void* vtask)
static void tr_webThreadFunc(void* vsession);
static struct tr_web_task* tr_webRunImpl(tr_session* session, int torrentId, char const* url, char const* range,
char const* cookies, tr_web_done_func done_func, void* done_func_user_data, struct evbuffer* buffer)
char const* cookies, tr_web_done_func done_func, void* done_func_user_data,
struct evbuffer* buffer)
{
struct tr_web_task* task = NULL;
@ -741,7 +745,7 @@ char* tr_http_unescape(char const* str, size_t len)
static bool is_rfc2396_alnum(uint8_t ch)
{
return ('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ch == '.' || ch == '-' ||
ch == '_' || ch == '~';
ch == '_' || ch == '~';
}
void tr_http_escape_sha1(char* out, uint8_t const* sha1_digest)

View File

@ -20,7 +20,7 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="5" userLabel="AboutWindow" customClass="NSPanel">
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" tabbingMode="disallowed" id="5" userLabel="AboutWindow" customClass="NSPanel">
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<rect key="contentRect" x="641" y="589" width="538" height="337"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
@ -128,7 +128,7 @@
</connections>
<point key="canvasLocation" x="100" y="100"/>
</window>
<window title="Panel" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="14" userLabel="LicenseSheet" customClass="NSPanel">
<window title="Panel" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" tabbingMode="disallowed" id="14" userLabel="LicenseSheet" customClass="NSPanel">
<windowStyleMask key="styleMask" titled="YES"/>
<rect key="contentRect" x="127" y="188" width="530" height="331"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>

View File

@ -20,6 +20,8 @@
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include <libtransmission/version.h>
#import "AboutWindowController.h"
@implementation AboutWindowController
@ -34,9 +36,7 @@ AboutWindowController * fAboutBoxInstance = nil;
- (void) awakeFromNib
{
NSDictionary * info = [[NSBundle mainBundle] infoDictionary];
[fVersionField setStringValue: [NSString stringWithFormat: @"%@ (%@)",
info[@"CFBundleShortVersionString"], info[(NSString *)kCFBundleVersionKey]]];
[fVersionField setStringValue: @(LONG_VERSION_STRING)];
[fCopyrightField setStringValue: [[NSBundle mainBundle] localizedStringForKey: @"NSHumanReadableCopyright"
value: nil table: @"InfoPlist"]];

View File

@ -21,6 +21,7 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "Torrent.h"
@class Controller;

View File

@ -21,6 +21,7 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "Torrent.h"
@class Controller;

View File

@ -21,7 +21,8 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <transmission.h>
#include <libtransmission/transmission.h>
@interface BadgeView : NSView
{

View File

@ -21,7 +21,8 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <transmission.h>
#include <libtransmission/transmission.h>
@class Torrent;

View File

@ -21,7 +21,8 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <transmission.h>
#include <libtransmission/transmission.h>
@class PrefsController;

View File

@ -16,7 +16,7 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="1">
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" tabbingMode="disallowed" id="1">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="389" width="405" height="121"/>

View File

@ -1,5 +1,7 @@
project(trmac)
include_directories(${CMAKE_SOURCE_DIR})
if(CMAKE_GENERATOR STREQUAL "Xcode")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC ON)
else()
@ -371,6 +373,7 @@ endforeach()
include_directories(
${CMAKE_SOURCE_DIR}/libtransmission
${CMAKE_BINARY_DIR}/libtransmission
${PROJECT_SOURCE_DIR}/VDKQueue
)

View File

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright (c) 2005-2012 Transmission authors and contributors
* Copyright (c) 2005-2019 Transmission authors and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -21,8 +21,10 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <transmission.h>
#import <Quartz/Quartz.h>
#include <libtransmission/transmission.h>
#import "VDKQueue.h"
@class AddMagnetWindowController;

View File

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright (c) 2005-2012 Transmission authors and contributors
* Copyright (c) 2005-2019 Transmission authors and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,14 @@
#import <Carbon/Carbon.h>
#import <libkern/OSAtomic.h>
#import <Sparkle/Sparkle.h>
#include <libtransmission/transmission.h>
#include <libtransmission/utils.h>
#include <libtransmission/variant.h>
#import "VDKQueue.h"
#import "Controller.h"
#import "Torrent.h"
#import "TorrentGroup.h"
@ -58,13 +66,6 @@
#import "ExpandedPathToPathTransformer.h"
#import "ExpandedPathToIconTransformer.h"
#import "transmission.h"
#import "utils.h"
#import "variant.h"
#import "VDKQueue.h"
#import <Sparkle/Sparkle.h>
#define TOOLBAR_CREATE @"Toolbar Create"
#define TOOLBAR_OPEN_FILE @"Toolbar Open"
#define TOOLBAR_OPEN_WEB @"Toolbar Open Web"
@ -734,16 +735,21 @@ static void removeKeRangerRansomware()
if ([fDefaults boolForKey: @"CheckQuitDownloading"] ? downloading > 0 : active > 0)
{
NSString * message = active == 1
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSAlertStyleInformational;
alert.messageText = NSLocalizedString(@"Are you sure you want to quit?", "Confirm Quit panel -> title");
alert.informativeText = active == 1
? NSLocalizedString(@"There is an active transfer that will be paused on quit."
" The transfer will automatically resume on the next launch.", "Confirm Quit panel -> message")
: [NSString stringWithFormat: NSLocalizedString(@"There are %d active transfers that will be paused on quit."
" The transfers will automatically resume on the next launch.", "Confirm Quit panel -> message"), active];
NSBeginAlertSheet(NSLocalizedString(@"Are you sure you want to quit?", "Confirm Quit panel -> title"),
NSLocalizedString(@"Quit", "Confirm Quit panel -> button"),
NSLocalizedString(@"Cancel", "Confirm Quit panel -> button"), nil, fWindow, self,
@selector(quitSheetDidEnd:returnCode:contextInfo:), nil, nil, @"%@", message);
[alert addButtonWithTitle:NSLocalizedString(@"Quit", "Confirm Quit panel -> button")];
[alert addButtonWithTitle:NSLocalizedString(@"Cancel", "Confirm Quit panel -> button")];
[alert beginSheetModalForWindow:fWindow
completionHandler:^(NSModalResponse returnCode) {
[NSApp replyToApplicationShouldTerminate: returnCode == NSAlertFirstButtonReturn];
}];
return NSTerminateLater;
}
}
@ -751,11 +757,6 @@ static void removeKeRangerRansomware()
return NSTerminateNow;
}
- (void) quitSheetDidEnd: (NSWindow *) sheet returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
{
[NSApp replyToApplicationShouldTerminate: returnCode == NSAlertDefaultReturn];
}
- (void) applicationWillTerminate: (NSNotification *) notification
{
fQuitting = YES;
@ -1400,9 +1401,6 @@ static void removeKeRangerRansomware()
if ([fDefaults boolForKey: @"CheckRemoveDownloading"] ? downloading > 0 : active > 0)
{
NSDictionary * dict = @{ @"Torrents" : torrents,
@"DeleteData" : @(deleteData) };
NSString * title, * message;
const NSUInteger selected = [torrents count];
@ -1445,9 +1443,19 @@ static void removeKeRangerRansomware()
"Removal confirm panel -> message part 2")];
}
NSBeginAlertSheet(title, NSLocalizedString(@"Remove", "Removal confirm panel -> button"),
NSLocalizedString(@"Cancel", "Removal confirm panel -> button"), nil, fWindow, self,
nil, @selector(removeSheetDidEnd:returnCode:contextInfo:), (__bridge_retained void *)(dict), @"%@", message);
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSAlertStyleInformational;
alert.messageText = title;
alert.informativeText = message;
[alert addButtonWithTitle:NSLocalizedString(@"Remove", "Removal confirm panel -> button")];
[alert addButtonWithTitle:NSLocalizedString(@"Cancel", "Removal confirm panel -> button")];
[alert beginSheetModalForWindow:fWindow
completionHandler:^(NSModalResponse returnCode) {
if (returnCode == NSAlertFirstButtonReturn) {
[self confirmRemoveTorrents: torrents deleteData: deleteData];
}
}];
return;
}
}
@ -1455,14 +1463,6 @@ static void removeKeRangerRansomware()
[self confirmRemoveTorrents: torrents deleteData: deleteData];
}
- (void) removeSheetDidEnd: (NSWindow *) sheet returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
{
NSDictionary * dict = (__bridge_transfer NSDictionary *)contextInfo;
NSArray * torrents = dict[@"Torrents"];
if (returnCode == NSAlertDefaultReturn)
[self confirmRemoveTorrents: torrents deleteData: [dict[@"DeleteData"] boolValue]];
}
- (void) confirmRemoveTorrents: (NSArray *) torrents deleteData: (BOOL) deleteData
{
//miscellaneous

View File

@ -21,8 +21,9 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "transmission.h"
#import "makemeta.h"
#include <libtransmission/transmission.h>
#include <libtransmission/makemeta.h>
@interface CreatorWindowController : NSWindowController
{

View File

@ -20,14 +20,14 @@
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include <libtransmission/transmission.h>
#include <libtransmission/utils.h> // tr_urlIsValidTracker()
#import "CreatorWindowController.h"
#import "Controller.h"
#import "NSApplicationAdditions.h"
#import "NSStringAdditions.h"
#import "transmission.h" // required by utils.h
#import "utils.h" // tr_urlIsValidTracker()
#define TRACKER_ADD_TAG 0
#define TRACKER_REMOVE_TAG 1

View File

@ -1,153 +1,155 @@
{\rtf1\ansi\ansicpg1252\cocoartf1265
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;\red127\green127\blue127;}
{\rtf1\ansi\ansicpg1252\cocoartf1659
{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red0\green0\blue0;\red0\green0\blue0;
\red0\green0\blue0;\red0\green0\blue0;\red127\green127\blue127;}
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0\c84706\cname headerTextColor;\cssrgb\c0\c0\c0\cname textColor;\cssrgb\c0\c0\c0\c84706\cname labelColor;
\cssrgb\c0\c0\c0\c24706\cname tertiaryLabelColor;\cssrgb\c0\c0\c0\c49804\cname secondaryLabelColor;\csgenericrgb\c49804\c49804\c49804;}
\vieww14160\viewh15100\viewkind0
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\qc
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\qc\partightenfactor0
\f0\b\fs28 \cf0 The Transmission Project
\fs24 \
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\qc
{\field{\*\fldinst{HYPERLINK "https://transmissionbt.com/"}}{\fldrslt
\b0 \cf0 https://transmissionbt.com/}}\
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40
\f0\b\fs28 \cf2 The Transmission Project
\fs24 \cf3 \
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\qc\partightenfactor0
{\field{\*\fldinst{HYPERLINK "https://transmissionbt.com/"}}{\fldrslt
\f1\b0 \cf3 https://transmissionbt.com/}}\
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\partightenfactor0
\cf3 \
\cf2 Lead Developers
\f1\b0 \cf3 <{\field{\*\fldinst{HYPERLINK "mailto:dev@transmissionbt.com"}}{\fldrslt dev@transmissionbt.com}}>\cf0 \
\cf4 Jordan Lee, Mnemosyne LLC <{\field{\*\fldinst{HYPERLINK "mailto:jordan@transmissionbt.com"}}{\fldrslt jordan@transmissionbt.com}}>
\fs20 \cf5 \cf6 (Daemon, Backend, GTK+ client)
\fs24 \cf0 \
\cf4 Mitchell Livingston, Digital Ignition LLC <{\field{\*\fldinst{HYPERLINK "mailto:livings124@transmissionbt.com"}}{\fldrslt livings124@transmissionbt.com}}>
\fs20 \cf3 \cf6 (Mac OS X client)
\fs24 \cf0 \
\cf3 \cf4 Mike Gelfand <{\field{\*\fldinst{HYPERLINK "mailto:mike@transmissionbt.com"}}{\fldrslt mike@transmissionbt.com}}>\cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\cf0 \
Lead Developers
\b0 <{\field{\*\fldinst{HYPERLINK "mailto:dev@transmissionbt.com"}}{\fldrslt dev@transmissionbt.com}}>\
Jordan Lee, Mnemosyne LLC <{\field{\*\fldinst{HYPERLINK "mailto:jordan@transmissionbt.com"}}{\fldrslt jordan@transmissionbt.com}}>
\fs20 \cf2 (Daemon, Backend, GTK+ client)
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\partightenfactor0
\f0\b \cf2 Project Contributors
\f1\b0 \
\cf0 \cf4 John Clay
\fs20
\fs24 <{\field{\*\fldinst{HYPERLINK "mailto:john@transmissionbt.com"}}{\fldrslt john@transmissionbt.com}}>
\fs20 \cf5 \cf6 (Website maintenance and troubleshooting, Mac OS X help documentation)\cf7 \
\fs24 \cf0 \cf4 Bruno Bierbaumer
\fs20 \cf7 \cf6 (Web client patches)
\fs24 \cf0 \
Mitchell Livingston, Digital Ignition LLC <{\field{\*\fldinst{HYPERLINK "mailto:livings124@transmissionbt.com"}}{\fldrslt livings124@transmissionbt.com}}>
\fs20 \cf2 (Mac OS X client)
\cf4 Juliusz Chroboczek
\fs20 \cf7 \cf6 (DHT, network code, BitTorrent code improvements)\cf7 \
\fs24 \cf0 \cf4 Daniel Lee
\fs20 \cf7 \cf6 (Patches)
\fs24 \cf0 \
Mike Gelfand <{\field{\*\fldinst{HYPERLINK "mailto:mike@transmissionbt.com"}}{\fldrslt mike@transmissionbt.com}}>
\cf4 Tomas Carnecky
\fs20 \cf7 \cf6 (Profiling, patches, and detection of sneaky bugs)\cf7 \
\fs24 \cf0 \cf4 Diego Jim\'e9nez
\fs20 \cf5 \cf6 (Patches)\cf7 \
\fs24 \cf0 \cf4 Kendall Hopkins <{\field{\*\fldinst{HYPERLINK "mailto:SoftwareElves@gmail.com"}}{\fldrslt SoftwareElves@gmail.com}}>
\fs20 \cf7 \cf6 (Web client)\cf7 \
\fs24 \cf0 \cf4 Malcolm Jarvis <{\field{\*\fldinst{HYPERLINK "mailto:mjarvis@transmissionbt.com"}}{\fldrslt mjarvis@transmissionbt.com}}>
\fs20 \cf7 \cf6 (Web client)
\fs24 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
\cf4 Kevin Glowacz <{\field{\*\fldinst{HYPERLINK "mailto:kjg@transmissionbt.com"}}{\fldrslt kjg@transmissionbt.com}}>
\fs20 \cf6 (Web client)\cf7 \
\fs24 \cf0 \cf4 Rashid Eissing
\fs20 \cf3 \cf6 (Mac OS X Transfers preferences icon)
\fs24 \cf0 \
\cf4 Hugo van Heuven, madebysofa
\fs20 \cf7 \cf6 (Main icon design)
\fs24 \cf0 \
\cf4 Andreas Nilsson
\fs20 \cf5 \cf6 (GNOME adaptation of main icon)\cf7 \
\fs24 \cf0 \cf4 Dean Ostetto
\fs20 \cf5 \cf6 (Mac OS X Turtle image)\cf7 \
\fs24 \cf0 \cf4 Rick Patrick
\fs20 \cf6 (Mac OS X images)\cf7 \
\fs24 \cf0 \cf4 Jonas Rask
\fs20 \cf7 \cf6 (Mac OS X Globe icon)\cf7 \
\fs24 \cf0 \cf4 Erick Turnquist\cf0
\fs20 \cf6 (IPv6 code, support)\cf7 \
\fs24 \cf0 \cf4 Maarten Van Coile
\fs20 \cf7 \cf6 (Wiki Wrangler, troubleshooting, support)\cf7 \
\fs24 \cf0 \cf4 James "Kibo" Parry
\fs20 \cf3 \cf6 (Updated Mac Retina images)
\fs24 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\cf0 \
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\partightenfactor0
\b \cf0 Project Contributors
\b0 \
John Clay
\fs20 \cf2
\fs24 \cf0 <{\field{\*\fldinst{HYPERLINK "mailto:john@transmissionbt.com"}}{\fldrslt john@transmissionbt.com}}>
\fs20 \cf2 (Website maintenance and troubleshooting, Mac OS X help documentation)\
\f0\b \cf2 Previous Developers
\f1\b0 \
\cf0 \cf4 Eric Petit <{\field{\*\fldinst{HYPERLINK "mailto:eric@lapsus.org"}}{\fldrslt eric@lapsus.org}}>
\fs20 \cf6 (Project originator)\cf7 \
\fs24 \cf0 Bruno Bierbaumer
\fs20 \cf2 (Web client patches)
\fs24 \cf0 \cf4 Josh Elsasser <{\field{\*\fldinst{HYPERLINK "mailto:josh@elsasser.org"}}{\fldrslt josh@elsasser.org}}>
\fs20 \cf6 (Daemon, Backend, GTK+ client)
\fs24 \cf0 \
Juliusz Chroboczek
\fs20 \cf2 (DHT, network code, BitTorrent code improvements)\
\fs24 \cf0 Daniel Lee
\fs20 \cf2 (Patches)
\cf4 Bryan Varner <{\field{\*\fldinst{HYPERLINK "mailto:bryan@varnernet.com"}}{\fldrslt bryan@varnernet.com}}>
\fs20 \cf7 \cf6 (BeOS client)
\fs24 \cf0 \
Tomas Carnecky
\fs20 \cf2 (Profiling, patches, and detection of sneaky bugs)\
\fs24 \cf0 Diego Jim\'e9nez
\fs20 \cf2 (Patches)\
\fs24 \cf0 Kendall Hopkins <{\field{\*\fldinst{HYPERLINK "mailto:SoftwareElves@gmail.com"}}{\fldrslt SoftwareElves@gmail.com}}>
\fs20 \cf2 (Web client)\
\fs24 \cf0 Malcolm Jarvis <{\field{\*\fldinst{HYPERLINK "mailto:mjarvis@transmissionbt.com"}}{\fldrslt mjarvis@transmissionbt.com}}>
\fs20 \cf2 (Web client)
\fs24 \cf0 \
Kevin Glowacz <{\field{\*\fldinst{HYPERLINK "mailto:kjg@transmissionbt.com"}}{\fldrslt kjg@transmissionbt.com}}>
\fs20 \cf2 (Web client)\
\fs24 \cf0 Rashid Eissing
\fs20 \cf2 (Mac OS X Transfers preferences icon)
\fs24 \cf0 \
Hugo van Heuven, madebysofa
\fs20 \cf2 (Main icon design)
\fs24 \cf0 \
Andreas Nilsson
\fs20 \cf2 (GNOME adaptation of main icon)\
\fs24 \cf0 Dean Ostetto
\fs20 \cf2 (Mac OS X Turtle image)\
\fs24 \cf0 Rick Patrick
\fs20 \cf2 (Mac OS X images)\
\fs24 \cf0 Jonas Rask
\fs20 \cf2 (Mac OS X Globe icon)\
\fs24 \cf0 Erick Turnquist
\fs20 \cf2 (IPv6 code, support)\
\fs24 \cf0 Maarten Van Coile
\fs20 \cf2 (Wiki Wrangler, troubleshooting, support)\
\fs24 \cf0 James "Kibo" Parry
\fs20 \cf2 (Updated Mac Retina images)
\fs24 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\cf0 \
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\partightenfactor0
\b \cf0 Previous Developers
\b0 \
Eric Petit <{\field{\*\fldinst{HYPERLINK "mailto:eric@lapsus.org"}}{\fldrslt eric@lapsus.org}}>
\fs20 \cf2 (Project originator)\
\f0\b \cf2 Mac OS X Translators
\f1\b0 \
\cf0 \cf4 Jorge Carrasco\cf7
\fs20 \cf6 (Spanish)\cf7 \
\fs24 \cf0 Josh Elsasser <{\field{\*\fldinst{HYPERLINK "mailto:josh@elsasser.org"}}{\fldrslt josh@elsasser.org}}>
\fs20 \cf2 (Daemon, Backend, GTK+ client)
\fs24 \cf0 \
Bryan Varner <{\field{\*\fldinst{HYPERLINK "mailto:bryan@varnernet.com"}}{\fldrslt bryan@varnernet.com}}>
\fs20 \cf2 (BeOS client)
\fs24 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
\cf0 \
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40
\fs24 \cf0 \cf4 Etienne Samson
\fs20 \cf7 \cf6 (French)\cf7 \
\b \cf0 Mac OS X Translators
\b0 \
Jorge Carrasco\cf2
\fs20 (Spanish)\
\fs24 \cf0 Etienne Samson
\fs20 \cf2 (French)\
\fs24 \cf0 Marco Cavazzuti
\fs20 \cf2 (Italian)\
\fs24 \cf0 \cf4 Marco Cavazzuti
\fs20 \cf6 (Italian)\cf7 \
\fs24 \cf0 Anton Sotkov
\fs20 \cf2 (Russian)\
\fs24 \cf0 \cf4 Anton Sotkov
\fs20 \cf7 \cf6 (Russian)\cf7 \
\fs24 \cf0 Alexander Bykov
\fs20 \cf2 (Russian)\
\fs24 \cf0 \cf4 Alexander Bykov
\fs20 \cf7 \cf6 (Russian)\cf7 \
\fs24 \cf0 Maarten Van Coile
\fs20 \cf2 (Dutch)\
\fs24 \cf4 Maarten Van Coile
\fs20 \cf6 (Dutch)\cf7 \
\fs24 \cf0 Guilherme Fernandes
\fs20 \cf2 (Brazilian Portuguese)\
\fs24 \cf4 Guilherme Fernandes
\fs20 \cf6 (Brazilian Portuguese)\cf7 \
\fs24 \cf0 Sven-S. Porst
\fs20 \cf2 (German)\
\fs24 \cf4 Sven-S. Porst
\fs20 \cf6 (German)\cf7 \
\fs24 \cf0 Tianhao He
\fs20 \cf2 (Simplified Chinese)\
\fs24 \cf4 Tianhao He
\fs20 \cf6 (Simplified Chinese)\cf7 \
\fs24 \cf0 S\'e9rgio Miranda
\fs20 \cf2 (European Portuguese)\
\fs24 \cf4 S\'e9rgio Miranda
\fs20 \cf7 \cf6 (European Portuguese)\cf7 \
\fs24 \cf0 Daniel \'d8stergaard Nielsen
\fs20 \cf2 (Danish)\
\fs24 \cf4 Daniel \'d8stergaard Nielsen
\fs20 \cf5 \cf6 (Danish)\cf7 \
\fs24 \cf0 Emir SARI
\fs20 \cf2 (Turkish)
\fs24 \cf4 Emir SARI
\fs20 \cf7 \cf6 (Turkish)
\fs24 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\cf0 \
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\partightenfactor0
\b \cf0 Third-Party Resources
\b0 \
Nick Mathewson and Niels Provos for libevent. <{\field{\*\fldinst{HYPERLINK "http://monkey.org/~provos/libevent/"}}{\fldrslt http://monkey.org/~provos/libevent/}}>\
Greg Hazel of BitTorrent Inc. for libutp. <{\field{\*\fldinst{HYPERLINK "https://github.com/bittorrent/libutp"}}{\fldrslt https://github.com/bittorrent/libutp}}>\
Thomas Bernard for MiniUPnP and libnatpmp. <{\field{\*\fldinst{HYPERLINK "http://miniupnp.tuxfamily.org/"}}{\fldrslt http://miniupnp.tuxfamily.org/}}>\
Andy Matuschak for Sparkle. <{\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt http://sparkle.andymatuschak.org/}}>\
Bryan D K Jones for VDKQueue. <{\field{\*\fldinst{HYPERLINK "https://github.com/bdkjones/VDKQueue"}}{\fldrslt https://github.com/bdkjones/VDKQueue}}>}
\f0\b \cf2 Third-Party Resources
\f1\b0 \
\cf3 \cf4 Nick Mathewson and Niels Provos for libevent. <{\field{\*\fldinst{HYPERLINK "http://monkey.org/~provos/libevent/"}}{\fldrslt http://monkey.org/~provos/libevent/}}>\cf3 \
\cf4 Greg Hazel of BitTorrent Inc. for libutp. <{\field{\*\fldinst{HYPERLINK "https://github.com/bittorrent/libutp"}}{\fldrslt https://github.com/bittorrent/libutp}}>\cf3 \
\cf4 Thomas Bernard for MiniUPnP and libnatpmp. <{\field{\*\fldinst{HYPERLINK "http://miniupnp.tuxfamily.org/"}}{\fldrslt http://miniupnp.tuxfamily.org/}}>\cf3 \
\cf4 Andy Matuschak for Sparkle. <{\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt http://sparkle.andymatuschak.org/}}>\cf3 \
\cf4 Bryan D K Jones for VDKQueue. <{\field{\*\fldinst{HYPERLINK "https://github.com/bdkjones/VDKQueue"}}{\fldrslt https://github.com/bdkjones/VDKQueue}}>}

View File

@ -21,7 +21,8 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <transmission.h>
#include <libtransmission/transmission.h>
@interface DragOverlayWindow : NSWindow
{

View File

@ -20,15 +20,15 @@
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include <libtransmission/transmission.h>
#include <libtransmission/utils.h>
#import "FileNameCell.h"
#import "FileOutlineView.h"
#import "Torrent.h"
#import "FileListNode.h"
#import "NSStringAdditions.h"
#import "transmission.h" // required by utils.h
#import "utils.h"
#define PADDING_HORIZONAL 2.0
#define IMAGE_FOLDER_SIZE 16.0
#define IMAGE_ICON_SIZE 32.0
@ -115,7 +115,7 @@
else
{
titleColor = [NSColor controlTextColor];
statusColor = [NSColor darkGrayColor];
statusColor = [NSColor secondaryLabelColor];
}
fTitleAttributes[NSForegroundColorAttributeName] = titleColor;

View File

@ -20,6 +20,8 @@
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#import <Quartz/Quartz.h>
#import "FileOutlineController.h"
#import "Torrent.h"
#import "FileListNode.h"
@ -29,7 +31,6 @@
#import "NSApplicationAdditions.h"
#import "NSMutableArrayAdditions.h"
#import "NSStringAdditions.h"
#import <Quartz/Quartz.h>
#define ROW_SMALL_HEIGHT 18.0

View File

@ -21,6 +21,7 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "FileOutlineView.h"
@interface FilePriorityCell : NSSegmentedCell

View File

@ -17,7 +17,7 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" visibleAtLaunch="NO" frameAutosaveName="RenameFileWindow" animationBehavior="default" id="1">
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" visibleAtLaunch="NO" frameAutosaveName="RenameFileWindow" animationBehavior="default" tabbingMode="disallowed" id="1">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="400" height="120"/>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -107,7 +107,7 @@
<action selector="setFilter:" target="-2" id="40"/>
</connections>
</button>
<searchField wantsLayer="YES" verticalHuggingPriority="750" id="10">
<searchField wantsLayer="YES" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="10">
<rect key="frame" x="357" y="2" width="95" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
<searchFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" bezelStyle="round" id="11">

View File

@ -58,7 +58,7 @@
const NSRect lineBorderRect = NSMakeRect(NSMinX(rect), 0.0, NSWidth(rect), 1.0);
if (NSIntersectsRect(lineBorderRect, rect))
{
[[NSColor lightGrayColor] setFill];
[[NSColor gridColor] setFill];
NSRectFill(lineBorderRect);
}
}

View File

@ -22,7 +22,7 @@
#import <Cocoa/Cocoa.h>
#import "transmission.h"
#include <libtransmission/transmission.h>
@interface GlobalOptionsPopoverViewController : NSViewController
{

View File

@ -274,8 +274,7 @@
if ([self.ruleEditor numberOfRows] == 0)
[self.ruleEditor addRow: nil];
[NSApp beginSheet: self.groupRulesSheetWindow modalForWindow: [fTableView window] modalDelegate: nil didEndSelector: NULL
contextInfo: NULL];
[fTableView.window beginSheet:self.groupRulesSheetWindow completionHandler:nil];
}
- (IBAction) cancelRules: (id) sender

View File

@ -59,7 +59,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>VCS_REVISION_NUM</string>
<string>BUILD_STRING_INFOPLIST</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
@ -72,7 +72,7 @@
<true/>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2005-2016 The Transmission Project</string>
<string>Copyright © 2005-2018 The Transmission Project</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>

View File

@ -72,7 +72,7 @@
<true/>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2005-2016 The Transmission Project</string>
<string>Copyright © 2005-2019 The Transmission Project</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>

View File

@ -21,6 +21,7 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "InfoViewController.h"
@class PiecesView;

View File

@ -20,15 +20,15 @@
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include <libtransmission/transmission.h>
#include <libtransmission/utils.h> //tr_getRatio()
#import "InfoActivityViewController.h"
#import "NSApplicationAdditions.h"
#import "NSStringAdditions.h"
#import "PiecesView.h"
#import "Torrent.h"
#include "transmission.h" // required by utils.h
#include "utils.h" //tr_getRatio()
#define PIECES_CONTROL_PROGRESS 0
#define PIECES_CONTROL_AVAILABLE 1

View File

@ -22,6 +22,7 @@
#import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>
#import "InfoViewController.h"
@class FileOutlineController;

View File

@ -21,6 +21,7 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "InfoViewController.h"
@interface InfoGeneralViewController : NSViewController <InfoViewController>

View File

@ -21,6 +21,7 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "InfoViewController.h"
@interface InfoOptionsViewController : NSViewController <InfoViewController>

View File

@ -21,6 +21,7 @@
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "InfoViewController.h"
@class WebSeedTableView;

Some files were not shown because too many files have changed in this diff Show More