Merge branch 'master' into rmintltool
This commit is contained in:
commit
dab4857f90
|
@ -5,5 +5,6 @@
|
|||
"indent_with_tabs": false,
|
||||
"preserve_newlines": true,
|
||||
"max_preserve_newlines": 2,
|
||||
"end_with_newline": true,
|
||||
"jslint_happy": true
|
||||
}
|
||||
|
|
|
@ -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}")
|
||||
|
|
2
COPYING
2
COPYING
|
@ -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
25
NEWS
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)";
|
||||
|
|
26
autogen.sh
26
autogen.sh
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#/bin/sh
|
||||
#!/bin/sh
|
||||
export G_SLICE=always-malloc
|
||||
export G_DEBUG=gc-friendly
|
||||
export GLIBCXX_FORCE_NEW=1
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#/bin/sh
|
||||
#!/bin/sh
|
||||
export G_SLICE=always-malloc
|
||||
export G_DEBUG=gc-friendly
|
||||
export GLIBCXX_FORCE_NEW=1
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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=$?
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; \
|
||||
} \
|
||||
|
|
|
@ -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*);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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, ...) \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[] =
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/* @} */
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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... */
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"]];
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "Torrent.h"
|
||||
|
||||
@class Controller;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "Torrent.h"
|
||||
|
||||
@class Controller;
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <transmission.h>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
|
||||
@interface BadgeView : NSView
|
||||
{
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <transmission.h>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
|
||||
@class Torrent;
|
||||
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <transmission.h>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
|
||||
@class PrefsController;
|
||||
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}}>}
|
|
@ -21,7 +21,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <transmission.h>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
|
||||
@interface DragOverlayWindow : NSWindow
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "FileOutlineView.h"
|
||||
|
||||
@interface FilePriorityCell : NSSegmentedCell
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "transmission.h"
|
||||
#include <libtransmission/transmission.h>
|
||||
|
||||
@interface GlobalOptionsPopoverViewController : NSViewController
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "InfoViewController.h"
|
||||
|
||||
@class PiecesView;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Quartz/Quartz.h>
|
||||
|
||||
#import "InfoViewController.h"
|
||||
|
||||
@class FileOutlineController;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "InfoViewController.h"
|
||||
|
||||
@interface InfoGeneralViewController : NSViewController <InfoViewController>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "InfoViewController.h"
|
||||
|
||||
@interface InfoOptionsViewController : NSViewController <InfoViewController>
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue