Updated Sparkle framework

CQTexperiment
Chris Moeller 2014-09-03 09:47:40 -07:00
parent a5c0125b23
commit 74114a3af2
51 changed files with 647 additions and 357 deletions

View File

@ -1,4 +1,3 @@
// BinaryDelta tool only
PRODUCT_NAME = BinaryDelta
GCC_PREFIX_HEADER =

View File

@ -1,6 +1,18 @@
// Common
FINISH_INSTALL_TOOL_NAME = Autoupdate
SPARKLE_BUNDLE_IDENTIFIER = org.andymatuschak.Sparkle
SPARKLE_RELAUNCH_TOOL_NAME = Autoupdate
SPARKLE_APPEND_VERSION_NUMBER = 1
// Sparkle usually doesn't allow downgrades as they're usually accidental, but
// if your app has a downgrade function or URL handler, turn this on
SPARKLE_AUTOMATED_DOWNGRADES = 0
// If your app file on disk is named "MyApp 1.1b4", Sparkle usually updates it
// in place, giving you an app named 1.1b4 that is actually 1.2. Turn the
// following on to always reset the name back to "MyApp":
SPARKLE_NORMALIZE_INSTALLED_APPLICATION_NAME = 0
SPARKLE_VERSION_MAJOR = 1
SPARKLE_VERSION_MINOR = 8
@ -10,11 +22,13 @@ SPARKLE_VERSION = $(SPARKLE_VERSION_MAJOR).$(SPARKLE_VERSION_MINOR).$(SPARKLE_VE
CURRENT_PROJECT_VERSION = $(SPARKLE_VERSION)
ALWAYS_SEARCH_USER_PATHS = NO
GCC_PRECOMPILE_PREFIX_HEADER = YES
GCC_PREFIX_HEADER = $(SDKROOT)/System/Library/Frameworks/Cocoa.framework/Headers/Cocoa.h
GCC_PREFIX_HEADER = Sparkle/Sparkle.pch
GCC_SYMBOLS_PRIVATE_EXTERN = YES
GCC_INLINES_ARE_PRIVATE_EXTERN = YES
ARCHS = $(ARCHS_STANDARD)
MACOSX_DEPLOYMENT_TARGET = 10.7
GCC_PREPROCESSOR_DEFINITIONS = FINISH_INSTALL_TOOL_NAME=$(FINISH_INSTALL_TOOL_NAME)
GCC_PREPROCESSOR_DEFINITIONS = SPARKLE_BUNDLE_IDENTIFIER=\"$(SPARKLE_BUNDLE_IDENTIFIER)\" SPARKLE_RELAUNCH_TOOL_NAME=\"$(SPARKLE_RELAUNCH_TOOL_NAME)\"
CLANG_ENABLE_OBJC_ARC = YES
// Enable warnings

View File

@ -1,12 +1,11 @@
// Framework only
INSTALL_PATH = @loader_path/../Frameworks
DYLIB_INSTALL_NAME_BASE = @rpath
DYLIB_COMPATIBILITY_VERSION = 1.6
DYLIB_CURRENT_VERSION = $(SPARKLE_VERSION_MAJOR).$(SPARKLE_VERSION_MINOR).$(SPARKLE_VERSION_PATCH)
PRODUCT_NAME = Sparkle
WRAPPER_EXTENSION = framework
FRAMEWORK_VERSION = A
INFOPLIST_FILE = Sparkle/Sparkle-Info.plist
GCC_PREFIX_HEADER = Sparkle/Sparkle.pch
SKIP_INSTALL = YES
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) BUILDING_SPARKLE=1
OTHER_LDFLAGS = -Wl,-U,_NSURLQuarantinePropertiesKey

View File

@ -1,8 +1,7 @@
// Relaunch Tool only
INFOPLIST_FILE = Sparkle/Autoupdate/Autoupdate-Info.plist
PRODUCT_NAME = $(FINISH_INSTALL_TOOL_NAME)
PRODUCT_NAME = $(SPARKLE_RELAUNCH_TOOL_NAME)
SKIP_INSTALL = YES
GCC_PREFIX_HEADER = Sparkle/Autoupdate/Autoupdate.pch
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
OTHER_LDFLAGS = -Wl,-U,_NSURLQuarantinePropertiesKey

View File

@ -5,3 +5,4 @@ PRODUCT_NAME = Sparkle Test App
WRAPPER_EXTENSION = app
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
CLANG_ENABLE_OBJC_ARC = NO
LD_RUNPATH_SEARCH_PATHS = @executable_path/../Frameworks

View File

@ -3,4 +3,8 @@
INFOPLIST_FILE = Tests/SparkleTests-Info.plist
PRODUCT_NAME = Sparkle Unit Tests
WRAPPER_EXTENSION = xctest
OTHER_CFLAGS = $(inherited) -iframework"$(DEVELOPER_FRAMEWORKS_DIR)" -iframework"$(PLATFORM_DIR)/Developer/Library/Frameworks"
GCC_SYMBOLS_PRIVATE_EXTERN = NO
WARNING_CFLAGS = $(inherited) -Wno-variadic-macros -Wno-gnu-zero-variadic-macro-arguments
FRAMEWORK_SEARCH_PATHS = $(inherited) $(DEVELOPER_FRAMEWORKS_DIR)
LD_RUNPATH_SEARCH_PATHS = @loader_path/../Frameworks

View File

@ -9,11 +9,16 @@ if [ "$ACTION" = "" ] ; then
cp "$SRCROOT/CHANGELOG" "$SRCROOT/LICENSE" "$SRCROOT/Resources/SampleAppcast.xml" "$CONFIGURATION_BUILD_DIR/staging"
cp -R "$SRCROOT/bin" "$CONFIGURATION_BUILD_DIR/staging"
cp "$CONFIGURATION_BUILD_DIR/BinaryDelta" "$CONFIGURATION_BUILD_DIR/staging/bin"
cp -R "$CONFIGURATION_BUILD_DIR/BinaryDelta.dSYM" "$CONFIGURATION_BUILD_DIR/staging/bin"
cp -R "$CONFIGURATION_BUILD_DIR/Sparkle Test App.app" "$CONFIGURATION_BUILD_DIR/staging"
cp -R "$CONFIGURATION_BUILD_DIR/Sparkle Test App.app.dSYM" "$CONFIGURATION_BUILD_DIR/staging"
cp -R "$CONFIGURATION_BUILD_DIR/Sparkle.framework" "$CONFIGURATION_BUILD_DIR/staging"
cp -R "$CONFIGURATION_BUILD_DIR/Sparkle.framework.dSYM" "$CONFIGURATION_BUILD_DIR/staging"
# Only copy dSYMs for Release builds, but don't check for the presence of the actual files
# because missing dSYMs in a release build SHOULD trigger a build failure
if [ "$CONFIGURATION" = "Release" ] ; then
cp -R "$CONFIGURATION_BUILD_DIR/BinaryDelta.dSYM" "$CONFIGURATION_BUILD_DIR/staging/bin"
cp -R "$CONFIGURATION_BUILD_DIR/Sparkle Test App.app.dSYM" "$CONFIGURATION_BUILD_DIR/staging"
cp -R "$CONFIGURATION_BUILD_DIR/Sparkle.framework.dSYM" "$CONFIGURATION_BUILD_DIR/staging"
fi
cd "$CONFIGURATION_BUILD_DIR/staging"
# Sorted file list groups similar files together, which improves tar compression

View File

@ -0,0 +1,28 @@
#!/bin/sh
set -e
if ! which -s git ; then
exit 0
fi
if [ -z "$SRCROOT" ] || \
[ -z "$BUILT_PRODUCTS_DIR" ] || \
[ -z "$INFOPLIST_PATH" ] || \
[ -z "$CURRENT_PROJECT_VERSION" ]; then
echo "$0: Must be run from Xcode!" 1>&2
exit 1
fi
# Get the current Git master hash
version=$(cd "$SRCROOT" ; git show-ref --abbrev heads/master | awk '{print $1}')
if [ -z "$version" ] ; then
echo "$0: Can't find a Git hash!" 1>&2
exit 0
fi
version="$CURRENT_PROJECT_VERSION git-$version"
# and use it to set the CFBundleShortVersionString value
export PATH="$PATH:/usr/libexec"
PlistBuddy -c "Set :CFBundleShortVersionString '$version'" \
"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH"

View File

@ -1,9 +1,9 @@
© 2006-2013 Andy Matuschak
© 2009-2013 Elgato Systems GmbH.
© 2011-2014 Kornel Lesiński
© 2014 C.W. Betts
© 2014 Petroules Corporation, Sparkle Project contributors
© 2014 Big Nerd Ranch
Copyright (c) 2006-2013 Andy Matuschak.
Copyright (c) 2009-2013 Elgato Systems GmbH.
Copyright (c) 2011-2014 Kornel Lesiński.
Copyright (c) 2014 C.W. Betts.
Copyright (c) 2014 Petroules Corporation.
Copyright (c) 2014 Big Nerd Ranch.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -27,8 +27,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
EXTERNAL LICENSES
=================
bspatch.c and bsdiff.c, from bsdiff 4.3 <http://www.daemonology.net/bsdiff/>: © 2003-2005 Colin Percival.
SUDSAVerifier.m: © 2011 Mark Hamlin.
bspatch.c and bsdiff.c, from bsdiff 4.3 <http://www.daemonology.net/bsdiff/>:
Copyright (c) 2003-2005 Colin Percival.
SUDSAVerifier.m:
Copyright (c) 2011 Mark Hamlin.
All rights reserved.

View File

@ -9,13 +9,13 @@ localizable-strings:
rm Sparkle/en.lproj/Localizable.strings
release:
xcodebuild -scheme Distribution -configuration Release -derivedDataPath "$(BUILDDIR)"
xcodebuild -scheme Distribution -configuration Release -derivedDataPath "$(BUILDDIR)" build
open -R "$(BUILDDIR)/Build/Products/Release/Sparkle-"*.tar.bz2
build:
xcodebuild clean build
test:
xcodebuild -target 'Sparkle Unit Tests' -scheme 'Sparkle' test
xcodebuild -scheme Distribution -configuration Debug test
travis: test

View File

@ -28,3 +28,18 @@ is an easy-to-use software update framework for Cocoa developers.
* Optionally sends system information to the server when checking for updates.
* Supports bundles, preference panes, plugins, and other non-.app software. Can install .pkg files for more complicated products.
* Supports branches due to minimum OS version requirements.
## Developers
Building Sparkle requires Xcode 5 or above.
### API
Sparkle is built with `-fvisibility=hidden -fvisibility-inlines-hidden` which means no symbols are exported by default.
If you are adding a symbol to the public API you must decorate the declaration with the `SU_EXPORT` macro (grep the source code for examples).
### Building the distribution package
`cd` to the root of the Sparkle source tree and run `make release`. Sparkle-*VERSION*.tar.bz2 will be created in a temporary directory and revealed in Finder after the build has completed.
Alternatively, build the Distribution scheme in the Xcode UI.

View File

@ -1,9 +1,9 @@
Pod::Spec.new do |s|
s.name = "Sparkle"
s.version = "1.7.1"
s.version = "1.8.0"
s.summary = "A software update framework for OS X"
s.description = "Sparkle is an easy-to-use software update framework for Cocoa developers."
s.homepage = "https://github.com/sparkle-project/Sparkle"
s.homepage = "http://sparkle-project.org"
s.license = {
:type => 'MIT',
:file => 'LICENSE'
@ -15,12 +15,12 @@ Pod::Spec.new do |s|
'Jake Petroules' => 'jake.petroules@petroules.com',
}
s.platform = :osx
s.source = { :http => "https://github.com/sparkle-project/Sparkle/releases/download/#{s.version}/Sparkle-#{s.version}.zip" }
s.platform = :osx, '10.7'
s.source = { :http => "https://github.com/sparkle-project/Sparkle/releases/download/#{s.version}/Sparkle-#{s.version}.tar.bz2" }
s.public_header_files = 'Sparkle.framework/Headers/*.h'
s.vendored_framework = 'Sparkle.framework'
s.resources = 'Sparkle.framework'
s.xcconfig = { 'FRAMEWORK_SEARCH_PATHS' => '"${PODS_ROOT}/Sparkle"' }
s.requires_arc = false
s.requires_arc = true
end

View File

@ -27,6 +27,18 @@
/* Begin PBXBuildFile section */
1420DF50196247F900203BB0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1420DF4F196247F900203BB0 /* Images.xcassets */; };
1420DF51196247F900203BB0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1420DF4F196247F900203BB0 /* Images.xcassets */; };
142E0E0019A6954400E4312B /* Sparkle.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
142E0E0219A6A14700E4312B /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
142E0E0419A6A26F00E4312B /* Autoupdate.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 55C14BB7136EEF1500649790 /* Autoupdate.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
142E0E0919A83AAC00E4312B /* SUBinaryDeltaTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 142E0E0819A83AAC00E4312B /* SUBinaryDeltaTest.m */; };
14652F7C19A9725300959E44 /* SUBinaryDeltaCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D06E8E20FD68CC7005AE3F6 /* SUBinaryDeltaCommon.m */; };
14652F7D19A9726700959E44 /* SUBinaryDeltaApply.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D06E8E00FD68CC7005AE3F6 /* SUBinaryDeltaApply.m */; };
14652F7E19A9728A00959E44 /* bspatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D06E8DC0FD68CB9005AE3F6 /* bspatch.c */; settings = {COMPILER_FLAGS = "-w"; }; };
14652F7F19A973F900959E44 /* SUDSAVerifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 61299A2E09CA2DAB00B7442F /* SUDSAVerifier.m */; };
14652F8019A9740F00959E44 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61B5F8F609C4CEB300B25A18 /* Security.framework */; };
14652F8119A9744200959E44 /* SUBinaryDeltaCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D06E8E20FD68CC7005AE3F6 /* SUBinaryDeltaCommon.m */; };
14652F8219A9746000959E44 /* SULog.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C14F05136EF6DB00649790 /* SULog.m */; };
14652F8419A978C200959E44 /* SUExport.h in Headers */ = {isa = PBXBuildFile; fileRef = 14652F8319A9759F00959E44 /* SUExport.h */; settings = {ATTRIBUTES = (Public, ); }; };
14732BC01960F2C200593899 /* test_app_only_dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = 14732BBF1960F0AC00593899 /* test_app_only_dsa_pub.pem */; };
14732BD019610A0D00593899 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; };
14732BD119610A1200593899 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D6A5FE840307C02AAC07 /* AppKit.framework */; };
@ -38,6 +50,8 @@
14950072195FCE4B00BC5B5B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; };
14950073195FCE4E00BC5B5B /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D6A5FE840307C02AAC07 /* AppKit.framework */; };
14950075195FDF5900BC5B5B /* SUUpdaterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 14950074195FDF5900BC5B5B /* SUUpdaterTest.m */; };
14958C6E19AEBC950061B14F /* signed-test-file.txt in Resources */ = {isa = PBXBuildFile; fileRef = 14958C6B19AEBC530061B14F /* signed-test-file.txt */; };
14958C6F19AEBC980061B14F /* test-pubkey.pem in Resources */ = {isa = PBXBuildFile; fileRef = 14958C6C19AEBC610061B14F /* test-pubkey.pem */; };
3772FEA913DE0B6B00F79537 /* SUVersionDisplayProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 3772FEA813DE0B6B00F79537 /* SUVersionDisplayProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
55C14BD4136EEFCE00649790 /* Autoupdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C14BD3136EEFCE00649790 /* Autoupdate.m */; };
55C14BD9136EF00C00649790 /* SUStatus.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55C14BD8136EF00C00649790 /* SUStatus.xib */; };
@ -51,7 +65,6 @@
55C14F08136EF6DB00649790 /* SULog.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C14F05136EF6DB00649790 /* SULog.m */; };
55C14F0C136EF6EA00649790 /* SUHost.m in Sources */ = {isa = PBXBuildFile; fileRef = 61EF67550E25B58D00F754E0 /* SUHost.m */; };
55C14F0D136EF6F200649790 /* SUInstaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 618FA5000DAE88B40026945C /* SUInstaller.m */; };
55C14F0F136EF73600649790 /* Autoupdate.pch in Headers */ = {isa = PBXBuildFile; fileRef = 55C14F0E136EF73600649790 /* Autoupdate.pch */; };
55C14F20136EF84300649790 /* SUStatusController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6196CFE409C71ADE000DC222 /* SUStatusController.m */; };
55C14F21136EF84D00649790 /* SUPlainInstaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 618FA5040DAE8AB80026945C /* SUPlainInstaller.m */; };
55C14F22136EF86000649790 /* SUStandardVersionComparator.m in Sources */ = {isa = PBXBuildFile; fileRef = 61A225A30D1C4AC000430CCD /* SUStandardVersionComparator.m */; };
@ -59,12 +72,10 @@
55C14F24136EF86F00649790 /* SUPackageInstaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 618FA5210DAE8E8A0026945C /* SUPackageInstaller.m */; };
55C14F2A136EF9A900649790 /* SUWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61180BC90D64138900B4E0D1 /* SUWindowController.m */; };
55C14F32136EFC2400649790 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55C14F31136EFC2400649790 /* SystemConfiguration.framework */; };
55C14F3B136EFCB300649790 /* Autoupdate.app in Resources */ = {isa = PBXBuildFile; fileRef = 55C14BB7136EEF1500649790 /* Autoupdate.app */; };
55C14F7E136F005000649790 /* SUPlainInstallerInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = 61B5F8E509C4CE3C00B25A18 /* SUPlainInstallerInternals.m */; };
55C14F9A136F045400649790 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61B5F8F609C4CEB300B25A18 /* Security.framework */; };
55C14FC7136F05E100649790 /* Sparkle.strings in Resources */ = {isa = PBXBuildFile; fileRef = 61AAE8220A321A7F00D8810D /* Sparkle.strings */; };
5AF9DC3C1981DBEE001EA135 /* SUDSAVerifierTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AF9DC3B1981DBEE001EA135 /* SUDSAVerifierTest.m */; };
5D06E8D80FD68C8E005AE3F6 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Sparkle.framework */; };
5D06E8E90FD68CDB005AE3F6 /* bsdiff.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D06E8DB0FD68CB9005AE3F6 /* bsdiff.c */; settings = {COMPILER_FLAGS = "-w"; }; };
5D06E8EA0FD68CDB005AE3F6 /* SUBinaryDeltaTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D06E8E30FD68CC7005AE3F6 /* SUBinaryDeltaTool.m */; };
5D06E8EB0FD68CE4005AE3F6 /* bspatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D06E8DC0FD68CB9005AE3F6 /* bspatch.c */; settings = {COMPILER_FLAGS = "-w"; }; };
@ -106,7 +117,6 @@
61299B3609CB04E000B7442F /* Sparkle.h in Headers */ = {isa = PBXBuildFile; fileRef = 61299B3509CB04E000B7442F /* Sparkle.h */; settings = {ATTRIBUTES = (Public, ); }; };
612DCBAF0D488BC60015DBEA /* SUUpdatePermissionPrompt.h in Headers */ = {isa = PBXBuildFile; fileRef = 612DCBAD0D488BC60015DBEA /* SUUpdatePermissionPrompt.h */; settings = {ATTRIBUTES = (); }; };
612DCBB00D488BC60015DBEA /* SUUpdatePermissionPrompt.m in Sources */ = {isa = PBXBuildFile; fileRef = 612DCBAE0D488BC60015DBEA /* SUUpdatePermissionPrompt.m */; };
61407C390A4099050009F71F /* Sparkle.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Sparkle.framework */; };
6158A1C5137904B300487EC1 /* SUUpdater_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 6158A1C4137904B300487EC1 /* SUUpdater_Private.h */; };
615AE3D00D64DC40001CA7BD /* SUModelTranslation.plist in Resources */ = {isa = PBXBuildFile; fileRef = 615AE3CF0D64DC40001CA7BD /* SUModelTranslation.plist */; };
6160E7E10D3B4A8800E9CD71 /* NTSynchronousTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 610EC1C00CF3914D00AE239E /* NTSynchronousTask.h */; settings = {ATTRIBUTES = (); }; };
@ -253,13 +263,33 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
142E0E0119A6A13300E4312B /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
142E0E0219A6A14700E4312B /* Sparkle.framework in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
142E0E0319A6A24100E4312B /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 12;
files = (
142E0E0419A6A26F00E4312B /* Autoupdate.app in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
61B5FB4D09C4E9FA00B25A18 /* Copy Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
61407C390A4099050009F71F /* Sparkle.framework in Copy Frameworks */,
142E0E0019A6954400E4312B /* Sparkle.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@ -280,6 +310,10 @@
1420DF4D196247B500203BB0 /* build-docs.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "build-docs.sh"; sourceTree = "<group>"; };
1420DF4E196247B500203BB0 /* Doxyfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Doxyfile; sourceTree = "<group>"; };
1420DF4F196247F900203BB0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
142E0E0819A83AAC00E4312B /* SUBinaryDeltaTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SUBinaryDeltaTest.m; sourceTree = "<group>"; };
14652F7919A93E5F00959E44 /* set-git-version-info.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "set-git-version-info.sh"; sourceTree = "<group>"; };
14652F8319A9759F00959E44 /* SUExport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SUExport.h; sourceTree = "<group>"; };
146EC84E19A68CF8004A50C5 /* Sparkle.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = Sparkle.podspec; sourceTree = SOURCE_ROOT; };
14732BB1195FF6B700593899 /* .clang-format */ = {isa = PBXFileReference; lastKnownFileType = text; path = ".clang-format"; sourceTree = SOURCE_ROOT; };
14732BB91960EEEE00593899 /* SampleAppcast.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = SampleAppcast.xml; sourceTree = "<group>"; };
14732BBA1960EF7100593899 /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = SOURCE_ROOT; };
@ -290,7 +324,9 @@
14732BC41960F3FF00593899 /* sign_update.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = sign_update.sh; sourceTree = "<group>"; };
14732BC91960F70A00593899 /* make-release-package.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "make-release-package.sh"; sourceTree = "<group>"; };
14732BD219610A1800593899 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
14950074195FDF5900BC5B5B /* SUUpdaterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SUUpdaterTest.m; path = Tests/SUUpdaterTest.m; sourceTree = "<group>"; usesTabs = 0; };
14950074195FDF5900BC5B5B /* SUUpdaterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SUUpdaterTest.m; sourceTree = "<group>"; usesTabs = 0; };
14958C6B19AEBC530061B14F /* signed-test-file.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "signed-test-file.txt"; sourceTree = "<group>"; };
14958C6C19AEBC610061B14F /* test-pubkey.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "test-pubkey.pem"; sourceTree = "<group>"; };
3772FEA813DE0B6B00F79537 /* SUVersionDisplayProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SUVersionDisplayProtocol.h; sourceTree = "<group>"; };
4607BEA21948443800EF8DA4 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Sparkle.strings; sourceTree = "<group>"; };
4607BEA31948443800EF8DA4 /* nb */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = nb; path = nb.lproj/SUAutomaticUpdateAlert.xib; sourceTree = "<group>"; };
@ -361,10 +397,9 @@
55C14C18136EF2C700649790 /* zh_TW */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = zh_TW; path = zh_TW.lproj/SUUpdatePermissionPrompt.xib; sourceTree = "<group>"; };
55C14F04136EF6DB00649790 /* SULog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SULog.h; sourceTree = "<group>"; };
55C14F05136EF6DB00649790 /* SULog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SULog.m; sourceTree = "<group>"; };
55C14F0E136EF73600649790 /* Autoupdate.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Autoupdate.pch; sourceTree = "<group>"; };
55C14F31136EFC2400649790 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
5AEF45D9189D1CC90030D7DC /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Sparkle.strings; sourceTree = "<group>"; };
5AF9DC3B1981DBEE001EA135 /* SUDSAVerifierTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SUDSAVerifierTest.m; path = Tests/SUDSAVerifierTest.m; sourceTree = "<group>"; };
5AF9DC3B1981DBEE001EA135 /* SUDSAVerifierTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SUDSAVerifierTest.m; sourceTree = "<group>"; };
5D06E8D00FD68C7C005AE3F6 /* BinaryDelta */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = BinaryDelta; sourceTree = BUILT_PRODUCTS_DIR; };
5D06E8DB0FD68CB9005AE3F6 /* bsdiff.c */ = {isa = PBXFileReference; comments = "-Wno-shorten-64-to-32"; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bsdiff.c; sourceTree = "<group>"; };
5D06E8DC0FD68CB9005AE3F6 /* bspatch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bspatch.c; sourceTree = "<group>"; };
@ -404,8 +439,8 @@
6120721009CC5C4B007FE0F6 /* SUAutomaticUpdateAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SUAutomaticUpdateAlert.h; sourceTree = "<group>"; };
6120721109CC5C4B007FE0F6 /* SUAutomaticUpdateAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SUAutomaticUpdateAlert.m; sourceTree = "<group>"; };
612279D90DB5470200AB99EA /* Sparkle Unit Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Sparkle Unit Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
612279DA0DB5470200AB99EA /* SparkleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "SparkleTests-Info.plist"; path = "Tests/SparkleTests-Info.plist"; sourceTree = "<group>"; };
61227A150DB548B800AB99EA /* SUVersionComparisonTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SUVersionComparisonTest.m; path = Tests/SUVersionComparisonTest.m; sourceTree = "<group>"; };
612279DA0DB5470200AB99EA /* SparkleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SparkleTests-Info.plist"; sourceTree = "<group>"; };
61227A150DB548B800AB99EA /* SUVersionComparisonTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SUVersionComparisonTest.m; sourceTree = "<group>"; };
6129984309C9E2DA00B7442F /* SUPlainInstallerInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SUPlainInstallerInternals.h; sourceTree = "<group>"; };
61299A2D09CA2DAB00B7442F /* SUDSAVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SUDSAVerifier.h; sourceTree = "<group>"; };
61299A2E09CA2DAB00B7442F /* SUDSAVerifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SUDSAVerifier.m; sourceTree = "<group>"; };
@ -535,7 +570,6 @@
5D1AF58B0FD7678C0065DB48 /* libxar.1.dylib in Frameworks */,
5D1AF5900FD767AD0065DB48 /* libxml2.dylib in Frameworks */,
5D1AF59A0FD767E50065DB48 /* libz.dylib in Frameworks */,
5D06E8D80FD68C8E005AE3F6 /* Sparkle.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -546,6 +580,7 @@
14732BD119610A1200593899 /* AppKit.framework in Frameworks */,
14732BD019610A0D00593899 /* Foundation.framework in Frameworks */,
61FA52880E2D9EA400EF58AD /* Sparkle.framework in Frameworks */,
14652F8019A9740F00959E44 /* Security.framework in Frameworks */,
14732BD319610A1800593899 /* XCTest.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -717,12 +752,20 @@
path = Sparkle;
sourceTree = "<group>";
};
14958C7019AEBE350061B14F /* Resources */ = {
isa = PBXGroup;
children = (
14958C6B19AEBC530061B14F /* signed-test-file.txt */,
14958C6C19AEBC610061B14F /* test-pubkey.pem */,
);
path = Resources;
sourceTree = "<group>";
};
55C14BD5136EEFD000649790 /* Autoupdate */ = {
isa = PBXGroup;
children = (
55C14BB9136EEF1500649790 /* Autoupdate-Info.plist */,
55C14BD3136EEFCE00649790 /* Autoupdate.m */,
55C14F0E136EF73600649790 /* Autoupdate.pch */,
);
path = Autoupdate;
sourceTree = "<group>";
@ -760,11 +803,13 @@
isa = PBXGroup;
children = (
612279DA0DB5470200AB99EA /* SparkleTests-Info.plist */,
142E0E0819A83AAC00E4312B /* SUBinaryDeltaTest.m */,
5AF9DC3B1981DBEE001EA135 /* SUDSAVerifierTest.m */,
14950074195FDF5900BC5B5B /* SUUpdaterTest.m */,
61227A150DB548B800AB99EA /* SUVersionComparisonTest.m */,
14958C7019AEBE350061B14F /* Resources */,
);
name = Tests;
path = Tests;
sourceTree = "<group>";
};
61299B3909CB055000B7442F /* Appcast Support */ = {
@ -823,6 +868,7 @@
61CFB3280E385186007A1735 /* Sparkle.pch */,
61299A5B09CA6D4500B7442F /* SUConstants.h */,
61299A5F09CA6EB100B7442F /* SUConstants.m */,
14652F8319A9759F00959E44 /* SUExport.h */,
61EF67580E25C5B400F754E0 /* SUHost.h */,
61EF67550E25B58D00F754E0 /* SUHost.m */,
55C14F04136EF6DB00649790 /* SULog.h */,
@ -912,6 +958,8 @@
FA3AAF3A1050B273004B3130 /* ConfigUnitTestDebug.xcconfig */,
FA3AAF391050B273004B3130 /* ConfigUnitTestRelease.xcconfig */,
14732BC91960F70A00593899 /* make-release-package.sh */,
14652F7919A93E5F00959E44 /* set-git-version-info.sh */,
146EC84E19A68CF8004A50C5 /* Sparkle.podspec */,
);
path = Configurations;
sourceTree = "<group>";
@ -923,7 +971,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
55C14F0F136EF73600649790 /* Autoupdate.pch in Headers */,
611142E910FB1BE5009810AA /* bspatch.h in Headers */,
6160E7E10D3B4A8800E9CD71 /* NTSynchronousTask.h in Headers */,
61299B3609CB04E000B7442F /* Sparkle.h in Headers */,
@ -936,6 +983,7 @@
5D06E9390FD69271005AE3F6 /* SUBinaryDeltaUnarchiver.h in Headers */,
61B078CE15A5FB6100600039 /* SUCodeSigningVerifier.h in Headers */,
61299A5C09CA6D4500B7442F /* SUConstants.h in Headers */,
14652F8419A978C200959E44 /* SUExport.h in Headers */,
6102FE4A0E07803800F85D09 /* SUDiskImageUnarchiver.h in Headers */,
61299A2F09CA2DAB00B7442F /* SUDSAVerifier.h in Headers */,
61EF67590E25C5B400F754E0 /* SUHost.h in Headers */,
@ -1010,6 +1058,7 @@
55C14BB3136EEF1500649790 /* Resources */,
55C14BB4136EEF1500649790 /* Sources */,
55C14BB5136EEF1500649790 /* Frameworks */,
14652F7B19A945D600959E44 /* Run Script: Set Git Version Info */,
);
buildRules = (
);
@ -1026,7 +1075,6 @@
buildPhases = (
5D06E8CD0FD68C7C005AE3F6 /* Sources */,
5D06E8CE0FD68C7C005AE3F6 /* Frameworks */,
5D06E90D0FD68DA3005AE3F6 /* Fix Install Name */,
);
buildRules = (
);
@ -1042,9 +1090,10 @@
isa = PBXNativeTarget;
buildConfigurationList = 612279DD0DB5470300AB99EA /* Build configuration list for PBXNativeTarget "Sparkle Unit Tests" */;
buildPhases = (
612279D40DB5470200AB99EA /* Resources */,
612279D50DB5470200AB99EA /* Sources */,
612279D60DB5470200AB99EA /* Frameworks */,
14958C6D19AEBC890061B14F /* Resources */,
142E0E0119A6A13300E4312B /* CopyFiles */,
612279D70DB5470200AB99EA /* ShellScript */,
);
buildRules = (
@ -1082,9 +1131,10 @@
buildPhases = (
8DC2EF500486A6940098B216 /* Headers */,
8DC2EF520486A6940098B216 /* Resources */,
142E0E0319A6A24100E4312B /* CopyFiles */,
8DC2EF540486A6940098B216 /* Sources */,
8DC2EF560486A6940098B216 /* Frameworks */,
6131B1910DDCDE32005215F0 /* Run Script: Set git Version Info */,
6131B1910DDCDE32005215F0 /* Run Script: Set Git Version Info */,
6195D4B40E40505A00D41A50 /* Run Script: Link fr_CA to fr */,
61E31A85103299750051D188 /* Run Script: Link pt to pt_BR */,
);
@ -1179,6 +1229,15 @@
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
14958C6D19AEBC890061B14F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
14958C6F19AEBC980061B14F /* test-pubkey.pem in Resources */,
14958C6E19AEBC950061B14F /* signed-test-file.txt in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
55C14BB3136EEF1500649790 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -1189,13 +1248,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
612279D40DB5470200AB99EA /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
61B5F8FE09C4CEE200B25A18 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -1211,7 +1263,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
55C14F3B136EFCB300649790 /* Autoupdate.app in Resources */,
61AAE8280A321A7F00D8810D /* Sparkle.strings in Resources */,
55C14BEE136EF20D00649790 /* SUAutomaticUpdateAlert.xib in Resources */,
615AE3D00D64DC40001CA7BD /* SUModelTranslation.plist in Resources */,
@ -1224,20 +1275,20 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
5D06E90D0FD68DA3005AE3F6 /* Fix Install Name */ = {
14652F7B19A945D600959E44 /* Run Script: Set Git Version Info */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Fix Install Name";
name = "Run Script: Set Git Version Info";
outputPaths = (
"$(CONFIGURATION_BUILD_DIR)/BinaryDelta",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "install_name_tool -change \"@loader_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle\" \"@loader_path/Sparkle.framework/Versions/A/Sparkle\" \"${CONFIGURATION_BUILD_DIR}/BinaryDelta\"";
shellScript = "\"$SRCROOT/Configurations/set-git-version-info.sh\"";
showEnvVarsInLog = 0;
};
612279D70DB5470200AB99EA /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@ -1253,19 +1304,19 @@
shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
showEnvVarsInLog = 0;
};
6131B1910DDCDE32005215F0 /* Run Script: Set git Version Info */ = {
6131B1910DDCDE32005215F0 /* Run Script: Set Git Version Info */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 12;
files = (
);
inputPaths = (
);
name = "Run Script: Set git Version Info";
name = "Run Script: Set Git Version Info";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/usr/bin/env ruby";
shellScript = "# Xcode auto-versioning script for Subversion\n# by Axel Andersson, modified by Daniel Jalkut to add\n# \"--revision HEAD\" to the svn info line, which allows\n# the latest revision to always be used.\n\nif ENV[\"BUILT_PRODUCTS_DIR\"].nil?\n\tSTDERR.print \"#{$0}: Must be run from Xcode!\"\n\texit(1)\nend\n\n# Get the current Git master hash and use it to set the CFBundleVersion value\nENV[\"PATH\"] = \"/bin:/sw/bin:/usr/local/git/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/opt/local/bin\"\nexit(0) if `type git` == \"\"\nrev = `/usr/bin/env git show-ref --abbrev heads/master`\ninfo = \"#{ENV[\"BUILT_PRODUCTS_DIR\"]}/#{ENV[\"WRAPPER_NAME\"]}/Resources/Info.plist\"\nversion = rev.split(\" \")[0]\n\nif version.nil?\n\tSTDERR.print \"#{$0}: Can't find a Git hash!\"\n\texit(0)\nend\n\ninfo_contents = File.read(info)\nif info_contents.nil?\n\tSTDERR.print \"#{$0}: Can't read in the Info.plist file!\"\n\texit(1)\nend\n\ninfo_contents.sub!(/([\\t ]+<key>CFBundleVersion<\\/key>\\n[\\t ]+<string>).*?(<\\/string>)/, '\\1' + version + '\\2')\nSTDERR.print info_contents\nf = File.open(info, \"w\")\nf.write(info_contents)\nf.close";
shellPath = /bin/sh;
shellScript = "\"$SRCROOT/Configurations/set-git-version-info.sh\"";
showEnvVarsInLog = 0;
};
6195D4B40E40505A00D41A50 /* Run Script: Link fr_CA to fr */ = {
@ -1274,15 +1325,15 @@
files = (
);
inputPaths = (
"$(BUILT_PRODUCTS_DIR)/$(WRAPPER_NAME)/Resources/fr.lproj",
"$(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/fr.lproj",
);
name = "Run Script: Link fr_CA to fr";
outputPaths = (
"$(BUILT_PRODUCTS_DIR)/$(WRAPPER_NAME)/Resources/fr_CA.lproj",
"$(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/fr_CA.lproj",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/usr/bin/env sh";
shellScript = "ln -sfh \"fr.lproj\" \"$BUILT_PRODUCTS_DIR/$WRAPPER_NAME/Resources/fr_CA.lproj\"";
shellScript = "ln -sfh \"fr.lproj\" \"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/fr_CA.lproj\"";
showEnvVarsInLog = 0;
};
61E31A85103299750051D188 /* Run Script: Link pt to pt_BR */ = {
@ -1291,15 +1342,15 @@
files = (
);
inputPaths = (
"$(BUILT_PRODUCTS_DIR)/$(WRAPPER_NAME)/Resources/pt_BR.lproj",
"$(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/pt_BR.lproj",
);
name = "Run Script: Link pt to pt_BR";
outputPaths = (
"$(BUILT_PRODUCTS_DIR)/$(WRAPPER_NAME)/Resources/pt.lproj",
"$(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/pt.lproj",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/usr/bin/env sh";
shellScript = "ln -sfh \"pt_BR.lproj\" \"$BUILT_PRODUCTS_DIR/$WRAPPER_NAME/Resources/pt.lproj\"";
shellScript = "ln -sfh \"pt_BR.lproj\" \"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/pt.lproj\"";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@ -1329,6 +1380,9 @@
buildActionMask = 2147483647;
files = (
5D06E8E90FD68CDB005AE3F6 /* bsdiff.c in Sources */,
14652F7E19A9728A00959E44 /* bspatch.c in Sources */,
14652F7D19A9726700959E44 /* SUBinaryDeltaApply.m in Sources */,
14652F7C19A9725300959E44 /* SUBinaryDeltaCommon.m in Sources */,
5D06E8EA0FD68CDB005AE3F6 /* SUBinaryDeltaTool.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1337,7 +1391,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
14652F8119A9744200959E44 /* SUBinaryDeltaCommon.m in Sources */,
14652F7F19A973F900959E44 /* SUDSAVerifier.m in Sources */,
14652F8219A9746000959E44 /* SULog.m in Sources */,
5AF9DC3C1981DBEE001EA135 /* SUDSAVerifierTest.m in Sources */,
142E0E0919A83AAC00E4312B /* SUBinaryDeltaTest.m in Sources */,
14950075195FDF5900BC5B5B /* SUUpdaterTest.m in Sources */,
61227A160DB548B800AB99EA /* SUVersionComparisonTest.m in Sources */,
);
@ -1674,7 +1732,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = FA1941CF0D94A70100DD942E /* ConfigCommonDebug.xcconfig */;
buildSettings = {
ONLY_ACTIVE_ARCH = YES;
};
name = Debug;
};
@ -1717,12 +1774,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = FA3AAF3A1050B273004B3130 /* ConfigUnitTestDebug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Sparkle.framework/Versions/A/Sparkle";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
TEST_HOST = "$(BUNDLE_LOADER)";
};
name = Debug;
};
@ -1730,12 +1781,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = FA3AAF391050B273004B3130 /* ConfigUnitTestRelease.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Sparkle.framework/Versions/A/Sparkle";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
TEST_HOST = "$(BUNDLE_LOADER)";
};
name = Release;
};

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14732BC51960F69300593899"
BuildableName = "Distribution"
BlueprintName = "Distribution"
ReferencedContainer = "container:Sparkle.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "612279D80DB5470200AB99EA"
BuildableName = "Sparkle Unit Tests.xctest"
BlueprintName = "Sparkle Unit Tests"
ReferencedContainer = "container:Sparkle.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14732BC51960F69300593899"
BuildableName = "Distribution"
BlueprintName = "Distribution"
ReferencedContainer = "container:Sparkle.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14732BC51960F69300593899"
BuildableName = "Distribution"
BlueprintName = "Distribution"
ReferencedContainer = "container:Sparkle.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14732BC51960F69300593899"
BuildableName = "Distribution"
BlueprintName = "Distribution"
ReferencedContainer = "container:Sparkle.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -20,10 +20,10 @@ static const NSTimeInterval SUParentQuitCheckInterval = .25;
@interface TerminationListener : NSObject <SUInstallerDelegate>
@property (assign) const char *hostpath;
@property (assign) const char *executablepath;
@property (copy) NSString *hostpath;
@property (copy) NSString *executablepath;
@property (assign) pid_t parentprocessid;
@property (assign) const char *folderpath;
@property (copy) NSString *folderpath;
@property (copy) NSString *selfPath;
@property (copy) NSString *installationPath;
@ -58,26 +58,26 @@ static const NSTimeInterval SUParentQuitCheckInterval = .25;
@synthesize shouldRelaunch;
@synthesize shouldShowUI;
- (instancetype)initWithHostPath:(const char *)inhostpath executablePath:(const char *)execpath parentProcessId:(pid_t)ppid folderPath:(const char *)infolderpath shouldRelaunch:(BOOL)relaunch shouldShowUI:(BOOL)showUI selfPath:(NSString *)inSelfPath
- (instancetype)initWithHostPath:(NSString *)inhostpath executablePath:(NSString *)execpath parentProcessId:(pid_t)ppid folderPath:(NSString *)infolderpath shouldRelaunch:(BOOL)relaunch shouldShowUI:(BOOL)showUI selfPath:(NSString *)inSelfPath
{
if (!(self = [super init])) {
return nil;
}
hostpath = inhostpath;
executablepath = execpath;
parentprocessid = ppid;
folderpath = infolderpath;
selfPath = inSelfPath;
shouldRelaunch = relaunch;
shouldShowUI = showUI;
self.hostpath = inhostpath;
self.executablepath = execpath;
self.parentprocessid = ppid;
self.folderpath = infolderpath;
self.selfPath = inSelfPath;
self.shouldRelaunch = relaunch;
self.shouldShowUI = showUI;
BOOL alreadyTerminated = (getppid() == 1); // ppid is launchd (1) => parent terminated already
if (alreadyTerminated)
[self parentHasQuit];
else
watchdogTimer = [NSTimer scheduledTimerWithTimeInterval:SUParentQuitCheckInterval target:self selector:@selector(watchdog:) userInfo:nil repeats:YES];
self.watchdogTimer = [NSTimer scheduledTimerWithTimeInterval:SUParentQuitCheckInterval target:self selector:@selector(watchdog:) userInfo:nil repeats:YES];
return self;
}
@ -85,7 +85,7 @@ static const NSTimeInterval SUParentQuitCheckInterval = .25;
- (void)dealloc
{
[longInstallationTimer invalidate];
[self.longInstallationTimer invalidate];
}
@ -121,8 +121,8 @@ static const NSTimeInterval SUParentQuitCheckInterval = .25;
if (self.shouldRelaunch)
{
NSString *appPath = nil;
if (!self.folderpath || strcmp(self.executablepath, self.hostpath) != 0)
appPath = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:self.executablepath length:strlen(self.executablepath)];
if (!self.folderpath || ![self.executablepath isEqualToString:self.hostpath])
appPath = self.executablepath;
else
appPath = self.installationPath;
[[NSWorkspace sharedWorkspace] openFile:appPath];
@ -142,7 +142,7 @@ static const NSTimeInterval SUParentQuitCheckInterval = .25;
- (void)install
{
NSBundle *theBundle = [NSBundle bundleWithPath:[[NSFileManager defaultManager] stringWithFileSystemRepresentation:self.hostpath length:strlen(self.hostpath)]];
NSBundle *theBundle = [NSBundle bundleWithPath:self.hostpath];
self.host = [[SUHost alloc] initWithBundle:theBundle];
self.installationPath = [[self.host installationPath] copy];
@ -154,7 +154,7 @@ static const NSTimeInterval SUParentQuitCheckInterval = .25;
[statusCtl showWindow:self];
}
[SUInstaller installFromUpdateFolder:[[NSFileManager defaultManager] stringWithFileSystemRepresentation:self.folderpath length:strlen(self.folderpath)]
[SUInstaller installFromUpdateFolder:self.folderpath
overHost:self.host
installationPath:self.installationPath
delegate:self
@ -175,44 +175,28 @@ static const NSTimeInterval SUParentQuitCheckInterval = .25;
@end
int main(int argc, const char *argv[])
int main(int __unused argc, const char __unused *argv[])
{
if (argc < 5 || argc > 7) {
return EXIT_FAILURE;
}
@autoreleasepool {
//ProcessSerialNumber psn = { 0, kCurrentProcess };
//TransformProcessType( &psn, kProcessTransformToForegroundApplication );
NSArray *args = [[NSProcessInfo processInfo] arguments];
if (args.count < 5 || args.count > 7) {
return EXIT_FAILURE;
}
#if 0 // Cmdline tool
NSString* selfPath = nil;
if (argv[0][0] == '/') {
selfPath = [[NSFileManager defaultManager] stringWithFileSystemRepresentation: argv[0] length: strlen(argv[0])];
}
else
{
selfPath = [[NSFileManager defaultManager] currentDirectoryPath];
selfPath = [selfPath stringByAppendingPathComponent: [[NSFileManager defaultManager] stringWithFileSystemRepresentation: argv[0] length: strlen(argv[0])]];
}
#else
NSString *selfPath = [[NSBundle mainBundle] bundlePath];
#endif
BOOL shouldShowUI = (argc > 6) ? !!atoi(argv[6]) : YES;
BOOL shouldShowUI = (args.count > 6) ? [args[6] boolValue] : YES;
if (shouldShowUI)
{
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
}
[NSApplication sharedApplication];
TerminationListener *termListen = [[TerminationListener alloc] initWithHostPath:(argc > 1) ? argv[1] : NULL
executablePath:(argc > 2) ? argv[2] : NULL
parentProcessId:(argc > 3) ? atoi(argv[3]) : 0
folderPath:(argc > 4) ? argv[4] : NULL
shouldRelaunch:(argc > 5) ? !!atoi(argv[5]) : YES
TerminationListener *termListen = [[TerminationListener alloc] initWithHostPath:args[1]
executablePath:args[2]
parentProcessId:[args[3] intValue]
folderPath:args[4]
shouldRelaunch:(args.count > 5) ? [args[5] boolValue] : YES
shouldShowUI:shouldShowUI
selfPath:selfPath];
selfPath:[[NSBundle mainBundle] bundlePath]];
[termListen class];
[[NSApplication sharedApplication] run];

View File

@ -1,16 +0,0 @@
//
// Sparkle.pch
// Sparkle
//
// Created by Andy Matuschak on 7/23/08.
// Copyright 2008 Andy Matuschak. All rights reserved.
//
#define SPARKLE_BUNDLE [NSBundle mainBundle]
#define SULocalizedString(key,comment) NSLocalizedStringFromTableInBundle(key, @"Sparkle", SPARKLE_BUNDLE, comment)
#define SUAbstractFail() NSAssert2(nil, @"Can't call %@ on an instance of %@; this is an abstract method!", __PRETTY_FUNCTION__, [self class]);
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#import "SUConstants.h"
#endif

View File

@ -9,10 +9,12 @@
#ifndef SUAPPCAST_H
#define SUAPPCAST_H
#import "SUExport.h"
@protocol SUAppcastDelegate;
@class SUAppcastItem;
@interface SUAppcast : NSObject <NSURLDownloadDelegate>
SU_EXPORT @interface SUAppcast : NSObject <NSURLDownloadDelegate>
@property (weak) id<SUAppcastDelegate> delegate;
@property (copy) NSString *userAgentString;

View File

@ -145,30 +145,38 @@
for (NSString *name in nodesDict)
{
node = [self bestNodeInNodes:nodesDict[name]];
if ([name isEqualToString:@"enclosure"])
if ([name isEqualToString:SURSSElementEnclosure])
{
// enclosure is flattened as a separate dictionary for some reason
NSDictionary *encDict = [(NSXMLElement *)node attributesAsDictionary];
dict[@"enclosure"] = encDict;
dict[name] = encDict;
}
else if ([name isEqualToString:@"pubDate"])
else if ([name isEqualToString:SURSSElementPubDate])
{
// pubDate is expected to be an NSDate by SUAppcastItem, but the RSS class was returning an NSString
NSDate *date = [NSDate dateWithNaturalLanguageString:[node stringValue]];
if (date)
dict[name] = date;
}
else if ([name isEqualToString:@"sparkle:deltas"])
else if ([name isEqualToString:SUAppcastElementDeltas])
{
NSMutableArray *deltas = [NSMutableArray array];
NSEnumerator *childEnum = [[node children] objectEnumerator];
for (NSXMLNode *child in childEnum) {
if ([[child name] isEqualToString:@"enclosure"])
if ([[child name] isEqualToString:SURSSElementEnclosure])
[deltas addObject:[(NSXMLElement *)child attributesAsDictionary]];
}
dict[@"deltas"] = deltas;
dict[name] = deltas;
}
else if ([name isEqualToString:SUAppcastElementTags]) {
NSMutableArray *tags = [NSMutableArray array];
NSEnumerator *childEnum = [[node children] objectEnumerator];
for (NSXMLNode *child in childEnum) {
[tags addObject:[child name]];
}
dict[name] = tags;
}
else if (name != nil)
{
// add all other values as strings
@ -196,7 +204,11 @@
if ([appcastItems count])
{
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wselector"
// @selector(date) is from SUAppcastItem
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:NSStringFromSelector(@selector(date)) ascending:NO];
#pragma clang diagnostic pop
[appcastItems sortUsingDescriptors:@[sort]];
self.items = appcastItems;
}

View File

@ -9,7 +9,9 @@
#ifndef SUAPPCASTITEM_H
#define SUAPPCASTITEM_H
@interface SUAppcastItem : NSObject
#include "SUExport.h"
SU_EXPORT @interface SUAppcastItem : NSObject
@property (copy, readonly) NSString *title;
@property (copy, readonly) NSDate *date;
@property (copy, readonly) NSString *itemDescription;

View File

@ -47,12 +47,12 @@
- (BOOL)isDeltaUpdate
{
return self.propertiesDictionary[@"enclosure"][@"sparkle:deltaFrom"] != nil;
return self.propertiesDictionary[SURSSElementEnclosure][SUAppcastAttributeDeltaFrom] != nil;
}
- (BOOL)isCriticalUpdate
{
return [self.propertiesDictionary[@"sparkle:tags"] containsObject:@"sparkle:criticalUpdate"];
return [self.propertiesDictionary[SUAppcastElementTags] containsObject:SUAppcastElementCriticalUpdate];
}
- (instancetype)initWithDictionary:(NSDictionary *)dict
@ -64,7 +64,7 @@
{
self = [super init];
if (self) {
id enclosure = dict[@"enclosure"];
id enclosure = dict[SURSSElementEnclosure];
// Try to find a version string.
// Finding the new version number from the RSS feed is a little bit hacky. There are two ways:
@ -74,17 +74,17 @@
// underscore and the last period as the version number. So name your packages like this: APPNAME_VERSION.extension.
// The big caveat with this is that you can't have underscores in your version strings, as that'll confuse Sparkle.
// Feel free to change the separator string to a hyphen or something more suited to your needs if you like.
NSString *newVersion = enclosure[@"sparkle:version"];
NSString *newVersion = enclosure[SUAppcastAttributeVersion];
if (newVersion == nil) {
newVersion = dict[@"sparkle:version"]; // Get version from the item, in case it's a download-less item (i.e. paid upgrade).
newVersion = dict[SUAppcastAttributeVersion]; // Get version from the item, in case it's a download-less item (i.e. paid upgrade).
}
if (newVersion == nil) // no sparkle:version attribute anywhere?
{
SULog(@"warning: <enclosure> for URL '%@' is missing sparkle:version attribute. Version comparison may be unreliable. Please always specify sparkle:version", enclosure[@"url"]);
SULog(@"warning: <%@> for URL '%@' is missing %@ attribute. Version comparison may be unreliable. Please always specify %@", SURSSElementEnclosure, enclosure[SURSSAttributeURL], SUAppcastAttributeVersion, SUAppcastAttributeVersion);
// Separate the url by underscores and take the last component, as that'll be closest to the end,
// then we remove the extension. Hopefully, this will be the version.
NSArray *fileComponents = [enclosure[@"url"] componentsSeparatedByString:@"_"];
NSArray *fileComponents = [enclosure[SURSSAttributeURL] componentsSeparatedByString:@"_"];
if ([fileComponents count] > 1) {
newVersion = [[fileComponents lastObject] stringByDeletingPathExtension];
}
@ -92,20 +92,20 @@
if (!newVersion) {
if (error) {
*error = @"Feed item lacks sparkle:version attribute, and version couldn't be deduced from file name (would have used last component of a file name like AppName_1.3.4.zip)";
*error = [NSString stringWithFormat:@"Feed item lacks %@ attribute, and version couldn't be deduced from file name (would have used last component of a file name like AppName_1.3.4.zip)", SUAppcastAttributeVersion];
}
return nil;
}
propertiesDictionary = [[NSMutableDictionary alloc] initWithDictionary:dict];
self.title = dict[@"title"];
self.date = dict[@"pubDate"];
self.itemDescription = dict[@"description"];
self.title = dict[SURSSElementTitle];
self.date = dict[SURSSElementPubDate];
self.itemDescription = dict[SURSSElementDescription];
NSString *theInfoURL = dict[@"link"];
NSString *theInfoURL = dict[SURSSElementLink];
if (theInfoURL) {
if (![theInfoURL isKindOfClass:[NSString class]]) {
SULog(@"SUAppcastItem -initWithDictionary: Info URL is not of valid type.");
SULog(@"%@ -%@ Info URL is not of valid type.", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
} else {
self.infoURL = [NSURL URLWithString:theInfoURL];
}
@ -120,7 +120,7 @@
return nil;
}
NSString *enclosureURLString = enclosure[@"url"];
NSString *enclosureURLString = enclosure[SURSSAttributeURL];
if (!enclosureURLString && !theInfoURL) {
if (error) {
*error = @"Feed item's enclosure lacks URL";
@ -133,16 +133,16 @@
self.fileURL = [NSURL URLWithString:fileURLString];
}
if (enclosure) {
self.DSASignature = enclosure[@"sparkle:dsaSignature"];
self.DSASignature = enclosure[SUAppcastAttributeDSASignature];
}
self.versionString = newVersion;
self.minimumSystemVersion = dict[@"sparkle:minimumSystemVersion"];
self.maximumSystemVersion = dict[@"sparkle:maximumSystemVersion"];
self.minimumSystemVersion = dict[SUAppcastElementMinimumSystemVersion];
self.maximumSystemVersion = dict[SUAppcastElementMaximumSystemVersion];
NSString *shortVersionString = enclosure[@"sparkle:shortVersionString"];
NSString *shortVersionString = enclosure[SUAppcastAttributeShortVersionString];
if (nil == shortVersionString) {
shortVersionString = dict[@"sparkle:shortVersionString"]; // fall back on the <item>
shortVersionString = dict[SUAppcastAttributeShortVersionString]; // fall back on the <item>
}
if (shortVersionString) {
@ -152,24 +152,24 @@
}
// Find the appropriate release notes URL.
if (dict[@"sparkle:releaseNotesLink"]) {
self.releaseNotesURL = [NSURL URLWithString:dict[@"sparkle:releaseNotesLink"]];
if (dict[SUAppcastElementReleaseNotesLink]) {
self.releaseNotesURL = [NSURL URLWithString:dict[SUAppcastElementReleaseNotesLink]];
} else if ([self.itemDescription hasPrefix:@"http://"] || [self.itemDescription hasPrefix:@"https://"]) { // if the description starts with http:// or https:// use that.
self.releaseNotesURL = [NSURL URLWithString:self.itemDescription];
} else {
self.releaseNotesURL = nil;
}
if (dict[@"deltas"]) {
NSArray *deltaDictionaries = dict[SUAppcastElementDeltas];
if (deltaDictionaries) {
NSMutableDictionary *deltas = [NSMutableDictionary dictionary];
NSArray *deltaDictionaries = dict[@"deltas"];
for (NSDictionary *deltaDictionary in deltaDictionaries) {
NSMutableDictionary *fakeAppCastDict = [dict mutableCopy];
[fakeAppCastDict removeObjectForKey:@"deltas"];
fakeAppCastDict[@"enclosure"] = deltaDictionary;
[fakeAppCastDict removeObjectForKey:SUAppcastElementDeltas];
fakeAppCastDict[SURSSElementEnclosure] = deltaDictionary;
SUAppcastItem *deltaItem = [[[self class] alloc] initWithDictionary:fakeAppCastDict];
deltas[deltaDictionary[@"sparkle:deltaFrom"]] = deltaItem;
deltas[deltaDictionary[SUAppcastAttributeDeltaFrom]] = deltaItem;
}
self.deltaUpdates = deltas;
}

View File

@ -135,7 +135,7 @@ static const NSTimeInterval SUAutomaticUpdatePromptImpatienceTimer = 60 * 60 * 2
- (void)applicationDidBecomeActive:(NSNotification *)__unused aNotification
{
[[self.alert window] makeKeyAndOrderFront:self];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"NSApplicationDidBecomeActiveNotification" object:NSApp];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidBecomeActiveNotification object:NSApp];
}
- (void)automaticUpdateAlert:(SUAutomaticUpdateAlert *)__unused aua finishedWithChoice:(SUAutomaticInstallationChoice)choice

View File

@ -21,15 +21,6 @@
#import "SUCodeSigningVerifier.h"
#import "SUUpdater_Private.h"
#ifdef FINISH_INSTALL_TOOL_NAME
// FINISH_INSTALL_TOOL_NAME expands to unquoted Autoupdate
#define QUOTE_NS_STRING2(str) @"" #str
#define QUOTE_NS_STRING1(str) QUOTE_NS_STRING2(str)
#define FINISH_INSTALL_TOOL_NAME_STRING QUOTE_NS_STRING1(FINISH_INSTALL_TOOL_NAME)
#else
#error FINISH_INSTALL_TOOL_NAME not defined
#endif
@interface SUBasicUpdateDriver ()
@property (strong) SUAppcastItem *updateItem;
@ -360,11 +351,11 @@
[updaterDelegate updater:self.updater willInstallUpdate:self.updateItem];
}
NSString *const finishInstallToolName = FINISH_INSTALL_TOOL_NAME_STRING;
NSBundle *sparkleBundle = [NSBundle bundleWithIdentifier:SUBundleIdentifier];
// Copy the relauncher into a temporary directory so we can get to it after the new version's installed.
// Only the paranoid survive: if there's already a stray copy of relaunch there, we would have problems.
NSString *relaunchPathToCopy = [SPARKLE_BUNDLE pathForResource:finishInstallToolName ofType:@"app"];
NSString *const relaunchPathToCopy = [sparkleBundle pathForResource:[[sparkleBundle infoDictionary] objectForKey:SURelaunchToolNameKey] ofType:@"app"];
if (relaunchPathToCopy != nil)
{
NSString *targetPath = [[self.host appSupportPath] stringByAppendingPathComponent:[relaunchPathToCopy lastPathComponent]];
@ -394,7 +385,7 @@
if ([updaterDelegate respondsToSelector:@selector(pathToRelaunchForUpdater:)]) {
pathToRelaunch = [updaterDelegate pathToRelaunchForUpdater:self.updater];
}
NSString *relaunchToolPath = [[self.relaunchPath stringByAppendingPathComponent:@"/Contents/MacOS"] stringByAppendingPathComponent:finishInstallToolName];
NSString *relaunchToolPath = [[NSBundle bundleWithPath:self.relaunchPath] executablePath];
[NSTask launchedTaskWithLaunchPath:relaunchToolPath arguments:@[[self.host bundlePath],
pathToRelaunch,
[NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]],

View File

@ -10,7 +10,7 @@
#import "SUBinaryDeltaCommon.h"
#include <CommonCrypto/CommonDigest.h>
#import <Foundation/Foundation.h>
#include <bspatch.h>
#include "bspatch.h"
#include <stdio.h>
#include <stdlib.h>
#include <xar/xar.h>

View File

@ -39,23 +39,28 @@ NSString *pathRelativeToDirectory(NSString *directory, NSString *path)
}
NSString *stringWithFileSystemRepresentation(const char *input) {
NSFileManager *fm = [NSFileManager defaultManager];
return [fm stringWithFileSystemRepresentation:input length:strlen(input)];
return [[NSFileManager defaultManager] stringWithFileSystemRepresentation:input length:strlen(input)];
}
NSString *temporaryFilename(NSString *base)
{
NSString *template = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.XXXXXXXXXX", base]];
const char *fsrepr = [template fileSystemRepresentation];
NSMutableData *data = [NSMutableData data];
[data appendBytes:template.fileSystemRepresentation length:strlen(template.fileSystemRepresentation) + 1];
const size_t buffer_len = strlen(fsrepr) + 1;
char *buffer = (char *)malloc(buffer_len);
strlcpy(buffer, fsrepr, buffer_len);
char *buffer = data.mutableBytes;
int fd = mkstemp(buffer);
if (fd == -1) {
perror("mkstemp");
return nil;
}
// mkstemp() can't be used, beause it returns a file descriptor, and XAR API requires a filename
NSString *ret = stringWithFileSystemRepresentation(mktemp(buffer));
free(buffer);
return ret;
if (close(fd) != 0) {
perror("close");
return nil;
}
return stringWithFileSystemRepresentation(buffer);
}
static void _hashOfBuffer(unsigned char *hash, const char* buffer, ssize_t bufferLength)

View File

@ -114,19 +114,33 @@ static BOOL shouldDeleteThenExtract(NSString * __unused key, NSDictionary* origi
return NO;
}
int main(int argc, char **argv)
int main(int __unused argc, char __unused *argv[])
{
@autoreleasepool {
if (argc != 5) {
NSArray *args = [[NSProcessInfo processInfo] arguments];
if (args.count != 5) {
usage:
fprintf(stderr, "Usage: BinaryDelta [create | apply] before-tree after-tree patch-file\n");
exit(1);
return 1;
}
NSString *command = @(argv[1]);
NSString *oldPath = stringWithFileSystemRepresentation(argv[2]);
NSString *newPath = stringWithFileSystemRepresentation(argv[3]);
NSString *patchFile = stringWithFileSystemRepresentation(argv[4]);
NSString *command = args[1];
NSString *oldPath = args[2];
NSString *newPath = args[3];
NSString *patchFile = args[4];
BOOL isDirectory;
[[NSFileManager defaultManager] fileExistsAtPath:oldPath isDirectory:&isDirectory];
if (!isDirectory) {
fprintf(stderr, "Usage: before-tree must be a directory\n");
return 1;
}
[[NSFileManager defaultManager] fileExistsAtPath:newPath isDirectory:&isDirectory];
if (!isDirectory) {
fprintf(stderr, "Usage: after-tree must be a directory\n");
return 1;
}
if ([command isEqualToString:@"apply"]) {
int result = applyBinaryDelta(oldPath, newPath, patchFile);

View File

@ -95,7 +95,7 @@ static id valueOrNSNull(id value) {
}
NSDictionary *infoPlist = signingDict[@"info-plist"];
relevantInfo[@"version"] = valueOrNSNull(infoPlist[@"CFBundleShortVersionString"]);
relevantInfo[@"build"] = valueOrNSNull(infoPlist[@"CFBundleVersion"]);
relevantInfo[@"build"] = valueOrNSNull(infoPlist[(__bridge NSString *)kCFBundleVersionKey]);
SULog(@"%@: %@", label, relevantInfo);
}
}

View File

@ -11,20 +11,13 @@
#define SUCONSTANTS_H
// -----------------------------------------------------------------------------
// Preprocessor flags:
// Misc:
// -----------------------------------------------------------------------------
// Sparkle usually doesn't allow downgrades as they're usually accidental, but
// if your app has a downgrade function or URL handler, turn this on:
#define PERMIT_AUTOMATED_DOWNGRADES 0
extern const NSTimeInterval SUMinimumUpdateCheckInterval;
extern const NSTimeInterval SUDefaultUpdateCheckInterval;
// If your app file on disk is named "MyApp 1.1b4", Sparkle usually updates it
// in place, giving you an app named 1.1b4 that is actually 1.2. Turn the
// following on to always reset the name back to "MyApp":
#define NORMALIZE_INSTALLED_APP_NAME 0
#define TRY_TO_APPEND_VERSION_NUMBER 1
extern NSString *const SUBundleIdentifier;
// -----------------------------------------------------------------------------
// Notifications:
@ -57,31 +50,62 @@ extern NSString *const SUKeepDownloadOnFailedInstallKey;
extern NSString *const SUDefaultsDomainKey;
extern NSString *const SUFixedHTMLDisplaySizeKey __attribute__((deprecated("This key is obsolete and has no effect.")));
extern NSString *const SUAppendVersionNumberKey;
extern NSString *const SUEnableAutomatedDowngradesKey;
extern NSString *const SUNormalizeInstalledApplicationNameKey;
extern NSString *const SURelaunchToolNameKey;
// -----------------------------------------------------------------------------
// Appcast keys::
// -----------------------------------------------------------------------------
extern NSString *const SUAppcastAttributeDeltaFrom;
extern NSString *const SUAppcastAttributeDSASignature;
extern NSString *const SUAppcastAttributeShortVersionString;
extern NSString *const SUAppcastAttributeVersion;
extern NSString *const SUAppcastElementCriticalUpdate;
extern NSString *const SUAppcastElementDeltas;
extern NSString *const SUAppcastElementMinimumSystemVersion;
extern NSString *const SUAppcastElementMaximumSystemVersion;
extern NSString *const SUAppcastElementReleaseNotesLink;
extern NSString *const SUAppcastElementTags;
extern NSString *const SURSSAttributeURL;
extern NSString *const SURSSElementDescription;
extern NSString *const SURSSElementEnclosure;
extern NSString *const SURSSElementLink;
extern NSString *const SURSSElementPubDate;
extern NSString *const SURSSElementTitle;
// -----------------------------------------------------------------------------
// Errors:
// -----------------------------------------------------------------------------
extern NSString *const SUSparkleErrorDomain;
// Appcast phase errors.
extern OSStatus SUAppcastParseError;
extern OSStatus SUNoUpdateError;
extern OSStatus SUAppcastError;
extern OSStatus SURunningFromDiskImageError;
typedef NS_ENUM(OSStatus, SUError) {
// Appcast phase errors.
SUAppcastParseError = 1000,
SUNoUpdateError = 1001,
SUAppcastError = 1002,
SURunningFromDiskImageError = 1003,
// Downlaod phase errors.
extern OSStatus SUTemporaryDirectoryError;
// Downlaod phase errors.
SUTemporaryDirectoryError = 2000,
// Extraction phase errors.
extern OSStatus SUUnarchivingError;
extern OSStatus SUSignatureError;
// Extraction phase errors.
SUUnarchivingError = 3000,
SUSignatureError = 3001,
// Installation phase errors.
extern OSStatus SUFileCopyFailure;
extern OSStatus SUAuthenticationFailure;
extern OSStatus SUMissingUpdateError;
extern OSStatus SUMissingInstallerToolError;
extern OSStatus SURelaunchError;
extern OSStatus SUInstallationError;
extern OSStatus SUDowngradeError;
// Installation phase errors.
SUFileCopyFailure = 4000,
SUAuthenticationFailure = 4001,
SUMissingUpdateError = 4002,
SUMissingInstallerToolError = 4003,
SURelaunchError = 4004,
SUInstallationError = 4005,
SUDowngradeError = 4006
};
#endif

View File

@ -13,6 +13,16 @@
#import "SUVersionComparisonProtocol.h"
#import "SUConstants.h"
#ifndef DEBUG
#define DEBUG 0
#endif
// Define some minimum intervals to avoid DoS-like checking attacks
const NSTimeInterval SUMinimumUpdateCheckInterval = DEBUG ? 60 : (60 * 60);
const NSTimeInterval SUDefaultUpdateCheckInterval = DEBUG ? 60 : (60 * 60 * 24);
NSString *const SUBundleIdentifier = @SPARKLE_BUNDLE_IDENTIFIER;
NSString *const SUTechnicalErrorInformationKey = @"SUTechnicalErrorInformation";
NSString *const SUHasLaunchedBeforeKey = @"SUHasLaunchedBefore";
@ -35,22 +45,29 @@ NSString *const SUPromptUserOnFirstLaunchKey = @"SUPromptUserOnFirstLaunch";
NSString *const SUFixedHTMLDisplaySizeKey = @"SUFixedHTMLDisplaySize";
NSString *const SUKeepDownloadOnFailedInstallKey = @"SUKeepDownloadOnFailedInstall";
NSString *const SUDefaultsDomainKey = @"SUDefaultsDomain";
NSString *const SUSparkleErrorDomain = @"SUSparkleErrorDomain";
OSStatus SUAppcastParseError = 1000;
OSStatus SUNoUpdateError = 1001;
OSStatus SUAppcastError = 1002;
OSStatus SURunningFromDiskImageError = 1003;
OSStatus SUTemporaryDirectoryError = 2000;
NSString *const SUAppendVersionNumberKey = @"SUAppendVersionNumber";
NSString *const SUEnableAutomatedDowngradesKey = @"SUEnableAutomatedDowngrades";
NSString *const SUNormalizeInstalledApplicationNameKey = @"SUNormalizeInstalledApplicationName";
NSString *const SURelaunchToolNameKey = @"SURelaunchToolName";
OSStatus SUUnarchivingError = 3000;
OSStatus SUSignatureError = 3001;
NSString *const SUAppcastAttributeDeltaFrom = @"sparkle:deltaFrom";
NSString *const SUAppcastAttributeDSASignature = @"sparkle:dsaSignature";
NSString *const SUAppcastAttributeShortVersionString = @"sparkle:shortVersionString";
NSString *const SUAppcastAttributeVersion = @"sparkle:version";
OSStatus SUFileCopyFailure = 4000;
OSStatus SUAuthenticationFailure = 4001;
OSStatus SUMissingUpdateError = 4002;
OSStatus SUMissingInstallerToolError = 4003;
OSStatus SURelaunchError = 4004;
OSStatus SUInstallationError = 4005;
OSStatus SUDowngradeError = 4006;
NSString *const SUAppcastElementCriticalUpdate = @"sparkle:criticalUpdate";
NSString *const SUAppcastElementDeltas = @"sparkle:deltas";
NSString *const SUAppcastElementMinimumSystemVersion = @"sparkle:minimumSystemVersion";
NSString *const SUAppcastElementMaximumSystemVersion = @"sparkle:maximumSystemVersion";
NSString *const SUAppcastElementReleaseNotesLink = @"sparkle:releaseNotesLink";
NSString *const SUAppcastElementTags = @"sparkle:tags";
NSString *const SURSSAttributeURL = @"url";
NSString *const SURSSElementDescription = @"description";
NSString *const SURSSElementEnclosure = @"enclosure";
NSString *const SURSSElementLink = @"link";
NSString *const SURSSElementPubDate = @"pubDate";
NSString *const SURSSElementTitle = @"title";

View File

@ -121,9 +121,12 @@
return cleanup();
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdirect-ivar-access"
dataVerifyTransform = SecVerifyTransformCreate(_secKey, (__bridge CFDataRef)signature, &error);
#pragma clang diagnostic pop
if (!dataVerifyTransform || error) {
SULog(@"Could not understand format of the sugnature: %@; Signature data: %@", error, signature);
SULog(@"Could not understand format of the signature: %@; Signature data: %@", error, signature);
return cleanup();
}

18
Frameworks/Sparkle/Sparkle/SUExport.h vendored Normal file
View File

@ -0,0 +1,18 @@
//
// SUExport.h
// Sparkle
//
// Created by Jake Petroules on 2014-08-23.
// Copyright (c) 2014 Sparkle Project. All rights reserved.
//
#ifndef SUEXPORT_H
#define SUEXPORT_H
#ifdef BUILDING_SPARKLE
#define SU_EXPORT __attribute__((visibility("default")))
#else
#define SU_EXPORT
#endif
#endif

View File

@ -44,7 +44,7 @@ typedef struct {
if (aBundle == nil) aBundle = [NSBundle mainBundle];
self.bundle = aBundle;
if (![self.bundle bundleIdentifier]) {
SULog(@"Error: the bundle being updated at %@ has no CFBundleIdentifier! This will cause preference read/write to not work properly.", self.bundle);
SULog(@"Error: the bundle being updated at %@ has no %@! This will cause preference read/write to not work properly.", self.bundle, kCFBundleIdentifierKey);
}
self.defaultsDomain = [self.bundle objectForInfoDictionaryKey:SUDefaultsDomainKey];
@ -85,13 +85,13 @@ typedef struct {
- (NSString *)installationPath
{
#if NORMALIZE_INSTALLED_APP_NAME
// We'll install to "#{CFBundleName}.app", but only if that path doesn't already exist. If we're "Foo 4.2.app," and there's a "Foo.app" in this directory, we don't want to overwrite it! But if there's no "Foo.app," we'll take that name.
NSString *normalizedAppPath = [[[self.bundle bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", [self.bundle objectForInfoDictionaryKey:@"CFBundleName"], [[self.bundle bundlePath] pathExtension]]];
if (![[NSFileManager defaultManager] fileExistsAtPath:[[[self.bundle bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", [self.bundle objectForInfoDictionaryKey:@"CFBundleName"], [[self.bundle bundlePath] pathExtension]]]]) {
return normalizedAppPath;
if ([[[NSBundle bundleWithIdentifier:SUBundleIdentifier] infoDictionary][SUNormalizeInstalledApplicationNameKey] boolValue]) {
// We'll install to "#{CFBundleName}.app", but only if that path doesn't already exist. If we're "Foo 4.2.app," and there's a "Foo.app" in this directory, we don't want to overwrite it! But if there's no "Foo.app," we'll take that name.
NSString *normalizedAppPath = [[[self.bundle bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", [self.bundle objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleNameKey], [[self.bundle bundlePath] pathExtension]]];
if (![[NSFileManager defaultManager] fileExistsAtPath:[[[self.bundle bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", [self.bundle objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleNameKey], [[self.bundle bundlePath] pathExtension]]]]) {
return normalizedAppPath;
}
}
#endif
return [self.bundle bundlePath];
}
@ -100,7 +100,7 @@ typedef struct {
NSString *name = [self.bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
if (name) return name;
name = [self objectForInfoDictionaryKey:@"CFBundleName"];
name = [self objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleNameKey];
if (name) return name;
return [[[NSFileManager defaultManager] displayNameAtPath:[self.bundle bundlePath]] stringByDeletingPathExtension];
@ -108,9 +108,9 @@ typedef struct {
- (NSString *)version
{
NSString *version = [self.bundle objectForInfoDictionaryKey:@"CFBundleVersion"];
NSString *version = [self.bundle objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleVersionKey];
if (!version || [version isEqualToString:@""])
[NSException raise:@"SUNoVersionException" format:@"This host (%@) has no CFBundleVersion! This attribute is required.", [self bundlePath]];
[NSException raise:@"SUNoVersionException" format:@"This host (%@) has no %@! This attribute is required.", [self bundlePath], (__bridge NSString *)kCFBundleVersionKey];
return version;
}

View File

@ -152,11 +152,6 @@ static NSString *sUpdateFolder = nil;
}
}
#define SUNotifyDictHostKey @"SUNotifyDictHost"
#define SUNotifyDictErrorKey @"SUNotifyDictError"
#define SUNotifyDictDelegateKey @"SUNotifyDictDelegate"
+ (void)finishInstallationToPath:(NSString *)installationPath withResult:(BOOL)result host:(SUHost *)host error:(NSError *)error delegate:(id<SUInstallerDelegate>)delegate
{
if (result)

View File

@ -18,7 +18,7 @@
// Constants:
// -----------------------------------------------------------------------------
#define LOG_FILE_PATH @"~/Library/Logs/SparkleUpdateLog.log"
static NSString *const SULogFilePath = @"~/Library/Logs/SparkleUpdateLog.log";
// -----------------------------------------------------------------------------
@ -38,7 +38,7 @@
void SUClearLog(void)
{
FILE *logfile = fopen([[LOG_FILE_PATH stringByExpandingTildeInPath] fileSystemRepresentation], "w");
FILE *logfile = fopen([[SULogFilePath stringByExpandingTildeInPath] fileSystemRepresentation], "w");
if (logfile) {
fclose(logfile);
}
@ -62,7 +62,7 @@ void SULog(NSString *format, ...)
NSString *theStr = [[NSString alloc] initWithFormat:format arguments:ap];
NSLog(@"Sparkle: %@", theStr);
FILE *logfile = fopen([[LOG_FILE_PATH stringByExpandingTildeInPath] fileSystemRepresentation], "a");
FILE *logfile = fopen([[SULogFilePath stringByExpandingTildeInPath] fileSystemRepresentation], "a");
if (logfile) {
theStr = [NSString stringWithFormat:@"%@: %@\n", [NSDate date], theStr];
NSData *theData = [theStr dataUsingEncoding:NSUTF8StringEncoding];

View File

@ -15,16 +15,16 @@
+ (void)performInstallationToPath:(NSString *)installationPath fromPath:(NSString *)path host:(SUHost *)host delegate:(id<SUInstallerDelegate>)delegate versionComparator:(id<SUVersionComparison>)comparator
{
// Prevent malicious downgrades:
#if !PERMIT_AUTOMATED_DOWNGRADES
if ([comparator compareVersion:[host version] toVersion:[[NSBundle bundleWithPath:path] objectForInfoDictionaryKey:@"CFBundleVersion"]] == NSOrderedDescending)
{
NSString *errorMessage = [NSString stringWithFormat:@"Sparkle Updater: Possible attack in progress! Attempting to \"upgrade\" from %@ to %@. Aborting update.", [host version], [[NSBundle bundleWithPath:path] objectForInfoDictionaryKey:@"CFBundleVersion"]];
NSError *error = [NSError errorWithDomain:SUSparkleErrorDomain code:SUDowngradeError userInfo:@{ NSLocalizedDescriptionKey: errorMessage }];
[self finishInstallationToPath:installationPath withResult:NO host:host error:error delegate:delegate];
return;
// Prevent malicious downgrades
if (![[[NSBundle bundleWithIdentifier:SUBundleIdentifier] infoDictionary][SUEnableAutomatedDowngradesKey] boolValue]) {
if ([comparator compareVersion:[host version] toVersion:[[NSBundle bundleWithPath:path] objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleVersionKey]] == NSOrderedDescending)
{
NSString *errorMessage = [NSString stringWithFormat:@"Sparkle Updater: Possible attack in progress! Attempting to \"upgrade\" from %@ to %@. Aborting update.", [host version], [[NSBundle bundleWithPath:path] objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleVersionKey]];
NSError *error = [NSError errorWithDomain:SUSparkleErrorDomain code:SUDowngradeError userInfo:@{ NSLocalizedDescriptionKey: errorMessage }];
[self finishInstallationToPath:installationPath withResult:NO host:host error:error delegate:delegate];
return;
}
}
#endif
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *error = nil;

View File

@ -90,7 +90,7 @@ static BOOL AuthorizationExecuteWithPrivilegesAndWait(AuthorizationRef authoriza
// Let's try to read the version number so the filename will be more meaningful.
NSString *postFix;
NSString *version;
if ((version = [[NSBundle bundleWithPath:path] objectForInfoDictionaryKey:@"CFBundleVersion"]) && ![version isEqualToString:@""])
if ((version = [[NSBundle bundleWithPath:path] objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleVersionKey]) && ![version isEqualToString:@""])
{
NSMutableCharacterSet *validCharacters = [NSMutableCharacterSet alphanumericCharacterSet];
[validCharacters formUnionWithCharacterSet:[NSCharacterSet characterSetWithCharactersInString:@".-()"]];
@ -138,23 +138,24 @@ static BOOL AuthorizationExecuteWithPrivilegesAndWait(AuthorizationRef authoriza
if (!tempDir)
tempDir = [path stringByDeletingLastPathComponent];
// Let's try to read the version number so the filename will be more meaningful.
#if TRY_TO_APPEND_VERSION_NUMBER
NSString *postFix = nil;
NSString *version = nil;
if ((version = [[NSBundle bundleWithPath: path] objectForInfoDictionaryKey:@"CFBundleVersion"]) && ![version isEqualToString:@""])
{
NSMutableCharacterSet *validCharacters = [NSMutableCharacterSet alphanumericCharacterSet];
[validCharacters formUnionWithCharacterSet:[NSCharacterSet characterSetWithCharactersInString:@".-()"]];
postFix = [version stringByTrimmingCharactersInSet:[validCharacters invertedSet]];
}
else {
postFix = @"old";
// Let's try to read the version number so the filename will be more meaningful
NSString *prefix;
if ([[[NSBundle bundleWithIdentifier:SUBundleIdentifier] infoDictionary][SUAppendVersionNumberKey] boolValue]) {
NSString *postFix = nil;
NSString *version = nil;
if ((version = [[NSBundle bundleWithPath: path] objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleVersionKey]) && ![version isEqualToString:@""])
{
NSMutableCharacterSet *validCharacters = [NSMutableCharacterSet alphanumericCharacterSet];
[validCharacters formUnionWithCharacterSet:[NSCharacterSet characterSetWithCharactersInString:@".-()"]];
postFix = [version stringByTrimmingCharactersInSet:[validCharacters invertedSet]];
}
else {
postFix = @"old";
}
prefix = [NSString stringWithFormat:@"%@ (%@)", [[path lastPathComponent] stringByDeletingPathExtension], postFix];
} else {
prefix = [[path lastPathComponent] stringByDeletingPathExtension];
}
NSString *prefix = [NSString stringWithFormat:@"%@ (%@)", [[path lastPathComponent] stringByDeletingPathExtension], postFix];
#else
NSString *prefix = [[path lastPathComponent] stringByDeletingPathExtension];
#endif
NSString *tempName = [prefix stringByAppendingPathExtension:[path pathExtension]];
tempDir = [tempDir stringByAppendingPathComponent:tempName];

View File

@ -9,7 +9,7 @@
#ifndef SUSTANDARDVERSIONCOMPARATOR_H
#define SUSTANDARDVERSIONCOMPARATOR_H
#import "SUExport.h"
#import "SUVersionComparisonProtocol.h"
/*!
@ -19,7 +19,7 @@
It's "dumb" in that it does essentially string comparison,
in components split by character type.
*/
@interface SUStandardVersionComparator : NSObject <SUVersionComparison>
SU_EXPORT @interface SUStandardVersionComparator : NSObject <SUVersionComparison>
/*!
Returns a singleton instance of the comparator.

View File

@ -12,6 +12,18 @@
#import "SUHost.h"
#include <sys/sysctl.h>
static NSString *const SUSystemProfilerApplicationNameKey = @"appName";
static NSString *const SUSystemProfilerApplicationVersionKey = @"appVersion";
static NSString *const SUSystemProfilerCPU64bitKey = @"cpu64bit";
static NSString *const SUSystemProfilerCPUCountKey = @"ncpu";
static NSString *const SUSystemProfilerCPUFrequencyKey = @"cpuFreqMHz";
static NSString *const SUSystemProfilerCPUTypeKey = @"cputype";
static NSString *const SUSystemProfilerCPUSubtypeKey = @"cpusubtype";
static NSString *const SUSystemProfilerHardwareModelKey = @"model";
static NSString *const SUSystemProfilerMemoryKey = @"ramMB";
static NSString *const SUSystemProfilerOperatingSystemVersionKey = @"osVersion";
static NSString *const SUSystemProfilerPreferredLanguageKey = @"lang";
@implementation SUSystemProfiler
+ (SUSystemProfiler *)sharedSystemProfiler
{
@ -42,7 +54,7 @@
// OS version
NSString *currentSystemVersion = [SUHost systemVersionString];
if (currentSystemVersion != nil) {
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"osVersion", @"OS Version", currentSystemVersion, currentSystemVersion] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerOperatingSystemVersionKey, @"OS Version", currentSystemVersion, currentSystemVersion] forKeys:profileDictKeys]];
}
// CPU type (decoder info for values found here is in mach/machine.h)
@ -52,11 +64,12 @@
cpuType = value;
NSString *visibleCPUType;
switch (value) {
case CPU_TYPE_ARM: visibleCPUType = @"ARM"; break;
case CPU_TYPE_X86: visibleCPUType = @"Intel"; break;
case CPU_TYPE_POWERPC: visibleCPUType = @"PowerPC"; break;
default: visibleCPUType = @"Unknown"; break;
}
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"cputype", @"CPU Type", @(value), visibleCPUType] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerCPUTypeKey, @"CPU Type", @(value), visibleCPUType] forKeys:profileDictKeys]];
}
error = sysctlbyname("hw.cpu64bit_capable", &value, &length, NULL, 0);
if (error != 0) {
@ -70,7 +83,7 @@
if (error == 0) {
is64bit = value == 1;
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"cpu64bit", @"CPU is 64-Bit?", @(is64bit), is64bit ? @"Yes" : @"No"] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerCPU64bitKey, @"CPU is 64-Bit?", @(is64bit), is64bit ? @"Yes" : @"No"] forKeys:profileDictKeys]];
}
error = sysctlbyname("hw.cpusubtype", &value, &length, NULL, 0);
if (error == 0) {
@ -90,7 +103,7 @@
} else {
visibleCPUSubType = @"Other";
}
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"cpusubtype", @"CPU Subtype", @(value), visibleCPUSubType] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerCPUSubtypeKey, @"CPU Subtype", @(value), visibleCPUSubType] forKeys:profileDictKeys]];
}
error = sysctlbyname("hw.model", NULL, &length, NULL, 0);
if (error == 0) {
@ -103,7 +116,7 @@
if (visibleModelName == nil) {
visibleModelName = rawModelName;
}
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"model", @"Mac Model", rawModelName, visibleModelName] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerHardwareModelKey, @"Mac Model", rawModelName, visibleModelName] forKeys:profileDictKeys]];
}
free(cpuModel);
}
@ -112,24 +125,24 @@
// Number of CPUs
error = sysctlbyname("hw.ncpu", &value, &length, NULL, 0);
if (error == 0) {
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"ncpu", @"Number of CPUs", @(value), @(value)] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerCPUCountKey, @"Number of CPUs", @(value), @(value)] forKeys:profileDictKeys]];
}
// User preferred language
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
NSArray *languages = [defs objectForKey:@"AppleLanguages"];
if ([languages count] > 0) {
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"lang", @"Preferred Language", languages[0], languages[0]] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerPreferredLanguageKey, @"Preferred Language", languages[0], languages[0]] forKeys:profileDictKeys]];
}
// Application sending the request
NSString *appName = [host name];
if (appName) {
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"appName", @"Application Name", appName, appName] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerApplicationNameKey, @"Application Name", appName, appName] forKeys:profileDictKeys]];
}
NSString *appVersion = [host version];
if (appVersion) {
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"appVersion", @"Application Version", appVersion, appVersion] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerApplicationVersionKey, @"Application Version", appVersion, appVersion] forKeys:profileDictKeys]];
}
// Number of displays?
@ -139,7 +152,7 @@
size_t hz_size = sizeof(unsigned long);
if (sysctlbyname("hw.cpufrequency", &hz, &hz_size, NULL, 0) == 0) {
unsigned long mhz = hz / 1000000;
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"cpuFreqMHz", @"CPU Speed (GHz)", @(mhz), @(mhz / 1000.)] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerCPUFrequencyKey, @"CPU Speed (MHz)", @(mhz), @(mhz / 1000.)] forKeys:profileDictKeys]];
}
// amount of RAM
@ -147,7 +160,7 @@
size_t bytes_size = sizeof(unsigned long);
if (sysctlbyname("hw.memsize", &bytes, &bytes_size, NULL, 0) == 0) {
double megabytes = bytes / (1024. * 1024.);
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[@"ramMB", @"Memory (MB)", @(megabytes), @(megabytes)] forKeys:profileDictKeys]];
[profileArray addObject:[NSDictionary dictionaryWithObjects:@[SUSystemProfilerMemoryKey, @"Memory (MB)", @(megabytes), @(megabytes)] forKeys:profileDictKeys]];
}
return profileArray;

View File

@ -75,7 +75,7 @@
- (void)applicationDidBecomeActive:(NSNotification *)__unused aNotification
{
[[self.updateAlert window] makeKeyAndOrderFront:self];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"NSApplicationDidBecomeActiveNotification" object:NSApp];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidBecomeActiveNotification object:NSApp];
}
- (void)updateAlert:(SUUpdateAlert *)__unused alert finishedWithChoice:(SUUpdateAlertChoice)choice

View File

@ -106,7 +106,7 @@
- (void)displayReleaseNotes
{
// Set the default font
[self.releaseNotesView setPreferencesIdentifier:[SPARKLE_BUNDLE bundleIdentifier]];
[self.releaseNotesView setPreferencesIdentifier:SUBundleIdentifier];
WebPreferences *prefs = [self.releaseNotesView preferences];
NSString *familyName = [[NSFont systemFontOfSize:8] familyName];
if ([familyName hasPrefix:@"."]) { // 10.9 returns ".Lucida Grande UI", which isn't a valid name for the WebView

View File

@ -9,6 +9,7 @@
#ifndef SUUPDATER_H
#define SUUPDATER_H
#import "SUExport.h"
#import "SUVersionComparisonProtocol.h"
#import "SUVersionDisplayProtocol.h"
@ -22,7 +23,7 @@
This class is used to configure the update paramters as well as manually
and automatically schedule and control checks for updates.
*/
@interface SUUpdater : NSObject
SU_EXPORT @interface SUUpdater : NSObject
@property (weak) IBOutlet id<SUUpdaterDelegate> delegate;
@ -107,17 +108,17 @@
// SUUpdater Notifications for events that might be interesting to more than just the delegate
// The updater will be the notification object
// -----------------------------------------------------------------------------
extern NSString *const SUUpdaterDidFinishLoadingAppCastNotification;
extern NSString *const SUUpdaterDidFindValidUpdateNotification;
extern NSString *const SUUpdaterDidNotFindUpdateNotification;
extern NSString *const SUUpdaterWillRestartNotification;
SU_EXPORT extern NSString *const SUUpdaterDidFinishLoadingAppCastNotification;
SU_EXPORT extern NSString *const SUUpdaterDidFindValidUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterDidNotFindUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterWillRestartNotification;
#define SUUpdaterWillRelaunchApplicationNotification SUUpdaterWillRestartNotification;
#define SUUpdaterWillInstallUpdateNotification SUUpdaterWillRestartNotification;
// Key for the SUAppcastItem object in the SUUpdaterDidFindValidUpdateNotification userInfo
extern NSString *const SUUpdaterAppcastItemNotificationKey;
SU_EXPORT extern NSString *const SUUpdaterAppcastItemNotificationKey;
// Key for the SUAppcast object in the SUUpdaterDidFinishLoadingAppCastNotification userInfo
extern NSString *const SUUpdaterAppcastNotificationKey;
SU_EXPORT extern NSString *const SUUpdaterAppcastNotificationKey;
// -----------------------------------------------------------------------------
// SUUpdater Delegate:
@ -313,22 +314,4 @@ extern NSString *const SUUpdaterAppcastNotificationKey;
@end
// -----------------------------------------------------------------------------
// Constants:
// -----------------------------------------------------------------------------
// Define some minimum intervals to avoid DOS-like checking attacks. These are in seconds.
#if defined(DEBUG) && DEBUG && 0
#define SU_MIN_CHECK_INTERVAL 60
#else
#define SU_MIN_CHECK_INTERVAL 60 * 60
#endif
#if defined(DEBUG) && DEBUG && 0
#define SU_DEFAULT_CHECK_INTERVAL 60
#else
#define SU_DEFAULT_CHECK_INTERVAL 60 * 60 * 24
#endif
#endif

View File

@ -231,8 +231,8 @@ static NSString *const SUUpdaterDefaultsObservationContext = @"SUUpdaterDefaults
// Now we want to figure out how long until we check again.
NSTimeInterval delayUntilCheck, updateCheckInterval = [self updateCheckInterval];
if (updateCheckInterval < SU_MIN_CHECK_INTERVAL)
updateCheckInterval = SU_MIN_CHECK_INTERVAL;
if (updateCheckInterval < SUMinimumUpdateCheckInterval)
updateCheckInterval = SUMinimumUpdateCheckInterval;
if (intervalSinceCheck < updateCheckInterval)
delayUntilCheck = (updateCheckInterval - intervalSinceCheck); // It hasn't been long enough.
else
@ -411,7 +411,7 @@ static NSString *const SUUpdaterDefaultsObservationContext = @"SUUpdaterDefaults
// Hack to support backwards compatibility with older Sparkle versions, which supported
// disabling updates by setting the check interval to 0.
if (automaticallyCheckForUpdates && (NSInteger)[self updateCheckInterval] == 0) {
[self setUpdateCheckInterval:SU_DEFAULT_CHECK_INTERVAL];
[self setUpdateCheckInterval:SUDefaultUpdateCheckInterval];
}
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil];
// Provide a small delay in case multiple preferences are being updated simultaneously.
@ -476,7 +476,7 @@ static NSString *const SUUpdaterDefaultsObservationContext = @"SUUpdaterDefaults
return customUserAgentString;
}
NSString *version = [SPARKLE_BUNDLE objectForInfoDictionaryKey:@"CFBundleVersion"];
NSString *version = [[NSBundle bundleWithIdentifier:SUBundleIdentifier] objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleVersionKey];
NSString *userAgent = [NSString stringWithFormat:@"%@/%@ Sparkle/%@", [self.host name], [self.host displayVersion], version ? version : @"?"];
NSData *cleanedAgent = [userAgent dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
return [[NSString alloc] initWithData:cleanedAgent encoding:NSASCIIStringEncoding];
@ -553,7 +553,7 @@ static NSString *const SUUpdaterDefaultsObservationContext = @"SUUpdaterDefaults
if (intervalValue)
return [intervalValue doubleValue];
else
return SU_DEFAULT_CHECK_INTERVAL;
return SUDefaultUpdateCheckInterval;
}
- (void)dealloc

View File

@ -10,6 +10,7 @@
#define SUVERSIONCOMPARISONPROTOCOL_H
#import <Cocoa/Cocoa.h>
#import "SUExport.h"
/*!
Provides version comparison facilities for Sparkle.

View File

@ -7,7 +7,7 @@
//
#import <Cocoa/Cocoa.h>
#import "SUExport.h"
/*!
Applies special display formatting to version numbers.

View File

@ -9,7 +9,7 @@
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>org.andymatuschak.Sparkle</string>
<string>${SPARKLE_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@ -17,12 +17,20 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>${CURRENT_PROJECT_VERSION} git</string>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
<key>SUAppendVersionNumber</key>
<string>${SPARKLE_APPEND_VERSION_NUMBER}</string>
<key>SUEnableAutomatedDowngrades</key>
<string>${SPARKLE_AUTOMATED_DOWNGRADES}</string>
<key>SUNormalizeInstalledApplicationName</key>
<string>${SPARKLE_NORMALIZE_INSTALLED_APPLICATION_NAME}</string>
<key>SURelaunchToolName</key>
<string>${SPARKLE_RELAUNCH_TOOL_NAME}</string>
</dict>
</plist>

View File

@ -12,11 +12,11 @@
// This list should include the shared headers. It doesn't matter if some of them aren't shared (unless
// there are name-space collisions) so we can list all of them to start with:
#import <Sparkle/SUUpdater.h>
#import <Sparkle/SUAppcast.h>
#import <Sparkle/SUAppcastItem.h>
#import <Sparkle/SUVersionComparisonProtocol.h>
#import <Sparkle/SUStandardVersionComparator.h>
#import <Sparkle/SUUpdater.h>
#import <Sparkle/SUVersionComparisonProtocol.h>
#import <Sparkle/SUVersionDisplayProtocol.h>
#endif

View File

@ -8,11 +8,9 @@
#ifdef __OBJC__
#define SPARKLE_BUNDLE [NSBundle bundleWithIdentifier:@"org.andymatuschak.Sparkle"]
#define SULocalizedString(key,comment) NSLocalizedStringFromTableInBundle(key, @"Sparkle", SPARKLE_BUNDLE, comment)
#define SUAbstractFail() NSAssert2(nil, @"Can't call %@ on an instance of %@; this is an abstract method!", __PRETTY_FUNCTION__, [self class]);
#import <Cocoa/Cocoa.h>
#import "SUConstants.h"
#define SULocalizedString(key, comment) NSLocalizedStringFromTableInBundle(key, @"Sparkle", [NSBundle bundleWithIdentifier:SUBundleIdentifier] ? [NSBundle bundleWithIdentifier:SUBundleIdentifier] : [NSBundle mainBundle], comment)
#endif

View File

@ -0,0 +1,28 @@
//
// SUBinaryDeltaTest.m
// Sparkle
//
// Created by Jake Petroules on 2014-08-22.
// Copyright (c) 2014 Sparkle Project. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <XCTest/XCTest.h>
#import "SUBinaryDeltaCommon.h"
@interface SUBinaryDeltaTest : XCTestCase
@end
@implementation SUBinaryDeltaTest
- (void)testTemporaryFilename
{
NSString *tmp1 = temporaryFilename(@"Sparkle");
NSString *tmp2 = temporaryFilename(@"Sparkle");
NSLog(@"Temporary filenames: %@, %@", tmp1, tmp2);
XCTAssertNotEqualObjects(tmp1, tmp2);
XCTAssert(YES, @"Pass");
}
@end

View File

@ -11,19 +11,18 @@
#import "SUDSAVerifier.h"
@interface SUDSAVerifierTest : XCTestCase
@property NSString *testDir, *testFile, *pubKeyFile;
@property NSString *testFile, *pubKeyFile;
@end
@implementation SUDSAVerifierTest
@synthesize testDir, testFile, pubKeyFile;
@synthesize testFile, pubKeyFile;
- (void)setUp
{
[super setUp];
self.testDir = [@"" __FILE__ stringByDeletingLastPathComponent];
self.testFile = [self.testDir stringByAppendingPathComponent:@"/signed_test_file"];
self.pubKeyFile = [self.testDir stringByAppendingPathComponent:@"test_pubkey"];
self.testFile = [[NSBundle bundleForClass:[self class]] pathForResource:@"signed-test-file" ofType:@"txt"];
self.pubKeyFile = [[NSBundle bundleForClass:[self class]] pathForResource:@"test-pubkey" ofType:@"pem"];
}
- (void)testVerifyFileAtPath

View File

@ -28,7 +28,7 @@
__FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:06 cperciva Exp $");
#endif
#include <bspatch.h>
#include "bspatch.h"
#include <bzlib.h>
#include <stdlib.h>
#include <stdio.h>