├── .clang-format ├── .gitignore ├── .travis.yml ├── Autoupdate ├── AgentConnection.h ├── AgentConnection.m ├── AppInstaller.h ├── AppInstaller.m ├── SPUInstallationInfo.h ├── SPUInstallationInfo.m ├── SPUInstallationInputData.h ├── SPUInstallationInputData.m ├── SPUMessageTypes.h ├── SPUMessageTypes.m ├── SUBinaryDeltaApply.h ├── SUBinaryDeltaApply.m ├── SUBinaryDeltaCommon.h ├── SUBinaryDeltaCommon.m ├── SUBinaryDeltaCreate.h ├── SUBinaryDeltaCreate.m ├── SUBinaryDeltaTool.m ├── SUBinaryDeltaUnarchiver.h ├── SUBinaryDeltaUnarchiver.m ├── SUCodeSigningVerifier.h ├── SUCodeSigningVerifier.m ├── SUDSAVerifier.h ├── SUDSAVerifier.m ├── SUDiskImageUnarchiver.h ├── SUDiskImageUnarchiver.m ├── SUGuidedPackageInstaller.h ├── SUGuidedPackageInstaller.m ├── SUInstaller.h ├── SUInstaller.m ├── SUInstallerProtocol.h ├── SUPackageInstaller.h ├── SUPackageInstaller.m ├── SUPipedUnarchiver.h ├── SUPipedUnarchiver.m ├── SUPlainInstaller.h ├── SUPlainInstaller.m ├── SUStatusInfoProtocol.h ├── SUUnarchiver.h ├── SUUnarchiver.m ├── SUUnarchiverNotifier.h ├── SUUnarchiverNotifier.m ├── SUUnarchiverProtocol.h ├── StatusInfo.h ├── StatusInfo.m ├── TerminationListener.h ├── TerminationListener.m └── main.m ├── CHANGELOG ├── CODE_OF_CONDUCT.md ├── Configurations ├── ConfigBinaryDelta.xcconfig ├── ConfigCommon.xcconfig ├── ConfigCommonCoverage.xcconfig ├── ConfigCommonDebug.xcconfig ├── ConfigCommonRelease.xcconfig ├── ConfigDownloader.xcconfig ├── ConfigDownloaderDebug.xcconfig ├── ConfigFramework.xcconfig ├── ConfigFrameworkDebug.xcconfig ├── ConfigGenerateAppcast.xcconfig ├── ConfigGenerateAppcastDebug.xcconfig ├── ConfigGenerateAppcastRelease.xcconfig ├── ConfigInstallerConnection.xcconfig ├── ConfigInstallerConnectionDebug.xcconfig ├── ConfigInstallerLauncher.xcconfig ├── ConfigInstallerLauncherDebug.xcconfig ├── ConfigInstallerProgress.xcconfig ├── ConfigInstallerStatus.xcconfig ├── ConfigInstallerStatusDebug.xcconfig ├── ConfigRelaunch.xcconfig ├── ConfigSparkleTool.xcconfig ├── ConfigSwift.xcconfig ├── ConfigSwiftDebug.xcconfig ├── ConfigSwiftRelease.xcconfig ├── ConfigTestApp.xcconfig ├── ConfigTestAppDebug.xcconfig ├── ConfigTestAppHelper.xcconfig ├── ConfigTestAppHelperDebug.xcconfig ├── ConfigUITest.xcconfig ├── ConfigUITestCoverage.xcconfig ├── ConfigUITestDebug.xcconfig ├── ConfigUITestRelease.xcconfig ├── ConfigUnitTest.xcconfig ├── ConfigUnitTestCoverage.xcconfig ├── ConfigUnitTestDebug.xcconfig ├── ConfigUnitTestRelease.xcconfig ├── make-release-package.sh ├── set-agent-signing.sh ├── set-ats-exceptions-downloader-service.sh ├── set-ats-exceptions-test-app.sh └── set-git-version-info.sh ├── Documentation ├── .gitignore ├── Design Practices.md ├── Doxyfile ├── Installation.md ├── Security.md ├── build-docs.sh └── graph-of-sparkle.png ├── Downloader ├── Info.plist ├── SPUDownloader.h ├── SPUDownloader.m ├── SPUDownloaderDelegate.h ├── SPUDownloaderProtocol.h ├── main.m └── org.sparkle-project.Downloader.entitlements ├── INSTALL ├── InstallerConnection ├── Info.plist ├── SUInstallerCommunicationProtocol.h ├── SUInstallerConnection.h ├── SUInstallerConnection.m ├── SUInstallerConnectionProtocol.h ├── SUXPCInstallerConnection.h ├── SUXPCInstallerConnection.m └── main.m ├── InstallerLauncher ├── Info.plist ├── SUInstallerLauncher.h ├── SUInstallerLauncher.m ├── SUInstallerLauncherProtocol.h ├── SUInstallerLauncherStatus.h └── main.m ├── InstallerStatus ├── Info.plist ├── SUInstallerStatus.h ├── SUInstallerStatus.m ├── SUInstallerStatusProtocol.h ├── SUXPCInstallerStatus.h ├── SUXPCInstallerStatus.m └── main.m ├── LICENSE ├── Makefile ├── README.markdown ├── Resources ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon_128x128.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_16x16.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_32x32.png │ │ ├── icon_32x32@2x.png │ │ ├── icon_512x512.png │ │ └── icon_512x512@2x.png ├── SUModelTranslation.plist ├── SampleAppcast.xml ├── Screenshot.png ├── Screenshot2.png ├── Screenshot3.png └── Sparkle-Icon.sketch ├── Sparkle.podspec ├── Sparkle.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── Distribution.xcscheme │ ├── Sparkle.xcscheme │ └── UITests.xcscheme ├── Sparkle ├── AppKitPrevention.h ├── Autoupdate │ ├── TerminationListener.h │ └── TerminationListener.m ├── CheckLocalizations.swift ├── InstallerProgress │ ├── InstallerProgress-Info.plist │ ├── InstallerProgressAppController.h │ ├── InstallerProgressAppController.m │ ├── InstallerProgressDelegate.h │ ├── SPUInstallerAgentProtocol.h │ ├── SUInstallerAgentInitiationProtocol.h │ ├── ShowInstallerProgress.h │ ├── ShowInstallerProgress.m │ └── main.m ├── SPUAutomaticUpdateDriver.h ├── SPUAutomaticUpdateDriver.m ├── SPUBasicUpdateDriver.h ├── SPUBasicUpdateDriver.m ├── SPUCoreBasedUpdateDriver.h ├── SPUCoreBasedUpdateDriver.m ├── SPUDownloadData.h ├── SPUDownloadData.m ├── SPUDownloadDriver.h ├── SPUDownloadDriver.m ├── SPUDownloadedUpdate.h ├── SPUDownloadedUpdate.m ├── SPUInformationalUpdate.h ├── SPUInformationalUpdate.m ├── SPUInstallationType.h ├── SPUInstallerDriver.h ├── SPUInstallerDriver.m ├── SPULocalCacheDirectory.h ├── SPULocalCacheDirectory.m ├── SPUProbeInstallStatus.h ├── SPUProbeInstallStatus.m ├── SPUProbingUpdateDriver.h ├── SPUProbingUpdateDriver.m ├── SPUResumableUpdate.h ├── SPUScheduledUpdateDriver.h ├── SPUScheduledUpdateDriver.m ├── SPUSecureCoding.h ├── SPUSecureCoding.m ├── SPUStandardUpdaterController.h ├── SPUStandardUpdaterController.m ├── SPUStandardUserDriver.h ├── SPUStandardUserDriver.m ├── SPUStandardUserDriverDelegate.h ├── SPUStandardUserDriverProtocol.h ├── SPUStatusCompletionResults.h ├── SPUSystemAuthorization.h ├── SPUSystemAuthorization.m ├── SPUUIBasedUpdateDriver.h ├── SPUUIBasedUpdateDriver.m ├── SPUURLDownload.h ├── SPUURLDownload.m ├── SPUURLRequest.h ├── SPUURLRequest.m ├── SPUUpdateDriver.h ├── SPUUpdatePermissionRequest.h ├── SPUUpdatePermissionRequest.m ├── SPUUpdater.h ├── SPUUpdater.m ├── SPUUpdaterCycle.h ├── SPUUpdaterCycle.m ├── SPUUpdaterDelegate.h ├── SPUUpdaterSettings.h ├── SPUUpdaterSettings.m ├── SPUUpdaterTimer.h ├── SPUUpdaterTimer.m ├── SPUUserDriver.h ├── SPUUserDriverCoreComponent.h ├── SPUUserDriverCoreComponent.m ├── SPUUserInitiatedUpdateDriver.h ├── SPUUserInitiatedUpdateDriver.m ├── SPUXPCServiceInfo.h ├── SPUXPCServiceInfo.m ├── SUAppcast.h ├── SUAppcast.m ├── SUAppcastDriver.h ├── SUAppcastDriver.m ├── SUAppcastItem.h ├── SUAppcastItem.m ├── SUApplicationInfo.h ├── SUApplicationInfo.m ├── SUBundleIcon.h ├── SUBundleIcon.m ├── SUConstants.h ├── SUConstants.m ├── SUErrors.h ├── SUExport.h ├── SUFileManager.h ├── SUFileManager.m ├── SUHost.h ├── SUHost.m ├── SUInstallerProtocol.h ├── SULocalizations.h ├── SULog.h ├── SULog.m ├── SUOperatingSystem.h ├── SUOperatingSystem.m ├── SUStandardVersionComparator.h ├── SUStandardVersionComparator.m ├── SUStatus.xib ├── SUStatusController.h ├── SUStatusController.m ├── SUSystemProfiler.h ├── SUSystemProfiler.m ├── SUSystemUpdateInfo.h ├── SUSystemUpdateInfo.m ├── SUTouchBarButtonGroup.h ├── SUTouchBarButtonGroup.m ├── SUTouchBarForwardDeclarations.h ├── SUUpdateAlert.h ├── SUUpdateAlert.m ├── SUUpdatePermissionPrompt.h ├── SUUpdatePermissionPrompt.m ├── SUUpdatePermissionResponse.h ├── SUUpdatePermissionResponse.m ├── SUUpdateValidator.h ├── SUUpdateValidator.m ├── SUUpdater.h ├── SUUpdater.m ├── SUUpdaterDelegate.h ├── SUVersionComparisonProtocol.h ├── SUVersionDisplayProtocol.h ├── Sparkle-Info.plist ├── Sparkle.h ├── SparkleCore.h ├── ar.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── ca.lproj │ ├── SUUpdateAlert.strings │ └── Sparkle.strings ├── cs.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── da.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── de.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── el.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── en.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── es.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── fi.lproj │ ├── SUUpdateAlert.strings │ └── Sparkle.strings ├── fr.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── he.lproj │ ├── SUUpdateAlert.strings │ └── Sparkle.strings ├── is.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── it.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── ja.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── ko.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── nb.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── nl.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── no.lproj │ ├── SUUpdateAlert.strings │ └── Sparkle.strings ├── pl.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── pt_BR.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── pt_PT.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── ro.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── ru.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── sk.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── sl.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── sv.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── th.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── tr.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── uk.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── zh_CN.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings └── zh_TW.lproj │ ├── SUUpdateAlert.xib │ ├── SUUpdatePermissionPrompt.xib │ └── Sparkle.strings ├── TestAppHelper ├── Info.plist ├── TestAppHelper.h ├── TestAppHelper.m ├── TestAppHelperProtocol.h └── main.m ├── TestApplication ├── English.lproj │ ├── InfoPlist.strings │ └── MainMenu.xib ├── SUAdHocCodeSigning.h ├── SUAdHocCodeSigning.m ├── SUInstallUpdateViewController.h ├── SUInstallUpdateViewController.m ├── SUInstallUpdateViewController.xib ├── SUPopUpTitlebarUserDriver.h ├── SUPopUpTitlebarUserDriver.m ├── SUTestApplicationDelegate.h ├── SUTestApplicationDelegate.m ├── SUTestWebServer.h ├── SUTestWebServer.m ├── SUUpdateSettingsWindowController.h ├── SUUpdateSettingsWindowController.m ├── SUUpdateSettingsWindowController.xib ├── Sparkle-Test-App.entitlements ├── TestApplication-Info.plist ├── ar.lproj │ └── InfoPlist.strings ├── ca.lproj │ └── InfoPlist.strings ├── cs.lproj │ └── InfoPlist.strings ├── cy.lproj │ └── InfoPlist.strings ├── da.lproj │ └── InfoPlist.strings ├── de.lproj │ └── InfoPlist.strings ├── el.lproj │ └── InfoPlist.strings ├── es.lproj │ └── InfoPlist.strings ├── fi.lproj │ └── InfoPlist.strings ├── fr-CA.lproj │ └── InfoPlist.strings ├── fr.lproj │ └── InfoPlist.strings ├── he.lproj │ └── InfoPlist.strings ├── hu.lproj │ └── InfoPlist.strings ├── id.lproj │ └── InfoPlist.strings ├── is.lproj │ └── InfoPlist.strings ├── it.lproj │ └── InfoPlist.strings ├── ja.lproj │ └── InfoPlist.strings ├── ko.lproj │ └── InfoPlist.strings ├── main.m ├── nb.lproj │ └── InfoPlist.strings ├── nl.lproj │ └── InfoPlist.strings ├── pl.lproj │ └── InfoPlist.strings ├── pt-BR.lproj │ └── InfoPlist.strings ├── pt-PT.lproj │ └── InfoPlist.strings ├── pt.lproj │ └── InfoPlist.strings ├── ro.lproj │ └── InfoPlist.strings ├── ru.lproj │ └── InfoPlist.strings ├── sk.lproj │ └── InfoPlist.strings ├── sl.lproj │ └── InfoPlist.strings ├── sparkletestcast.xml ├── sv.lproj │ └── InfoPlist.strings ├── test_app_only_dsa_priv_dont_ever_do_this_for_real.pem ├── test_app_only_dsa_pub.pem ├── th.lproj │ └── InfoPlist.strings ├── tr.lproj │ └── InfoPlist.strings ├── uk.lproj │ └── InfoPlist.strings ├── zh-Hans.lproj │ └── InfoPlist.strings └── zh-Hant.lproj │ └── InfoPlist.strings ├── Tests ├── Resources │ ├── SparkleTestCodeSignApp.dmg │ ├── SparkleTestCodeSignApp.enc.dmg │ ├── SparkleTestCodeSignApp.tar │ ├── SparkleTestCodeSignApp.tar.bz2 │ ├── SparkleTestCodeSignApp.tar.gz │ ├── SparkleTestCodeSignApp.tar.xz │ ├── SparkleTestCodeSignApp.zip │ ├── signed-test-file.txt │ ├── test-pubkey.pem │ ├── test.pkg │ ├── testappcast.xml │ └── testnamespaces.xml ├── SUAppcastTest.swift ├── SUBinaryDeltaTest.m ├── SUCodeSigningVerifierTest.m ├── SUDSAVerifierTest.m ├── SUFileManagerTest.swift ├── SUInstallerTest.m ├── SUSpotlightImporterTest.swift ├── SUUnarchiverTest.swift ├── SUUpdaterTest.m ├── SUVersionComparisonTest.m ├── Sparkle Unit Tests-Bridging-Header.h └── SparkleTests-Info.plist ├── UITests ├── SUTestApplicationTest.swift └── UITests-Info.plist ├── Vendor └── bsdiff │ ├── bscommon.c │ ├── bscommon.h │ ├── bsdiff.c │ ├── bspatch.c │ ├── bspatch.h │ ├── sais.c │ └── sais.h ├── bin ├── codesign_xpc ├── generate_keys └── sign_update ├── generate_appcast ├── Appcast-Bridging-Header.h ├── Appcast.swift ├── ArchiveItem.swift ├── DSASignature.swift ├── FeedXML.swift ├── Unarchive.swift └── main.swift └── sparkle-cli ├── Info.plist ├── SPUCommandLineDriver.h ├── SPUCommandLineDriver.m ├── SPUCommandLineUserDriver.h ├── SPUCommandLineUserDriver.m └── main.m /.clang-format: -------------------------------------------------------------------------------- 1 | AccessModifierOffset: -4 2 | AlignEscapedNewlinesLeft: true 3 | AlignTrailingComments: false 4 | AllowAllParametersOfDeclarationOnNextLine: false 5 | AllowShortBlocksOnASingleLine: false 6 | AllowShortFunctionsOnASingleLine: None 7 | AllowShortIfStatementsOnASingleLine: false 8 | AllowShortLoopsOnASingleLine: false 9 | AlwaysBreakBeforeMultilineStrings: false 10 | AlwaysBreakTemplateDeclarations: false 11 | BinPackParameters: true 12 | BreakBeforeBinaryOperators: true 13 | BreakBeforeBraces: Linux 14 | BreakBeforeTernaryOperators: true 15 | BreakConstructorInitializersBeforeComma: false 16 | ColumnLimit: 0 17 | CommentPragmas: '^ IWYU pragma:' 18 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 19 | ConstructorInitializerIndentWidth: 4 20 | ContinuationIndentWidth: 4 21 | Cpp11BracedListStyle: false 22 | #DerivePointerAlignment: false 23 | DisableFormat: false 24 | #ForEachMacros: foreach,Q_FOREACH 25 | IndentCaseLabels: true 26 | IndentFunctionDeclarationAfterType: true 27 | IndentWidth: 4 28 | KeepEmptyLinesAtTheStartOfBlocks: false 29 | Language: Cpp 30 | MaxEmptyLinesToKeep: 1 31 | NamespaceIndentation: All 32 | ObjCSpaceAfterProperty: true 33 | ObjCSpaceBeforeProtocolList: true 34 | #PointerAlignment: Right 35 | SpaceBeforeAssignmentOperators: true 36 | SpaceBeforeParens: ControlStatements 37 | SpaceInEmptyParentheses: false 38 | SpacesBeforeTrailingComments: 1 39 | SpacesInAngles: false 40 | SpacesInCStyleCastParentheses: false 41 | SpacesInContainerLiterals: false 42 | SpacesInParentheses: false 43 | Standard: Cpp03 44 | TabWidth: 4 45 | UseTab: Never 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.pbxuser 3 | !default.pbxuser 4 | *.mode1v3 5 | !default.mode1v3 6 | *.mode2v3 7 | !default.mode2v3 8 | *.perspectivev3 9 | !default.perspectivev3 10 | xcuserdata 11 | *.xccheckout 12 | *.moved-aside 13 | DerivedData 14 | *.xcuserstate 15 | 16 | .DS_Store 17 | .AppleDouble 18 | .LSOverride 19 | 20 | # Icon must end with two \r 21 | Icon 22 | 23 | 24 | # Thumbnails 25 | ._* 26 | 27 | # Files that might appear on external disk 28 | .Spotlight-V100 29 | .Trashes 30 | 31 | # With Carthage, if Sparkle is included as a Git submodule (e.g. with the 32 | # --use-submodules option), the main module's .gitignore can't reach all the 33 | # way inside the submodule to ignore the added Carthage/Build symlink, and Git 34 | # keeps complaining about untracked changes in the submodule forever, which 35 | # is very annoying. To avoid that issue, ignore here in Sparkle instead. 36 | Carthage/Build 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode8.2 3 | before_install: 4 | - brew update 5 | script: make ci 6 | -------------------------------------------------------------------------------- /Autoupdate/AgentConnection.h: -------------------------------------------------------------------------------- 1 | // 2 | // AgentConnection.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/17/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol AgentConnectionDelegate 14 | 15 | - (void)agentConnectionDidInitiate; 16 | - (void)agentConnectionDidInvalidate; 17 | 18 | @end 19 | 20 | @protocol SPUInstallerAgentProtocol; 21 | 22 | @interface AgentConnection : NSObject 23 | 24 | - (instancetype)initWithHostBundleIdentifier:(NSString *)bundleIdentifier delegate:(id)delegate; 25 | 26 | - (void)startListener; 27 | - (void)invalidate; 28 | 29 | @property (nonatomic, readonly, nullable) id agent; 30 | @property (nonatomic, readonly) BOOL connected; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /Autoupdate/AppInstaller.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppInstaller.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/7/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUUnarchiverProtocol.h" 11 | 12 | @interface AppInstaller : NSObject 13 | 14 | - (instancetype)initWithHostBundleIdentifier:(NSString *)hostBundleIdentifier; 15 | 16 | - (void)start; 17 | 18 | - (void)cleanupAndExitWithStatus:(int)status __attribute__((noreturn)); 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Autoupdate/SPUInstallationInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUInstallationInfo.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUAppcastItem; 14 | 15 | @interface SPUInstallationInfo : NSObject 16 | 17 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)appcastItem canSilentlyInstall:(BOOL)canSilentyInstall; 18 | 19 | @property (nonatomic, readonly) SUAppcastItem *appcastItem; 20 | @property (nonatomic, readonly) BOOL canSilentlyInstall; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Autoupdate/SPUInstallationInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUInstallationInfo.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUInstallationInfo.h" 10 | #import "SUAppcastItem.h" 11 | 12 | 13 | #include "AppKitPrevention.h" 14 | 15 | static NSString *SUAppcastItemKey = @"SUAppcastItem"; 16 | static NSString *SUCanSilentlyInstallKey = @"SUCanSilentlyInstall"; 17 | 18 | @implementation SPUInstallationInfo 19 | 20 | @synthesize appcastItem = _appcastItem; 21 | @synthesize canSilentlyInstall = _canSilentlyInstall; 22 | 23 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)appcastItem canSilentlyInstall:(BOOL)canSilentlyInstall 24 | { 25 | self = [super init]; 26 | if (self != nil) { 27 | _appcastItem = appcastItem; 28 | _canSilentlyInstall = canSilentlyInstall; 29 | } 30 | return self; 31 | } 32 | 33 | - (nullable instancetype)initWithCoder:(NSCoder *)decoder 34 | { 35 | SUAppcastItem *appcastItem = [decoder decodeObjectOfClass:[SUAppcastItem class] forKey:SUAppcastItemKey]; 36 | if (appcastItem == nil) { 37 | return nil; 38 | } 39 | 40 | BOOL canSilentlyInstall = [decoder decodeBoolForKey:SUCanSilentlyInstallKey]; 41 | return [self initWithAppcastItem:appcastItem canSilentlyInstall:canSilentlyInstall]; 42 | } 43 | 44 | - (void)encodeWithCoder:(NSCoder *)coder 45 | { 46 | [coder encodeObject:self.appcastItem forKey:SUAppcastItemKey]; 47 | [coder encodeBool:self.canSilentlyInstall forKey:SUCanSilentlyInstallKey]; 48 | } 49 | 50 | + (BOOL)supportsSecureCoding 51 | { 52 | return YES; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Autoupdate/SPUInstallationInputData.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUInstallationInputData.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/24/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SPUInstallationInputData : NSObject 14 | 15 | /* 16 | * relaunchPath - path to application bundle to relaunch and listen for termination 17 | * hostBundlePath - path to host bundle to update & replace 18 | * updateDirectoryPath - path to update directory (i.e, temporary directory containing the new update archive) 19 | * downloadName - name of update archive in update directory 20 | * dsaSignature - DSA signature for the update that came from the appcast item 21 | * decryptionPassword - optional decryption password for dmg archives 22 | */ 23 | - (instancetype)initWithRelaunchPath:(NSString *)relaunchPath hostBundlePath:(NSString *)hostBundlePath updateDirectoryPath:(NSString *)updateDirectoryPath downloadName:(NSString *)downloadName installationType:(NSString *)installationType dsaSignature:(NSString *)dsaSignature decryptionPassword:(nullable NSString *)decryptionPassword; 24 | 25 | @property (nonatomic, copy, readonly) NSString *relaunchPath; 26 | @property (nonatomic, copy, readonly) NSString *hostBundlePath; 27 | @property (nonatomic, copy, readonly) NSString *updateDirectoryPath; 28 | @property (nonatomic, copy, readonly) NSString *downloadName; 29 | @property (nonatomic, copy, readonly) NSString *installationType; 30 | @property (nonatomic, copy, readonly) NSString *dsaSignature; 31 | @property (nonatomic, copy, readonly, nullable) NSString *decryptionPassword; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Autoupdate/SPUMessageTypes.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUMessageTypes.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/11/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUHost; 14 | 15 | extern NSString *SPUAppcastItemArchiveKey; 16 | 17 | // Order matters; higher stages have higher values. 18 | typedef NS_ENUM(int32_t, SPUInstallerMessageType) 19 | { 20 | SPUInstallerNotStarted = 0, 21 | SPUExtractionStarted = 1, 22 | SPUExtractedArchiveWithProgress = 2, 23 | SPUArchiveExtractionFailed = 3, 24 | SPUValidationStarted = 4, 25 | SPUInstallationStartedStage1 = 5, 26 | SPUInstallationFinishedStage1 = 6, 27 | SPUInstallationFinishedStage2 = 7, 28 | SPUInstallationFinishedStage3 = 8, 29 | SPUUpdaterAlivePing = 9 30 | }; 31 | 32 | typedef NS_ENUM(int32_t, SPUUpdaterMessageType) 33 | { 34 | SPUInstallationData = 0, 35 | SPUSentUpdateAppcastItemData = 1, 36 | SPUResumeInstallationToStage2 = 2, 37 | SPUUpdaterAlivePong = 3 38 | }; 39 | 40 | BOOL SPUInstallerMessageTypeIsLegal(SPUInstallerMessageType oldMessageType, SPUInstallerMessageType newMessageType); 41 | 42 | NSString *SPUInstallerServiceNameForBundleIdentifier(NSString *bundleIdentifier); 43 | 44 | NSString *SPUStatusInfoServiceNameForBundleIdentifier(NSString *bundleIdentifier); 45 | 46 | NSString *SPUProgressAgentServiceNameForBundleIdentifier(NSString *bundleIdentifier); 47 | 48 | NS_ASSUME_NONNULL_END 49 | -------------------------------------------------------------------------------- /Autoupdate/SUBinaryDeltaApply.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUBinaryDeltaApply.h 3 | // Sparkle 4 | // 5 | // Created by Mark Rowe on 2009-06-01. 6 | // Copyright 2009 Mark Rowe. All rights reserved. 7 | // 8 | 9 | #ifndef SUBINARYDELTAAPPLY_H 10 | #define SUBINARYDELTAAPPLY_H 11 | 12 | #import 13 | 14 | @class NSString; 15 | BOOL applyBinaryDelta(NSString *source, NSString *destination, NSString *patchFile, BOOL verbose, void (^progressCallback)(double), NSError * __autoreleasing *error); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /Autoupdate/SUBinaryDeltaCreate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUBinaryDeltaCreate.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/9/15. 6 | // Copyright (c) 2015 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUBINARYDELTACREATE_H 10 | #define SUBINARYDELTACREATE_H 11 | 12 | #import "SUBinaryDeltaCommon.h" 13 | 14 | @class NSString; 15 | BOOL createBinaryDelta(NSString *source, NSString *destination, NSString *patchFile, SUBinaryDeltaMajorVersion majorVersion, BOOL verbose, NSError * __autoreleasing *error); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /Autoupdate/SUBinaryDeltaUnarchiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUBinaryDeltaUnarchiver.h 3 | // Sparkle 4 | // 5 | // Created by Mark Rowe on 2009-06-03. 6 | // Copyright 2009 Mark Rowe. All rights reserved. 7 | // 8 | 9 | #ifndef SUBINARYDELTAUNARCHIVER_H 10 | #define SUBINARYDELTAUNARCHIVER_H 11 | 12 | #import 13 | #import "SUUnarchiverProtocol.h" 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface SUBinaryDeltaUnarchiver : NSObject 18 | 19 | - (instancetype)initWithArchivePath:(NSString *)archivePath updateHostBundlePath:(NSString *)updateHostBundlePath; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Autoupdate/SUCodeSigningVerifier.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUCodeSigningVerifier.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 7/5/12. 6 | // 7 | // 8 | 9 | #ifndef SUCODESIGNINGVERIFIER_H 10 | #define SUCODESIGNINGVERIFIER_H 11 | 12 | #import 13 | 14 | @interface SUCodeSigningVerifier : NSObject 15 | + (BOOL)codeSignatureAtBundleURL:(NSURL *)oldBundleURL matchesSignatureAtBundleURL:(NSURL *)newBundleURL error:(NSError **)error; 16 | + (BOOL)codeSignatureIsValidAtBundleURL:(NSURL *)bundleURL error:(NSError **)error; 17 | + (BOOL)bundleAtURLIsCodeSigned:(NSURL *)bundleURL; 18 | @end 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /Autoupdate/SUDSAVerifier.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUDSAVerifier.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | // Includes code by Zach Waldowski on 10/18/13. 9 | // Copyright 2014 Big Nerd Ranch. Licensed under MIT. 10 | // 11 | // Includes code from Plop by Mark Hamlin. 12 | // Copyright 2011 Mark Hamlin. Licensed under BSD. 13 | // 14 | 15 | #ifndef SUDSAVERIFIER_H 16 | #define SUDSAVERIFIER_H 17 | 18 | #import 19 | 20 | #if __MAC_OS_X_VERSION_MAX_ALLOWED < 1090 21 | @interface NSData (SUDSAVerifier) 22 | - (id)initWithBase64Encoding:(NSString *)base64String; 23 | @end 24 | #endif 25 | 26 | @interface SUDSAVerifier : NSObject 27 | 28 | + (BOOL)validatePath:(NSString *)path withEncodedDSASignature:(NSString *)encodedSignature withPublicDSAKey:(NSString *)pkeyString; 29 | 30 | - (instancetype)initWithPublicKeyData:(NSData *)data; 31 | 32 | - (BOOL)verifyFileAtPath:(NSString *)path signature:(NSData *)signature; 33 | - (BOOL)verifyStream:(NSInputStream *)stream signature:(NSData *)signature; 34 | 35 | @end 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Autoupdate/SUDiskImageUnarchiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUDiskImageUnarchiver.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 6/16/08. 6 | // Copyright 2008 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUDISKIMAGEUNARCHIVER_H 10 | #define SUDISKIMAGEUNARCHIVER_H 11 | 12 | #import 13 | #import "SUUnarchiverProtocol.h" 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface SUDiskImageUnarchiver : NSObject 18 | 19 | - (instancetype)initWithArchivePath:(NSString *)archivePath decryptionPassword:(nullable NSString *)decryptionPassword; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Autoupdate/SUGuidedPackageInstaller.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUGuidedPackageInstaller.h 3 | // Sparkle 4 | // 5 | // Created by Graham Miln on 14/05/2010. 6 | // Copyright 2010 Dragon Systems Software Limited. All rights reserved. 7 | // 8 | 9 | /*! 10 | # Sparkle Guided Installations 11 | 12 | A guided installation allows Sparkle to download and install a package (pkg) or multi-package (mpkg) without user interaction. 13 | 14 | The installer package is installed using macOS's built-in command line installer, `/usr/sbin/installer`. No installation interface is shown to the user. 15 | 16 | A guided installation can be started by applications other than the application being replaced. This is particularly useful where helper applications or agents are used. 17 | */ 18 | 19 | #import 20 | #import "SUInstallerProtocol.h" 21 | 22 | @interface SUGuidedPackageInstaller : NSObject 23 | 24 | - (instancetype)initWithPackagePath:(NSString *)packagePath installationPath:(NSString *)installationPath; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Autoupdate/SUInstaller.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstaller.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 4/10/08. 6 | // Copyright 2008 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @class SUHost; 15 | 16 | @interface SUInstaller : NSObject 17 | 18 | + (nullable id)installerForHost:(SUHost *)host expectedInstallationType:(NSString *)expectedInstallationType updateDirectory:(NSString *)updateDirectory error:(NSError **)error; 19 | 20 | + (nullable NSString *)installSourcePathInUpdateFolder:(NSString *)inUpdateFolder forHost:(SUHost *)host isPackage:(BOOL *)isPackagePtr isGuided:(nullable BOOL *)isGuidedPtr; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Autoupdate/SUInstallerProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/12/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SUInstallerProtocol 14 | 15 | // Any installation work can be done prior to user application being terminated and relaunched 16 | // No UI should occur during this stage (i.e, do not show package installer apps, etc..) 17 | // Should be able to be called from non-main thread 18 | - (BOOL)performInitialInstallation:(NSError **)error; 19 | 20 | // Any installation work after the user application has has been terminated. This is where the final installation work can be done. 21 | // After this stage is done, the user application may be relaunched. 22 | // Should be able to be called from non-main thread 23 | - (BOOL)performFinalInstallation:(NSError **)error; 24 | 25 | // Indicates whether or not this installer can install the update silently in the background, without hindering the user 26 | // If this returns NO, then the installation can fail if the user did not directly request for the install to occur. 27 | // Should be thread safe 28 | - (BOOL)canInstallSilently; 29 | 30 | // The destination and installation path of the bundle being updated 31 | - (NSString *)installationPath; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Autoupdate/SUPackageInstaller.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUPackageInstaller.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 4/10/08. 6 | // Copyright 2008 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerProtocol.h" 11 | 12 | // This is the deprecated package installation type, aka the "interactive" package installer 13 | // For a more supported package installation, see SUGuidedPackageInstaller 14 | 15 | @interface SUPackageInstaller : NSObject 16 | 17 | - (instancetype)initWithPackagePath:(NSString *)packagePath installationPath:(NSString *)installationPath; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Autoupdate/SUPipedUnarchiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUPipedUnarchiver.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 6/16/08. 6 | // Copyright 2008 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUPIPEDUNARCHIVER_H 10 | #define SUPIPEDUNARCHIVER_H 11 | 12 | #import 13 | #import "SUUnarchiverProtocol.h" 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface SUPipedUnarchiver : NSObject 18 | 19 | - (instancetype)initWithArchivePath:(NSString *)archivePath; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Autoupdate/SUPlainInstaller.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUPlainInstaller.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 4/10/08. 6 | // Copyright 2008 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerProtocol.h" 11 | 12 | @class SUHost; 13 | @protocol SUVersionComparison; 14 | 15 | @interface SUPlainInstaller : NSObject 16 | 17 | /*! 18 | @param host The current (old) bundle host 19 | @param bundlePath The path to the new bundle that will be installed. 20 | @param installationPath The path the new bundlePath will be installed to. 21 | */ 22 | - (instancetype)initWithHost:(SUHost *)host bundlePath:(NSString *)bundlePath installationPath:(NSString *)installationPath; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Autoupdate/SUStatusInfoProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStatusInfoProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SUStatusInfoProtocol 14 | 15 | - (void)probeStatusInfoWithReply:(void (^)(NSData * _Nullable installationInfoData))reply; 16 | 17 | - (void)probeStatusConnectivityWithReply:(void (^)(void))reply; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Autoupdate/SUUnarchiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUnarchiver.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SUUnarchiverProtocol; 14 | 15 | @interface SUUnarchiver : NSObject 16 | 17 | + (nullable id )unarchiverForPath:(NSString *)path updatingHostBundlePath:(nullable NSString *)hostPath decryptionPassword:(nullable NSString *)decryptionPassword; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Autoupdate/SUUnarchiver.m: -------------------------------------------------------------------------------- 1 | // 2 | // SUUnarchiver.m 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import "SUUnarchiver.h" 10 | #import "SUUnarchiverProtocol.h" 11 | #import "SUPipedUnarchiver.h" 12 | #import "SUDiskImageUnarchiver.h" 13 | #import "SUBinaryDeltaUnarchiver.h" 14 | 15 | 16 | #include "AppKitPrevention.h" 17 | 18 | @implementation SUUnarchiver 19 | 20 | + (nullable id )unarchiverForPath:(NSString *)path updatingHostBundlePath:(nullable NSString *)hostPath decryptionPassword:(nullable NSString *)decryptionPassword 21 | { 22 | if ([SUPipedUnarchiver canUnarchivePath:path]) { 23 | return [[SUPipedUnarchiver alloc] initWithArchivePath:path]; 24 | 25 | } else if ([SUDiskImageUnarchiver canUnarchivePath:path]) { 26 | return [[SUDiskImageUnarchiver alloc] initWithArchivePath:path decryptionPassword:decryptionPassword]; 27 | 28 | } else if ([SUBinaryDeltaUnarchiver canUnarchivePath:path]) { 29 | assert(hostPath != nil); 30 | NSString *nonNullHostPath = hostPath; 31 | return [[SUBinaryDeltaUnarchiver alloc] initWithArchivePath:path updateHostBundlePath:nonNullHostPath]; 32 | } 33 | return nil; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Autoupdate/SUUnarchiverNotifier.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUnarchiverNotifier.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 12/21/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SUUnarchiverNotifier : NSObject 14 | 15 | - (instancetype)initWithCompletionBlock:(void (^)(NSError * _Nullable))completionBlock progressBlock:(void (^ _Nullable)(double))progressBlock; 16 | 17 | - (void)notifySuccess; 18 | 19 | - (void)notifyFailureWithError:(NSError * _Nullable)reason; 20 | 21 | - (void)notifyProgress:(double)progress; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Autoupdate/SUUnarchiverNotifier.m: -------------------------------------------------------------------------------- 1 | // 2 | // SUUnarchiverNotifier.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 12/21/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SUUnarchiverNotifier.h" 10 | #import "SULocalizations.h" 11 | #import "SUErrors.h" 12 | 13 | 14 | #include "AppKitPrevention.h" 15 | 16 | @interface SUUnarchiverNotifier () 17 | 18 | @property (nonatomic, readonly, copy) void (^completionBlock)(NSError * _Nullable); 19 | @property (nonatomic, readonly, copy) void (^ _Nullable progressBlock)(double); 20 | 21 | @end 22 | 23 | @implementation SUUnarchiverNotifier 24 | 25 | @synthesize completionBlock = _completionBlock; 26 | @synthesize progressBlock = _progressBlock; 27 | 28 | - (instancetype)initWithCompletionBlock:(void (^)(NSError * _Nullable))completionBlock progressBlock:(void (^ _Nullable)(double))progressBlock 29 | { 30 | self = [super init]; 31 | if (self != nil) { 32 | _completionBlock = [completionBlock copy]; 33 | _progressBlock = [progressBlock copy]; 34 | } 35 | return self; 36 | } 37 | 38 | - (void)notifySuccess 39 | { 40 | dispatch_async(dispatch_get_main_queue(), ^{ 41 | self.completionBlock(nil); 42 | }); 43 | } 44 | 45 | - (void)notifyFailureWithError:(NSError * _Nullable)reason 46 | { 47 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:SULocalizedString(@"An error occurred while extracting the archive. Please try again later.", nil) forKey:NSLocalizedDescriptionKey]; 48 | if (reason) { 49 | [userInfo setObject:(NSError * _Nonnull)reason forKey:NSUnderlyingErrorKey]; 50 | } 51 | 52 | NSError *error = [NSError errorWithDomain:SUSparkleErrorDomain code:SUUnarchivingError userInfo:userInfo]; 53 | 54 | dispatch_async(dispatch_get_main_queue(), ^{ 55 | self.completionBlock(error); 56 | }); 57 | } 58 | 59 | - (void)notifyProgress:(double)progress 60 | { 61 | if (self.progressBlock != nil) { 62 | dispatch_async(dispatch_get_main_queue(), ^{ 63 | self.progressBlock(progress); 64 | }); 65 | } 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Autoupdate/SUUnarchiverProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUnarchiverProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/26/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SUUnarchiverProtocol 14 | 15 | + (BOOL)canUnarchivePath:(NSString *)path; 16 | 17 | + (BOOL)unsafeIfArchiveIsNotValidated; 18 | 19 | - (void)unarchiveWithCompletionBlock:(void (^)(NSError * _Nullable))completionBlock progressBlock:(void (^ _Nullable)(double))progressBlock; 20 | 21 | - (NSString *)description; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Autoupdate/StatusInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // StatusInfo.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUStatusInfoProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface StatusInfo : NSObject 15 | 16 | - (instancetype)initWithHostBundleIdentifier:(NSString *)bundleIdentifier; 17 | 18 | @property (nonatomic, nullable) NSData *installationInfoData; 19 | 20 | - (void)startListener; 21 | 22 | - (void)invalidate; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Autoupdate/StatusInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // StatusInfo.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "StatusInfo.h" 10 | #import "SPUMessageTypes.h" 11 | 12 | 13 | #include "AppKitPrevention.h" 14 | 15 | @interface StatusInfo () 16 | 17 | @property (nonatomic) NSXPCListener *xpcListener; 18 | 19 | @end 20 | 21 | @implementation StatusInfo 22 | 23 | @synthesize xpcListener = _xpcListener; 24 | @synthesize installationInfoData = _installationInfoData; 25 | 26 | - (instancetype)initWithHostBundleIdentifier:(NSString *)bundleIdentifier 27 | { 28 | self = [super init]; 29 | if (self != nil) { 30 | _xpcListener = [[NSXPCListener alloc] initWithMachServiceName:SPUStatusInfoServiceNameForBundleIdentifier(bundleIdentifier)]; 31 | _xpcListener.delegate = self; 32 | } 33 | return self; 34 | } 35 | 36 | - (void)startListener 37 | { 38 | [self.xpcListener resume]; 39 | } 40 | 41 | - (void)invalidate 42 | { 43 | [self.xpcListener invalidate]; 44 | self.xpcListener = nil; 45 | } 46 | 47 | - (BOOL)listener:(NSXPCListener *)__unused listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection 48 | { 49 | newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SUStatusInfoProtocol)]; 50 | newConnection.exportedObject = self; 51 | 52 | [newConnection resume]; 53 | 54 | return YES; 55 | } 56 | 57 | - (void)probeStatusInfoWithReply:(void (^)(NSData * _Nullable))reply 58 | { 59 | dispatch_async(dispatch_get_main_queue(), ^{ 60 | reply(self.installationInfoData); 61 | }); 62 | } 63 | 64 | - (void)probeStatusConnectivityWithReply:(void (^)(void))reply 65 | { 66 | reply(); 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Autoupdate/TerminationListener.h: -------------------------------------------------------------------------------- 1 | // 2 | // TerminationListener.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/7/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface TerminationListener : NSObject 14 | 15 | - (instancetype)initWithProcessIdentifier:(NSNumber * _Nullable)processIdentifier; 16 | 17 | @property (nonatomic, readonly) BOOL terminated; 18 | 19 | // If the process identifier provided was nil, then the completion block will invoke immediately with a YES success 20 | - (void)startListeningWithCompletion:(void (^)(BOOL success))completionBlock; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Autoupdate/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "AppInstaller.h" 3 | 4 | 5 | #include "AppKitPrevention.h" 6 | 7 | int main(int __unused argc, const char __unused *argv[]) 8 | { 9 | @autoreleasepool 10 | { 11 | NSArray *args = [[NSProcessInfo processInfo] arguments]; 12 | if (args.count != 2) { 13 | return EXIT_FAILURE; 14 | } 15 | 16 | NSString *hostBundleIdentifier = args[1]; 17 | 18 | AppInstaller *appInstaller = [[AppInstaller alloc] initWithHostBundleIdentifier:hostBundleIdentifier]; 19 | [appInstaller start]; 20 | 21 | // Ignore SIGTERM because we are going to catch it ourselves 22 | signal(SIGTERM, SIG_IGN); 23 | 24 | dispatch_source_t sigtermSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGTERM, 0, dispatch_get_main_queue()); 25 | dispatch_source_set_event_handler(sigtermSource, ^{ 26 | [appInstaller cleanupAndExitWithStatus:SIGTERM]; 27 | }); 28 | dispatch_resume(sigtermSource); 29 | 30 | [[NSRunLoop currentRunLoop] run]; 31 | } 32 | 33 | return EXIT_SUCCESS; 34 | } 35 | -------------------------------------------------------------------------------- /Configurations/ConfigBinaryDelta.xcconfig: -------------------------------------------------------------------------------- 1 | // BinaryDelta tool only 2 | -------------------------------------------------------------------------------- /Configurations/ConfigCommonCoverage.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigCommonDebug.xcconfig" 2 | 3 | SPARKLE_ALLOW_ARBITRARY_HTTP_LOADS = 1 4 | GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS_COMMON) 5 | 6 | GCC_GENERATE_TEST_COVERAGE_FILES = YES 7 | GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES 8 | -------------------------------------------------------------------------------- /Configurations/ConfigCommonDebug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigCommon.xcconfig" 2 | 3 | // Debug only 4 | 5 | SPARKLE_ALLOW_ARBITRARY_HTTP_LOADS = 1 6 | 7 | GCC_OPTIMIZATION_LEVEL = 0 8 | DEBUG_INFORMATION_FORMAT = dwarf 9 | ENABLE_TESTABILITY = YES 10 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES 11 | GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS_COMMON) DEBUG=1 12 | ONLY_ACTIVE_ARCH = YES 13 | COPY_PHASE_STRIP = NO 14 | -------------------------------------------------------------------------------- /Configurations/ConfigCommonRelease.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigCommon.xcconfig" 2 | 3 | // Release only 4 | 5 | SPARKLE_ALLOW_ARBITRARY_HTTP_LOADS = 0 6 | 7 | GCC_OPTIMIZATION_LEVEL = s 8 | DEBUG_INFORMATION_FORMAT = dwarf-with-dsym 9 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES 10 | GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS_COMMON) 11 | DEAD_CODE_STRIPPING = YES 12 | GCC_TREAT_WARNINGS_AS_ERRORS = NO 13 | GCC_WARN_UNINITIALIZED_AUTOS = YES 14 | -------------------------------------------------------------------------------- /Configurations/ConfigDownloader.xcconfig: -------------------------------------------------------------------------------- 1 | // Downloader 2 | 3 | INFOPLIST_FILE = Downloader/Info.plist 4 | WRAPPER_EXTENSION = xpc 5 | PRODUCT_BUNDLE_IDENTIFIER = ${DOWNLOADER_BUNDLE_ID} 6 | PRODUCT_NAME = ${DOWNLOADER_BUNDLE_ID} 7 | CODE_SIGN_ENTITLEMENTS = Downloader/${DOWNLOADER_BUNDLE_ID}.entitlements 8 | -------------------------------------------------------------------------------- /Configurations/ConfigDownloaderDebug.xcconfig: -------------------------------------------------------------------------------- 1 | // Downloader Debug 2 | #include "ConfigDownloader.xcconfig" 3 | 4 | CODE_SIGN_IDENTITY = - 5 | -------------------------------------------------------------------------------- /Configurations/ConfigFramework.xcconfig: -------------------------------------------------------------------------------- 1 | // Framework only 2 | 3 | DYLIB_INSTALL_NAME_BASE = @rpath 4 | DYLIB_COMPATIBILITY_VERSION = 1.6 5 | DYLIB_CURRENT_VERSION = $(SPARKLE_VERSION_MAJOR).$(SPARKLE_VERSION_MINOR).$(SPARKLE_VERSION_PATCH) 6 | WRAPPER_EXTENSION = framework 7 | FRAMEWORK_VERSION = A 8 | INFOPLIST_FILE = Sparkle/Sparkle-Info.plist 9 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) BUILDING_SPARKLE=1 10 | SKIP_INSTALL = YES 11 | DEFINES_MODULE = YES 12 | PRODUCT_BUNDLE_IDENTIFIER = ${SPARKLE_BUNDLE_IDENTIFIER} 13 | -------------------------------------------------------------------------------- /Configurations/ConfigFrameworkDebug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigFramework.xcconfig" 2 | 3 | // Unit tests need access to non-public classes 4 | GCC_SYMBOLS_PRIVATE_EXTERN = NO 5 | -------------------------------------------------------------------------------- /Configurations/ConfigGenerateAppcast.xcconfig: -------------------------------------------------------------------------------- 1 | // Generate Appcast only 2 | 3 | #include "ConfigSwift.xcconfig" 4 | 5 | SWIFT_OBJC_BRIDGING_HEADER = generate_appcast/Appcast-Bridging-Header.h 6 | MACOSX_DEPLOYMENT_TARGET = 10.11 7 | PRODUCT_NAME = generate_appcast 8 | -------------------------------------------------------------------------------- /Configurations/ConfigGenerateAppcastDebug.xcconfig: -------------------------------------------------------------------------------- 1 | // Generate Appcast Debug 2 | 3 | #include "ConfigGenerateAppcast.xcconfig" 4 | #include "ConfigSwiftDebug.xcconfig" 5 | -------------------------------------------------------------------------------- /Configurations/ConfigGenerateAppcastRelease.xcconfig: -------------------------------------------------------------------------------- 1 | // Generate Appcast Release 2 | 3 | #include "ConfigGenerateAppcast.xcconfig" 4 | #include "ConfigSwiftRelease.xcconfig" 5 | -------------------------------------------------------------------------------- /Configurations/ConfigInstallerConnection.xcconfig: -------------------------------------------------------------------------------- 1 | // InstallerConnection 2 | 3 | INFOPLIST_FILE = InstallerConnection/Info.plist 4 | WRAPPER_EXTENSION = xpc 5 | PRODUCT_BUNDLE_IDENTIFIER = ${INSTALLER_CONNECTION_BUNDLE_ID} 6 | PRODUCT_NAME = ${INSTALLER_CONNECTION_BUNDLE_ID} 7 | -------------------------------------------------------------------------------- /Configurations/ConfigInstallerConnectionDebug.xcconfig: -------------------------------------------------------------------------------- 1 | // InstallerConnection Debug 2 | 3 | #include "ConfigInstallerConnection.xcconfig" 4 | 5 | CODE_SIGN_IDENTITY = - 6 | -------------------------------------------------------------------------------- /Configurations/ConfigInstallerLauncher.xcconfig: -------------------------------------------------------------------------------- 1 | // Installer Launcher 2 | 3 | INFOPLIST_FILE = InstallerLauncher/Info.plist 4 | WRAPPER_EXTENSION = xpc 5 | PRODUCT_BUNDLE_IDENTIFIER = ${INSTALLER_LAUNCHER_BUNDLE_ID} 6 | PRODUCT_NAME = ${INSTALLER_LAUNCHER_BUNDLE_ID} 7 | -------------------------------------------------------------------------------- /Configurations/ConfigInstallerLauncherDebug.xcconfig: -------------------------------------------------------------------------------- 1 | // Installer Launcher Debug 2 | #include "ConfigInstallerLauncher.xcconfig" 3 | 4 | CODE_SIGN_IDENTITY = - 5 | -------------------------------------------------------------------------------- /Configurations/ConfigInstallerProgress.xcconfig: -------------------------------------------------------------------------------- 1 | // Installer Progress only 2 | 3 | INFOPLIST_FILE = Sparkle/InstallerProgress/InstallerProgress-Info.plist 4 | PRODUCT_NAME = $(SPARKLE_INSTALLER_PROGRESS_TOOL_NAME) 5 | SKIP_INSTALL = YES 6 | CLANG_ENABLE_MODULES = NO 7 | -------------------------------------------------------------------------------- /Configurations/ConfigInstallerStatus.xcconfig: -------------------------------------------------------------------------------- 1 | // InstallerStatus 2 | 3 | INFOPLIST_FILE = InstallerStatus/Info.plist 4 | WRAPPER_EXTENSION = xpc 5 | PRODUCT_BUNDLE_IDENTIFIER = ${INSTALLER_STATUS_BUNDLE_ID} 6 | PRODUCT_NAME = ${INSTALLER_STATUS_BUNDLE_ID} 7 | -------------------------------------------------------------------------------- /Configurations/ConfigInstallerStatusDebug.xcconfig: -------------------------------------------------------------------------------- 1 | // InstallerStatus Debug 2 | 3 | #include "ConfigInstallerStatus.xcconfig" 4 | 5 | CODE_SIGN_IDENTITY = - 6 | -------------------------------------------------------------------------------- /Configurations/ConfigRelaunch.xcconfig: -------------------------------------------------------------------------------- 1 | // Relaunch Tool only 2 | 3 | PRODUCT_NAME = $(SPARKLE_RELAUNCH_TOOL_NAME) 4 | SKIP_INSTALL = YES 5 | CLANG_ENABLE_MODULES = NO 6 | -------------------------------------------------------------------------------- /Configurations/ConfigSparkleTool.xcconfig: -------------------------------------------------------------------------------- 1 | // sparkle command line tool only 2 | 3 | INFOPLIST_FILE = sparkle-cli/Info.plist 4 | PRODUCT_BUNDLE_IDENTIFIER = org.sparkle-project.sparkle-cli 5 | PRODUCT_NAME = sparkle 6 | LD_RUNPATH_SEARCH_PATHS = @executable_path/../Frameworks/ 7 | -------------------------------------------------------------------------------- /Configurations/ConfigSwift.xcconfig: -------------------------------------------------------------------------------- 1 | SWIFT_VERSION = 3.0 2 | -------------------------------------------------------------------------------- /Configurations/ConfigSwiftDebug.xcconfig: -------------------------------------------------------------------------------- 1 | SWIFT_OPTIMIZATION_LEVEL = -Onone 2 | -------------------------------------------------------------------------------- /Configurations/ConfigSwiftRelease.xcconfig: -------------------------------------------------------------------------------- 1 | SWIFT_OPTIMIZATION_LEVEL = -Owholemodule 2 | -------------------------------------------------------------------------------- /Configurations/ConfigTestApp.xcconfig: -------------------------------------------------------------------------------- 1 | // Test Application 2 | 3 | INFOPLIST_FILE = TestApplication/TestApplication-Info.plist 4 | WRAPPER_EXTENSION = app 5 | ASSETCATALOG_COMPILER_APPICON_NAME = $(SPARKLE_ICON_NAME) 6 | LD_RUNPATH_SEARCH_PATHS = @executable_path/../Frameworks 7 | PRODUCT_BUNDLE_IDENTIFIER = org.sparkle-project.SparkleTestApp 8 | CODE_SIGN_ENTITLEMENTS = TestApplication/Sparkle-Test-App.entitlements 9 | -------------------------------------------------------------------------------- /Configurations/ConfigTestAppDebug.xcconfig: -------------------------------------------------------------------------------- 1 | // Test Application Debug 2 | #include "ConfigTestApp.xcconfig" 3 | 4 | CODE_SIGN_IDENTITY = - 5 | -------------------------------------------------------------------------------- /Configurations/ConfigTestAppHelper.xcconfig: -------------------------------------------------------------------------------- 1 | // Test Application Helper 2 | 3 | INFOPLIST_FILE = TestAppHelper/Info.plist 4 | WRAPPER_EXTENSION = xpc 5 | LD_RUNPATH_SEARCH_PATHS = @executable_path/../../../../Frameworks 6 | PRODUCT_BUNDLE_IDENTIFIER = org.sparkle-project.TestAppHelper 7 | -------------------------------------------------------------------------------- /Configurations/ConfigTestAppHelperDebug.xcconfig: -------------------------------------------------------------------------------- 1 | // Test Application Helper Debug 2 | #include "ConfigTestAppHelper.xcconfig" 3 | 4 | CODE_SIGN_IDENTITY = - 5 | -------------------------------------------------------------------------------- /Configurations/ConfigUITest.xcconfig: -------------------------------------------------------------------------------- 1 | // UI Test only 2 | 3 | #include "ConfigSwift.xcconfig" 4 | 5 | INFOPLIST_FILE = UITests/UITests-Info.plist 6 | WRAPPER_EXTENSION = xctest 7 | MACOSX_DEPLOYMENT_TARGET = 10.11 8 | 9 | FRAMEWORK_SEARCH_PATHS = $(inherited) $(DEVELOPER_FRAMEWORKS_DIR) 10 | LD_RUNPATH_SEARCH_PATHS = @loader_path/../Frameworks 11 | 12 | TEST_TARGET_NAME = Sparkle Test App 13 | USES_XCTRUNNER = YES 14 | -------------------------------------------------------------------------------- /Configurations/ConfigUITestCoverage.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigUITest.xcconfig" 2 | #include "ConfigSwiftDebug.xcconfig" 3 | 4 | GCC_GENERATE_TEST_COVERAGE_FILES = NO 5 | GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO 6 | -------------------------------------------------------------------------------- /Configurations/ConfigUITestDebug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigUITest.xcconfig" 2 | #include "ConfigSwiftDebug.xcconfig" 3 | -------------------------------------------------------------------------------- /Configurations/ConfigUITestRelease.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigUITest.xcconfig" 2 | #include "ConfigSwiftRelease.xcconfig" 3 | -------------------------------------------------------------------------------- /Configurations/ConfigUnitTest.xcconfig: -------------------------------------------------------------------------------- 1 | // Unit Test only 2 | 3 | #include "ConfigSwift.xcconfig" 4 | 5 | INFOPLIST_FILE = Tests/SparkleTests-Info.plist 6 | WRAPPER_EXTENSION = xctest 7 | OTHER_CFLAGS = $(inherited) -iframework"$(DEVELOPER_FRAMEWORKS_DIR)" -iframework"$(PLATFORM_DIR)/Developer/Library/Frameworks" 8 | GCC_SYMBOLS_PRIVATE_EXTERN = NO 9 | WARNING_CFLAGS = $(inherited) -Wno-variadic-macros -Wno-gnu-zero-variadic-macro-arguments 10 | FRAMEWORK_SEARCH_PATHS = $(inherited) $(DEVELOPER_FRAMEWORKS_DIR) 11 | LD_RUNPATH_SEARCH_PATHS = @loader_path/../Frameworks 12 | MACOSX_DEPLOYMENT_TARGET = 10.9 13 | CLANG_ENABLE_MODULES = YES 14 | SWIFT_OBJC_BRIDGING_HEADER = Tests/Sparkle Unit Tests-Bridging-Header.h 15 | -------------------------------------------------------------------------------- /Configurations/ConfigUnitTestCoverage.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigUnitTest.xcconfig" 2 | #include "ConfigSwiftDebug.xcconfig" 3 | 4 | GCC_GENERATE_TEST_COVERAGE_FILES = NO 5 | GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO 6 | -------------------------------------------------------------------------------- /Configurations/ConfigUnitTestDebug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigUnitTest.xcconfig" 2 | #include "ConfigSwiftDebug.xcconfig" 3 | -------------------------------------------------------------------------------- /Configurations/ConfigUnitTestRelease.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ConfigUnitTest.xcconfig" 2 | #include "ConfigSwiftRelease.xcconfig" 3 | -------------------------------------------------------------------------------- /Configurations/set-agent-signing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AGENT_PATH="${TARGET_BUILD_DIR}"/"${CONTENTS_FOLDER_PATH}"/"MacOS/${SPARKLE_INSTALLER_PROGRESS_TOOL_NAME}.app" 4 | 5 | #Only sign the agent app if we have code signing enabled (as we do with adhoc signatures in Debug builds for testing sandboxing) 6 | if ! [ -z ${CODE_SIGN_IDENTITY}] ; then 7 | codesign --verbose -f -s "${CODE_SIGN_IDENTITY}" "${AGENT_PATH}" 8 | fi 9 | -------------------------------------------------------------------------------- /Configurations/set-ats-exceptions-downloader-service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # http://stackoverflow.com/questions/32390228/is-it-possible-to-disable-ats-in-ios-9-just-for-debug-environment 4 | INFOPLIST="${TARGET_BUILD_DIR}"/"${INFOPLIST_PATH}" 5 | case "${SPARKLE_ALLOW_ARBITRARY_HTTP_LOADS}" in 6 | "YES"|"1") 7 | /usr/libexec/PlistBuddy -c "Set :NSAppTransportSecurity:NSAllowsArbitraryLoads YES" "${INFOPLIST}" 8 | ;; 9 | "NO"|"0") 10 | /usr/libexec/PlistBuddy -c "Set :NSAppTransportSecurity:NSAllowsArbitraryLoads NO" "${INFOPLIST}" 11 | ;; 12 | esac 13 | -------------------------------------------------------------------------------- /Configurations/set-ats-exceptions-test-app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # We should make sure ATS is off for the test app 4 | 5 | DOWNLOADER_INFO_PLIST="${TARGET_BUILD_DIR}"/"${CONTENTS_FOLDER_PATH}"/"XPCServices"/"${DOWNLOADER_BUNDLE_ID}.xpc"/"Contents"/"Info.plist" 6 | 7 | #Only alter bundles if code signing is off, else we'll invalidate the signature on them 8 | #If code signing is enabled (as in debug mode), then we rely on another script for turning ATS exceptions on for these services 9 | #In release mode however, those services do not have ATS exceptions set up which is why we have to set up exceptions *here* 10 | if [ -z ${CODE_SIGN_IDENTITY}] ; then 11 | /usr/libexec/PlistBuddy -c "Set :NSAppTransportSecurity:NSAllowsArbitraryLoads YES" "${DOWNLOADER_INFO_PLIST}" 12 | fi 13 | -------------------------------------------------------------------------------- /Configurations/set-git-version-info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if ! which -s git ; then 5 | exit 0 6 | fi 7 | 8 | if [ -z "$SRCROOT" ] || \ 9 | [ -z "$BUILT_PRODUCTS_DIR" ] || \ 10 | [ -z "$INFOPLIST_PATH" ] || \ 11 | [ -z "$CURRENT_PROJECT_VERSION" ]; then 12 | echo "$0: Must be run from Xcode!" 1>&2 13 | exit 1 14 | fi 15 | 16 | version="$CURRENT_PROJECT_VERSION" 17 | 18 | # Get version in format 1.x.x-commits-hash 19 | gitversion=$( cd "$SRCROOT"; git describe --tags --match '[12].*' || true ) 20 | if [ -z "$gitversion" ] ; then 21 | echo "$0: Can't find a Git hash!" 1>&2 22 | exit 0 23 | fi 24 | 25 | # remove everything before the first "-" to keep the hash part only 26 | versionsuffix=${gitversion#*-}; 27 | if [ "$versionsuffix" != "$gitversion" ]; then 28 | version="$version $versionsuffix" 29 | fi 30 | 31 | # and use it to set the CFBundleShortVersionString value 32 | export PATH="$PATH:/usr/libexec" 33 | PlistBuddy -c "Set :CFBundleShortVersionString '$version'" \ 34 | "$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH" 35 | -------------------------------------------------------------------------------- /Documentation/.gitignore: -------------------------------------------------------------------------------- 1 | html 2 | -------------------------------------------------------------------------------- /Documentation/Doxyfile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = Sparkle 2 | PROJECT_NUMBER = 1.14.0 3 | PROJECT_BRIEF = "A software update framework for macOS" 4 | PROJECT_LOGO = Resources/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png 5 | 6 | RECURSIVE = YES 7 | INPUT = Sparkle 8 | OUTPUT_DIRECTORY = Documentation 9 | 10 | GENERATE_HTML = YES 11 | GENERATE_LATEX = NO 12 | 13 | GENERATE_BUGLIST = YES 14 | GENERATE_DEPRECATEDLIST = YES 15 | GENERATE_TODOLIST = YES 16 | 17 | ALPHABETICAL_INDEX = YES 18 | 19 | QT_AUTOBRIEF = YES 20 | WARN_IF_UNDOCUMENTED = NO 21 | -------------------------------------------------------------------------------- /Documentation/build-docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$ACTION" = "" ] ; then 4 | if which -s doxygen ; then 5 | doxygen Documentation/Doxyfile 6 | else 7 | echo "warning: Doxygen not found in PATH" 8 | fi 9 | elif [ "$ACTION" = "clean" ] ; then 10 | rm -rf "$SRCROOT/Documentation/html" 11 | fi 12 | -------------------------------------------------------------------------------- /Documentation/graph-of-sparkle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Documentation/graph-of-sparkle.png -------------------------------------------------------------------------------- /Downloader/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | XPC! 17 | CFBundleShortVersionString 18 | ${CURRENT_PROJECT_VERSION} 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSAppTransportSecurity 24 | 25 | NSAllowsArbitraryLoads 26 | 27 | 28 | NSHumanReadableCopyright 29 | Copyright © 2016 Sparkle Project. All rights reserved. 30 | XPCService 31 | 32 | ServiceType 33 | Application 34 | RunLoopType 35 | NSRunLoop 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Downloader/SPUDownloader.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloader.h 3 | // Downloader 4 | // 5 | // Created by Mayur Pawashe on 4/1/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SPUDownloaderProtocol.h" 11 | 12 | @protocol SPUDownloaderDelegate; 13 | 14 | // This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection. 15 | @interface SPUDownloader : NSObject 16 | 17 | // Due to XPC remote object reasons, this delegate is strongly referenced 18 | // Invoke cleanup when done with this instance 19 | - (instancetype)initWithDelegate:(id )delegate; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Downloader/SPUDownloaderDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloaderDelegate.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/1/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SPUDownloadData; 14 | 15 | @protocol SPUDownloaderDelegate 16 | 17 | // This is only invoked for persistent downloads 18 | - (void)downloaderDidSetDestinationName:(NSString *)destinationName temporaryDirectory:(NSString *)temporaryDirectory; 19 | 20 | // Under rare cases, this may be called more than once, in which case the current progress should be reset back to 0 21 | // This is only invoked for persistent downloads 22 | - (void)downloaderDidReceiveExpectedContentLength:(int64_t)expectedContentLength; 23 | 24 | // This is only invoked for persistent downloads 25 | - (void)downloaderDidReceiveDataOfLength:(uint64_t)length; 26 | 27 | // downloadData is nil if this is a persisent download, otherwise it's non-nil if it's a temporary download 28 | - (void)downloaderDidFinishWithTemporaryDownloadData:(SPUDownloadData * _Nullable)downloadData; 29 | 30 | - (void)downloaderDidFailWithError:(NSError *)error; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /Downloader/SPUDownloaderProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloaderProtocol.h 3 | // PersistentDownloader 4 | // 5 | // Created by Mayur Pawashe on 4/1/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SPUURLRequest; 14 | 15 | // The protocol that this service will vend as its API. This header file will also need to be visible to the process hosting the service. 16 | @protocol SPUDownloaderProtocol 17 | 18 | - (void)startPersistentDownloadWithRequest:(SPUURLRequest *)request bundleIdentifier:(NSString *)bundleIdentifier desiredFilename:(NSString *)desiredFilename; 19 | 20 | - (void)startTemporaryDownloadWithRequest:(SPUURLRequest *)request; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Downloader/org.sparkle-project.Downloader.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /InstallerConnection/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | XPC! 17 | CFBundleShortVersionString 18 | ${CURRENT_PROJECT_VERSION} 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSHumanReadableCopyright 24 | Copyright © 2016 Sparkle Project. All rights reserved. 25 | XPCService 26 | 27 | ServiceType 28 | Application 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /InstallerConnection/SUInstallerCommunicationProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerCommunicationProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/9/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SUInstallerCommunicationProtocol 14 | 15 | - (void)handleMessageWithIdentifier:(int32_t)identifier data:(NSData *)data; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /InstallerConnection/SUInstallerConnection.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerConnection.h 3 | // InstallerConnection 4 | // 5 | // Created by Mayur Pawashe on 7/9/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerConnectionProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | // This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection. 15 | @interface SUInstallerConnection : NSObject 16 | 17 | // Due to XPC reasons, this delegate is strongly referenced, until it's invalidated 18 | - (instancetype)initWithDelegate:(id)delegate; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /InstallerConnection/SUInstallerConnectionProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerConnectionProtocol.h 3 | // InstallerConnection 4 | // 5 | // Created by Mayur Pawashe on 7/9/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerCommunicationProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @protocol SUInstallerConnectionProtocol 15 | 16 | // This method is declared in SUInstallerCommunicationProtocol too 17 | // the XPC decoder on macOS 10.8 doesn't follow protocols that adopt other protocols, which is why this protocol doesn't adopt SUInstallerCommunicationProtocol 18 | - (void)handleMessageWithIdentifier:(int32_t)identifier data:(NSData *)data; 19 | 20 | - (void)setInvalidationHandler:(void (^)(void))invalidationHandler; 21 | 22 | - (void)setServiceName:(NSString *)serviceName hostPath:(NSString *)hostPath installationType:(NSString *)installationType; 23 | 24 | - (void)invalidate; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /InstallerConnection/SUXPCInstallerConnection.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUXPCInstallerConnection.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerConnectionProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface SUXPCInstallerConnection : NSObject 15 | 16 | // Due to XPC reasons, this delegate is strongly referenced, until it's invalidated 17 | - (instancetype)initWithDelegate:(id)delegate; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /InstallerConnection/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // InstallerConnection 4 | // 5 | // Created by Mayur Pawashe on 7/9/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerConnection.h" 11 | #import "SUInstallerCommunicationProtocol.h" 12 | 13 | 14 | #include "AppKitPrevention.h" 15 | 16 | @interface ServiceDelegate : NSObject 17 | @end 18 | 19 | @implementation ServiceDelegate 20 | 21 | - (BOOL)listener:(NSXPCListener *)__unused listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { 22 | // This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection. 23 | 24 | // Configure the connection. 25 | // First, set the interface that the exported object implements. 26 | newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SUInstallerConnectionProtocol)]; 27 | newConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SUInstallerCommunicationProtocol)]; 28 | 29 | SUInstallerConnection *exportedObject = [[SUInstallerConnection alloc] initWithDelegate:newConnection.remoteObjectProxy]; 30 | 31 | newConnection.exportedObject = exportedObject; 32 | 33 | // Resuming the connection allows the system to deliver more incoming messages. 34 | [newConnection resume]; 35 | 36 | return YES; 37 | } 38 | 39 | @end 40 | 41 | int main(int __unused argc, const char * __unused argv[]) 42 | { 43 | // Create the delegate for the service. 44 | ServiceDelegate *delegate = [ServiceDelegate new]; 45 | 46 | // Set up the one NSXPCListener for this service. It will handle all incoming connections. 47 | NSXPCListener *listener = [NSXPCListener serviceListener]; 48 | listener.delegate = delegate; 49 | 50 | // Resuming the serviceListener starts this service. This method does not return. 51 | [listener resume]; 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /InstallerLauncher/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | XPC! 17 | CFBundleShortVersionString 18 | ${CURRENT_PROJECT_VERSION} 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSHumanReadableCopyright 24 | Copyright © 2016 Sparkle Project. All rights reserved. 25 | XPCService 26 | 27 | ServiceType 28 | Application 29 | JoinExistingSession 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /InstallerLauncher/SUInstallerLauncher.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerLauncher.h 3 | // InstallerLauncher 4 | // 5 | // Created by Mayur Pawashe on 4/1/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerLauncherProtocol.h" 11 | 12 | // Non-sandboxed XPC service used for launching our installer 13 | // This is necessary for sandboxed applications 14 | @interface SUInstallerLauncher : NSObject 15 | @end 16 | -------------------------------------------------------------------------------- /InstallerLauncher/SUInstallerLauncherProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerLauncherProtocol.h 3 | // InstallerLauncher 4 | // 5 | // Created by Mayur Pawashe on 4/1/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerLauncherStatus.h" 11 | 12 | @protocol SUInstallerLauncherProtocol 13 | 14 | - (void)launchInstallerWithHostBundlePath:(NSString *)hostBundlePath authorizationPrompt:(NSString *)authorizationPrompt installationType:(NSString *)installationType allowingDriverInteraction:(BOOL)allowingDriverInteraction allowingUpdaterInteraction:(BOOL)allowingUpdaterInteraction completion:(void (^)(SUInstallerLauncherStatus))completionHandler; 15 | 16 | - (void)checkIfApplicationInstallationRequiresAuthorizationWithHostBundlePath:(NSString *)hostBundlePath reply:(void(^)(BOOL requiresAuthorization))reply; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /InstallerLauncher/SUInstallerLauncherStatus.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerLauncherStatus.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/18/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, SUInstallerLauncherStatus) 12 | { 13 | SUInstallerLauncherSuccess = 0, 14 | SUInstallerLauncherCanceled = 1, 15 | SUInstallerLauncherAuthorizeLater = 3, 16 | SUInstallerLauncherFailure = 4 17 | }; 18 | -------------------------------------------------------------------------------- /InstallerLauncher/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // InstallerLauncher 4 | // 5 | // Created by Mayur Pawashe on 4/1/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerLauncher.h" 11 | 12 | @interface ServiceDelegate : NSObject 13 | @end 14 | 15 | @implementation ServiceDelegate 16 | 17 | - (BOOL)listener:(NSXPCListener *)__unused listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { 18 | // This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection. 19 | 20 | // Configure the connection. 21 | // First, set the interface that the exported object implements. 22 | newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SUInstallerLauncherProtocol)]; 23 | 24 | // Next, set the object that the connection exports. All messages sent on the connection to this service will be sent to the exported object to handle. The connection retains the exported object. 25 | SUInstallerLauncher *exportedObject = [SUInstallerLauncher new]; 26 | newConnection.exportedObject = exportedObject; 27 | 28 | // Resuming the connection allows the system to deliver more incoming messages. 29 | [newConnection resume]; 30 | 31 | // Returning YES from this method tells the system that you have accepted this connection. If you want to reject the connection for some reason, call -invalidate on the connection and return NO. 32 | return YES; 33 | } 34 | 35 | @end 36 | 37 | int main(int __unused argc, const char * __unused argv[]) 38 | { 39 | // Create the delegate for the service. 40 | ServiceDelegate *delegate = [ServiceDelegate new]; 41 | 42 | // Set up the one NSXPCListener for this service. It will handle all incoming connections. 43 | NSXPCListener *listener = [NSXPCListener serviceListener]; 44 | listener.delegate = delegate; 45 | 46 | // Resuming the serviceListener starts this service. This method does not return. 47 | [listener resume]; 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /InstallerStatus/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | XPC! 17 | CFBundleShortVersionString 18 | ${CURRENT_PROJECT_VERSION} 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSHumanReadableCopyright 24 | Copyright © 2016 Sparkle Project. All rights reserved. 25 | XPCService 26 | 27 | ServiceType 28 | Application 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /InstallerStatus/SUInstallerStatus.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerStatus.h 3 | // InstallerStatus 4 | // 5 | // Created by Mayur Pawashe on 7/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerStatusProtocol.h" 11 | 12 | // This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection. 13 | @interface SUInstallerStatus : NSObject 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /InstallerStatus/SUInstallerStatusProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerStatusProtocol.h 3 | // InstallerStatus 4 | // 5 | // Created by Mayur Pawashe on 7/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUStatusInfoProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | // The protocol that this service will vend as its API. This header file will also need to be visible to the process hosting the service. 15 | @protocol SUInstallerStatusProtocol 16 | 17 | // Even though this is declared in SUStatusInfoProtocol, we should declare it here because macOS 10.8 doesn't traverse adopted protocols, 18 | // which is why this protocol doesn't adopt SUStatusInfoProtocol 19 | - (void)probeStatusInfoWithReply:(void (^)(NSData * _Nullable installationInfoData))reply; 20 | 21 | // Even though this is declared in SUStatusInfoProtocol, we should declare it here because macOS 10.8 doesn't traverse adopted protocols, 22 | // which is why this protocol doesn't adopt SUStatusInfoProtocol 23 | - (void)probeStatusConnectivityWithReply:(void (^)(void))reply; 24 | 25 | - (void)setInvalidationHandler:(void (^)(void))invalidationHandler; 26 | 27 | - (void)setServiceName:(NSString *)serviceName; 28 | 29 | - (void)invalidate; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /InstallerStatus/SUXPCInstallerStatus.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUXPCInstallerStatus.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUInstallerStatusProtocol.h" 11 | 12 | @interface SUXPCInstallerStatus : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all localizable-strings release build test ci 2 | 3 | ifndef BUILDDIR 4 | BUILDDIR := $(shell mktemp -d "$(TMPDIR)/Sparkle.XXXXXX") 5 | endif 6 | 7 | localizable-strings: 8 | rm -f Sparkle/en.lproj/Sparkle.strings 9 | genstrings -o Sparkle/en.lproj -s SULocalizedString Sparkle/*.m Sparkle/*.h 10 | iconv -f UTF-16 -t UTF-8 < Sparkle/en.lproj/Localizable.strings > Sparkle/en.lproj/Sparkle.strings 11 | rm Sparkle/en.lproj/Localizable.strings 12 | 13 | release: 14 | xcodebuild -scheme Distribution -configuration Release -derivedDataPath "$(BUILDDIR)" build 15 | open -R "$(BUILDDIR)/Build/Products/Release/Sparkle-"*.tar.bz2 16 | cat Sparkle.podspec 17 | @echo "Don't forget to update CocoaPods! pod trunk push" 18 | 19 | build: 20 | xcodebuild clean build 21 | 22 | test: 23 | xcodebuild -scheme Distribution -configuration Debug test 24 | 25 | uitest: 26 | xcodebuild -scheme UITests -configuration Debug test 27 | 28 | ci: 29 | for i in {7..9} ; do \ 30 | if xcrun --sdk "macosx10.$$i" --show-sdk-path 2> /dev/null ; then \ 31 | ( rm -rf build && xcodebuild -sdk "macosx10.$$i" -scheme Distribution -configuration Coverage -derivedDataPath build ) || exit 1 ; \ 32 | fi ; \ 33 | done 34 | for i in {10..12} ; do \ 35 | if xcrun --sdk "macosx10.$$i" --show-sdk-path 2> /dev/null ; then \ 36 | ( rm -rf build && xcodebuild -sdk "macosx10.$$i" -scheme Distribution -configuration Coverage -derivedDataPath build test ) || exit 1 ; \ 37 | fi ; \ 38 | done 39 | 40 | check-localizations: 41 | ./Sparkle/CheckLocalizations.swift -root . -htmlPath "$(TMPDIR)/LocalizationsReport.htm" 42 | open "$(TMPDIR)/LocalizationsReport.htm" 43 | -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon_512x512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /Resources/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /Resources/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Screenshot.png -------------------------------------------------------------------------------- /Resources/Screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Screenshot2.png -------------------------------------------------------------------------------- /Resources/Screenshot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Screenshot3.png -------------------------------------------------------------------------------- /Resources/Sparkle-Icon.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Resources/Sparkle-Icon.sketch -------------------------------------------------------------------------------- /Sparkle.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Sparkle" 3 | s.version = "1.16.0" 4 | s.summary = "A software update framework for macOS" 5 | s.description = "Sparkle is an easy-to-use software update framework for Cocoa developers." 6 | s.homepage = "http://sparkle-project.org" 7 | s.documentation_url = "http://sparkle-project.org/documentation/" 8 | s.screenshot = "http://sparkle-project.org/images/screenshot-noshadow@2x.png" 9 | s.license = { 10 | :type => 'MIT', 11 | :file => 'LICENSE' 12 | } 13 | s.authors = { 14 | 'Mayur Pawashe' => 'zorgiepoo@gmail.com', 15 | 'Kornel Lesiński' => 'pornel@pornel.net', 16 | 'Jake Petroules' => 'jake.petroules@petroules.com', 17 | 'C.W. Betts' => 'computers57@hotmail.com', 18 | 'Andy Matuschak' => 'andy@andymatuschak.org', 19 | } 20 | 21 | s.platform = :osx, '10.7' 22 | s.source = { :http => "https://github.com/sparkle-project/Sparkle/releases/download/#{s.version}/Sparkle-#{s.version}.tar.bz2" } 23 | s.source_files = 'Sparkle.framework/Versions/A/Headers/*.h' 24 | 25 | s.public_header_files = 'Sparkle.framework/Versions/A/Headers/*.h' 26 | s.vendored_frameworks = 'Sparkle.framework' 27 | s.xcconfig = { 28 | 'FRAMEWORK_SEARCH_PATHS' => '"${PODS_ROOT}/Sparkle"', 29 | 'LD_RUNPATH_SEARCH_PATHS' => '@loader_path/../Frameworks' 30 | } 31 | s.requires_arc = true 32 | end 33 | -------------------------------------------------------------------------------- /Sparkle.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sparkle/AppKitPrevention.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppKitPrevention.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 1/17/17. 6 | // Copyright © 2017 Sparkle Project. All rights reserved. 7 | // 8 | 9 | // #include (not #import) this header to prevent AppKit from being imported 10 | // Note this should be your LAST #include in your implementation file 11 | 12 | // If this error is triggered, you can have Xcode indicate to you which source file including this header caused the issue 13 | 14 | // One may wonder for certain targets where AppKit is banned completely, why just not link AppKit instead. 15 | // Well, Xcode has thing called auto-linking that I don't trust very much. 16 | // Even after trying to disable the setting, I've had targets able to link to AppKit without AppKit being specified in the list of linked libraries. 17 | 18 | #ifdef _APPKITDEFINES_H 19 | #error This is a core or daemon-safe module and should NOT import AppKit 20 | #endif 21 | -------------------------------------------------------------------------------- /Sparkle/Autoupdate/TerminationListener.h: -------------------------------------------------------------------------------- 1 | // 2 | // TerminationListener.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/7/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface TerminationListener : NSObject 14 | 15 | - (instancetype)initWithProcessIdentifier:(NSNumber * _Nullable)processIdentifier; 16 | 17 | @property (nonatomic, readonly) BOOL terminated; 18 | 19 | // If the process identifier provided was nil, then the completion block will invoke immediately with a YES success 20 | - (void)startListeningWithCompletion:(void (^)(BOOL success))completionBlock; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Sparkle/InstallerProgress/InstallerProgress-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | ${CURRENT_PROJECT_VERSION} 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | ${CURRENT_PROJECT_VERSION} 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSPrincipalClass 28 | NSApplication 29 | LSUIElement 30 | 1 31 | 32 | 33 | -------------------------------------------------------------------------------- /Sparkle/InstallerProgress/InstallerProgressAppController.h: -------------------------------------------------------------------------------- 1 | // 2 | // InstallerProgressAppController.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol InstallerProgressDelegate; 14 | 15 | @interface InstallerProgressAppController : NSObject 16 | 17 | - (instancetype)initWithApplication:(NSApplication *)application arguments:(NSArray *)arguments delegate:(id)delegate; 18 | 19 | - (void)run; 20 | 21 | - (void)cleanupAndExitWithStatus:(int)status __attribute__((noreturn)); 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Sparkle/InstallerProgress/InstallerProgressDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // InstallerProgressDelegate.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUHost; 14 | 15 | @protocol InstallerProgressDelegate 16 | 17 | - (void)installerProgressShouldDisplayWithHost:(SUHost *)host; 18 | - (void)installerProgressShouldStop; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Sparkle/InstallerProgress/SPUInstallerAgentProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUInstallerAgentProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/17/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SPUInstallerAgentProtocol 14 | 15 | - (void)registerApplicationBundlePath:(NSString *)applicationBundlePath reply:(void (^)(NSNumber * _Nullable processIdentifier))reply; 16 | 17 | - (void)registerInstallationInfoData:(NSData *)installationInfoData; 18 | 19 | - (void)sendTerminationSignal; 20 | 21 | - (void)showProgress; 22 | 23 | - (void)stopProgress; 24 | 25 | - (void)relaunchPath:(NSString *)pathToRelaunch; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Sparkle/InstallerProgress/SUInstallerAgentInitiationProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerAgentInitiationProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/17/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol SUInstallerAgentInitiationProtocol 12 | 13 | - (void)connectionDidInitiateWithReply:(void (^)(void))acknowledgement; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Sparkle/InstallerProgress/ShowInstallerProgress.h: -------------------------------------------------------------------------------- 1 | // 2 | // ShowInstallerProgress.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "InstallerProgressDelegate.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface ShowInstallerProgress : NSObject 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Sparkle/InstallerProgress/ShowInstallerProgress.m: -------------------------------------------------------------------------------- 1 | // 2 | // ShowInstallerProgress.m 3 | // Installer Progress 4 | // 5 | // Created by Mayur Pawashe on 4/7/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ShowInstallerProgress.h" 11 | #import "SUStatusController.h" 12 | #import "SUHost.h" 13 | #import "SULocalizations.h" 14 | 15 | @interface ShowInstallerProgress () 16 | 17 | @property (nonatomic) SUStatusController *statusController; 18 | 19 | @end 20 | 21 | @implementation ShowInstallerProgress 22 | 23 | @synthesize statusController = _statusController; 24 | 25 | - (void)installerProgressShouldDisplayWithHost:(SUHost *)host 26 | { 27 | self.statusController = [[SUStatusController alloc] initWithHost:host]; 28 | 29 | [self.statusController setButtonTitle:SULocalizedString(@"Cancel Update", @"") target:nil action:nil isDefault:NO]; 30 | [self.statusController beginActionWithTitle:SULocalizedString(@"Installing update...", @"") maxProgressValue:0 statusText:@""]; 31 | [self.statusController showWindow:self]; 32 | } 33 | 34 | - (void)installerProgressShouldStop 35 | { 36 | [self.statusController close]; 37 | self.statusController = nil; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Sparkle/InstallerProgress/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "InstallerProgressAppController.h" 11 | #import "ShowInstallerProgress.h" 12 | 13 | int main(int __unused argc, const char __unused *argv[]) 14 | { 15 | @autoreleasepool 16 | { 17 | id showInstallerProgress = [[ShowInstallerProgress alloc] init]; 18 | 19 | InstallerProgressAppController *appController = 20 | [[InstallerProgressAppController alloc] 21 | initWithApplication:[NSApplication sharedApplication] 22 | arguments:[[NSProcessInfo processInfo] arguments] 23 | delegate:showInstallerProgress]; 24 | 25 | // Ignore SIGTERM because we are going to catch it ourselves 26 | signal(SIGTERM, SIG_IGN); 27 | 28 | dispatch_source_t sigtermSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGTERM, 0, dispatch_get_main_queue()); 29 | dispatch_source_set_event_handler(sigtermSource, ^{ 30 | [appController cleanupAndExitWithStatus:SIGTERM]; 31 | }); 32 | dispatch_resume(sigtermSource); 33 | 34 | [appController run]; 35 | } 36 | 37 | return EXIT_SUCCESS; 38 | } 39 | -------------------------------------------------------------------------------- /Sparkle/SPUAutomaticUpdateDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUAutomaticUpdateDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/18/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SPUUpdateDriver.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @class SUHost; 15 | @protocol SPUUpdaterDelegate, SPUUserDriver; 16 | 17 | @interface SPUAutomaticUpdateDriver : NSObject 18 | 19 | - (instancetype)initWithHost:(SUHost *)host applicationBundle:(NSBundle *)applicationBundle sparkleBundle:(NSBundle *)sparkleBundle updater:(id)updater userDriver:(id )userDriver updaterDelegate:(nullable id )updaterDelegate; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sparkle/SPUBasicUpdateDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUBasicUpdateDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/18/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SPUUpdateDriver.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @class SUHost, SUAppcastItem; 15 | @protocol SPUUpdaterDelegate; 16 | 17 | @protocol SPUBasicUpdateDriverDelegate 18 | 19 | - (void)basicDriverDidFindUpdateWithAppcastItem:(SUAppcastItem *)appcastItem; 20 | 21 | - (void)basicDriverIsRequestingAbortUpdateWithError:(nullable NSError *)error; 22 | 23 | @optional 24 | 25 | - (void)basicDriverDidFinishLoadingAppcast; 26 | 27 | @end 28 | 29 | @interface SPUBasicUpdateDriver : NSObject 30 | 31 | - (instancetype)initWithHost:(SUHost *)host updater:(id)updater updaterDelegate:(nullable id )updaterDelegate delegate:(id )delegate; 32 | 33 | - (void)prepareCheckForUpdatesWithCompletion:(SPUUpdateDriverCompletion)completionBlock; 34 | 35 | - (void)checkForUpdatesAtAppcastURL:(NSURL *)appcastURL withUserAgent:(NSString *)userAgent httpHeaders:(NSDictionary * _Nullable)httpHeaders inBackground:(BOOL)background includesSkippedUpdates:(BOOL)includesSkippedUpdates; 36 | 37 | - (void)resumeInstallingUpdateWithCompletion:(SPUUpdateDriverCompletion)completionBlock; 38 | 39 | - (void)resumeUpdate:(id)resumableUpdate completion:(SPUUpdateDriverCompletion)completionBlock; 40 | 41 | @property (nullable, nonatomic, readonly) SUAppcastItem *nonDeltaUpdateItem; 42 | 43 | - (void)abortUpdateAndShowNextUpdateImmediately:(BOOL)shouldSignalShowingUpdate resumableUpdate:(id _Nullable)resumableUpdate error:(nullable NSError *)error; 44 | 45 | @end 46 | 47 | NS_ASSUME_NONNULL_END 48 | -------------------------------------------------------------------------------- /Sparkle/SPUDownloadData.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloadData.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "SUExport.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | /*! 20 | * A class for containing downloaded data along with some information about it. 21 | */ 22 | SU_EXPORT @interface SPUDownloadData : NSObject 23 | 24 | - (instancetype)initWithData:(NSData *)data textEncodingName:(NSString * _Nullable)textEncodingName MIMEType:(NSString * _Nullable)MIMEType; 25 | 26 | /*! 27 | * The raw data that was downloaded. 28 | */ 29 | @property (nonatomic, readonly) NSData *data; 30 | 31 | /*! 32 | * The IANA charset encoding name if available. Eg: "utf-8" 33 | */ 34 | @property (nonatomic, readonly, nullable, copy) NSString *textEncodingName; 35 | 36 | /*! 37 | * The MIME type if available. Eg: "text/plain" 38 | */ 39 | @property (nonatomic, readonly, nullable, copy) NSString *MIMEType; 40 | 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /Sparkle/SPUDownloadData.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloadData.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUDownloadData.h" 10 | 11 | 12 | #include "AppKitPrevention.h" 13 | 14 | static NSString *SPUDownloadDataKey = @"SPUDownloadData"; 15 | static NSString *SPUDownloadTextEncodingKey = @"SPUDownloadTextEncoding"; 16 | static NSString *SPUDownloadMIMETypeKey = @"SPUDownloadMIMEType"; 17 | 18 | @implementation SPUDownloadData 19 | 20 | @synthesize data = _data; 21 | @synthesize textEncodingName = _textEncodingName; 22 | @synthesize MIMEType = _MIMEType; 23 | 24 | + (BOOL)supportsSecureCoding 25 | { 26 | return YES; 27 | } 28 | 29 | - (instancetype)initWithData:(NSData *)data textEncodingName:(NSString * _Nullable)textEncodingName MIMEType:(NSString *)MIMEType 30 | { 31 | self = [super init]; 32 | if (self != nil) { 33 | _data = data; 34 | _textEncodingName = textEncodingName; 35 | _MIMEType = MIMEType; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)encodeWithCoder:(NSCoder *)coder 41 | { 42 | [coder encodeObject:self.data forKey:SPUDownloadDataKey]; 43 | 44 | if (self.textEncodingName != nil) { 45 | [coder encodeObject:self.textEncodingName forKey:SPUDownloadTextEncodingKey]; 46 | } 47 | 48 | if (self.MIMEType != nil) { 49 | [coder encodeObject:self.MIMEType forKey:SPUDownloadMIMETypeKey]; 50 | } 51 | } 52 | 53 | - (nullable instancetype)initWithCoder:(NSCoder *)decoder 54 | { 55 | NSData *data = [decoder decodeObjectOfClass:[NSData class] forKey:SPUDownloadDataKey]; 56 | if (data == nil) { 57 | return nil; 58 | } 59 | 60 | NSString *textEncodingName = [decoder decodeObjectOfClass:[NSString class] forKey:SPUDownloadTextEncodingKey]; 61 | 62 | NSString *MIMEType = [decoder decodeObjectOfClass:[NSString class] forKey:SPUDownloadMIMETypeKey]; 63 | 64 | return [self initWithData:data textEncodingName:textEncodingName MIMEType:MIMEType]; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Sparkle/SPUDownloadDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloadDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/15/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUAppcastItem, SUHost, SPUDownloadedUpdate; 14 | 15 | @protocol SPUDownloadDriverDelegate 16 | 17 | - (void)downloadDriverWillBeginDownload; 18 | 19 | - (void)downloadDriverDidReceiveExpectedContentLength:(uint64_t)expectedContentLength; 20 | 21 | - (void)downloadDriverDidReceiveDataOfLength:(uint64_t)length; 22 | 23 | - (void)downloadDriverDidDownloadUpdate:(SPUDownloadedUpdate *)downloadedUpdate; 24 | 25 | - (void)downloadDriverDidFailToDownloadUpdateWithError:(NSError *)error; 26 | 27 | @end 28 | 29 | @interface SPUDownloadDriver : NSObject 30 | 31 | - (instancetype)initWithUpdateItem:(SUAppcastItem *)updateItem host:(SUHost *)host userAgent:(NSString *)userAgent inBackground:(BOOL)background delegate:(id)delegate; 32 | 33 | - (void)downloadUpdate; 34 | 35 | @property (nonatomic, readonly) NSMutableURLRequest *request; 36 | @property (nonatomic, readonly) BOOL inBackground; 37 | 38 | - (void)cleanup; 39 | 40 | @end 41 | 42 | NS_ASSUME_NONNULL_END 43 | -------------------------------------------------------------------------------- /Sparkle/SPUDownloadedUpdate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloadedUpdate.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 1/8/17. 6 | // Copyright © 2017 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SPUResumableUpdate.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface SPUDownloadedUpdate : NSObject 15 | 16 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)updateItem downloadName:(NSString *)downloadName temporaryDirectory:(NSString *)temporaryDirectory; 17 | 18 | @property (nonatomic, copy, readonly) NSString *downloadName; 19 | @property (nonatomic, copy, readonly) NSString *temporaryDirectory; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sparkle/SPUDownloadedUpdate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloadedUpdate.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 1/8/17. 6 | // Copyright © 2017 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUDownloadedUpdate.h" 10 | 11 | 12 | #include "AppKitPrevention.h" 13 | 14 | @implementation SPUDownloadedUpdate 15 | 16 | // If we ever enable auto-synthesize in the future, we'll still need this synthesize 17 | // because the property is declared in a protocol 18 | @synthesize updateItem = _updateItem; 19 | 20 | @synthesize downloadName = _downloadName; 21 | @synthesize temporaryDirectory = _temporaryDirectory; 22 | 23 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)updateItem downloadName:(NSString *)downloadName temporaryDirectory:(NSString *)temporaryDirectory 24 | { 25 | self = [super init]; 26 | if (self != nil) { 27 | _updateItem = updateItem; 28 | _downloadName = [downloadName copy]; 29 | _temporaryDirectory = [temporaryDirectory copy]; 30 | } 31 | return self; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Sparkle/SPUInformationalUpdate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUInformationalUpdate.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 1/8/17. 6 | // Copyright © 2017 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SPUResumableUpdate.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface SPUInformationalUpdate : NSObject 15 | 16 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)updateItem; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Sparkle/SPUInformationalUpdate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUInformationalUpdate.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 1/8/17. 6 | // Copyright © 2017 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUInformationalUpdate.h" 10 | 11 | 12 | #include "AppKitPrevention.h" 13 | 14 | @implementation SPUInformationalUpdate 15 | 16 | // If we ever enable auto-synthesize in the future, we'll still need this synthesize 17 | // because the property is declared in a protocol 18 | @synthesize updateItem = _updateItem; 19 | 20 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)updateItem 21 | { 22 | self = [super init]; 23 | if (self != nil) { 24 | _updateItem = updateItem; 25 | } 26 | return self; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Sparkle/SPUInstallationType.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUInstallationType.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/24/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SPUInstallationType_h 10 | #define SPUInstallationType_h 11 | 12 | #define SPUInstallationTypeApplication @"application" // the default installation type for ordinary application updates 13 | #define SPUInstallationTypeGuidedPackage @"package" // the preferred installation type for package installations 14 | #define SPUInstallationTypeInteractivePackage @"interactive-package" // the deprecated installation type; use guided package instead 15 | 16 | #define SPUInstallationTypeDefault SPUInstallationTypeApplication 17 | #define SPUInstallationTypesArray (@[SPUInstallationTypeApplication, SPUInstallationTypeGuidedPackage, SPUInstallationTypeInteractivePackage]) 18 | #define SPUValidInstallationType(x) ((x != nil) && [SPUInstallationTypesArray containsObject:x]) 19 | 20 | #endif /* SPUInstallationType_h */ 21 | -------------------------------------------------------------------------------- /Sparkle/SPUInstallerDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUInstallerDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/17/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SPUUpdaterDelegate; 14 | @class SUHost, SUAppcastItem, SPUDownloadedUpdate; 15 | 16 | @protocol SPUInstallerDriverDelegate 17 | 18 | - (void)installerDidStartInstalling; 19 | - (void)installerDidExtractUpdateWithProgress:(double)progress; 20 | - (void)installerDidFinishPreparationAndWillInstallImmediately:(BOOL)willInstallImmediately silently:(BOOL)willInstallSilently; 21 | - (void)installerIsSendingAppTerminationSignal; 22 | - (void)installerWillFinishInstallationAndRelaunch:(BOOL)relaunch; 23 | - (void)installerDidFinishInstallationWithAcknowledgement:(void(^)(void))acknowledgement; 24 | 25 | - (void)installerIsRequestingAbortInstallWithError:(nullable NSError *)error; 26 | - (void)installerDidFailToApplyDeltaUpdate; 27 | 28 | @end 29 | 30 | @interface SPUInstallerDriver : NSObject 31 | 32 | - (instancetype)initWithHost:(SUHost *)host applicationBundle:(NSBundle *)applicationBundle sparkleBundle:(NSBundle *)sparkleBundle updater:(id)updater updaterDelegate:(nullable id)updaterDelegate delegate:(nullable id)delegate; 33 | 34 | - (void)resumeInstallingUpdateWithUpdateItem:(SUAppcastItem *)updateItem; 35 | 36 | - (void)checkIfApplicationInstallationRequiresAuthorizationWithReply:(void (^)(BOOL requiresAuthorization))reply; 37 | 38 | - (void)extractDownloadedUpdate:(SPUDownloadedUpdate *)downloadedUpdate silently:(BOOL)silently preventsInstallerInteraction:(BOOL)preventsInstallerInteraction completion:(void (^)(NSError * _Nullable))completionHandler; 39 | 40 | - (void)installWithToolAndRelaunch:(BOOL)relaunch displayingUserInterface:(BOOL)showUI; 41 | 42 | - (void)abortInstall; 43 | 44 | @end 45 | 46 | NS_ASSUME_NONNULL_END 47 | -------------------------------------------------------------------------------- /Sparkle/SPULocalCacheDirectory.h: -------------------------------------------------------------------------------- 1 | // 2 | // SULocalCacheDirectory.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 6/23/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SPULocalCacheDirectory : NSObject 14 | 15 | // Returns a path to a suitable cache directory to create specifically for Sparkle 16 | // Intermediate directories to this path may not exist yet 17 | // This path may depend on the type of running process, 18 | // such that sandboxed vs non-sandboxed processes could yield different paths 19 | // The caller should create a subdirectory from the path that is returned here so they don't have files that 20 | // conflict with other callers. Once that subdirectory name is decided, the caller can remove old items inside it (using +removeOldItemsInDirectory:) 21 | // and then create a unique temporary directory inside it (using +createUniqueDirectoryInDirectory:) 22 | + (NSString *)cachePathForBundleIdentifier:(NSString *)bundleIdentifier; 23 | 24 | // Remove old files inside a directory 25 | // A caller may want to invoke this on a directory they own rather than remove and re-create an entire directory 26 | // This does nothing if the supplied directory does not exist yet 27 | + (void)removeOldItemsInDirectory:(NSString *)directory; 28 | 29 | // Create a unique directory inside a parent directory 30 | // The parent directory doesn't have to exist yet. If it doesn't exist, intermediate directories will be created. 31 | + (NSString * _Nullable)createUniqueDirectoryInDirectory:(NSString *)directory; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Sparkle/SPUProbeInstallStatus.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUProbeInstallStatus.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/20/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SPUInstallationInfo; 14 | 15 | @interface SPUProbeInstallStatus : NSObject 16 | 17 | + (void)probeInstallerInProgressForHostBundleIdentifier:(NSString *)hostBundleIdentifier completion:(void (^)(BOOL))completionHandler; 18 | 19 | // completionHandler may not be sent on main queue 20 | // additionally, it may be possible that the installer is in progress but we get a nil installation info back 21 | + (void)probeInstallerUpdateItemForHostBundleIdentifier:(NSString *)hostBundleIdentifier completion:(void (^)(SPUInstallationInfo * _Nullable))completionHandler; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Sparkle/SPUProbingUpdateDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUProbingUpdateDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/18/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SPUUpdateDriver.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @class SUHost; 15 | @protocol SPUUpdaterDelegate; 16 | 17 | @interface SPUProbingUpdateDriver : NSObject 18 | 19 | - (instancetype)initWithHost:(SUHost *)host updater:(id)updater updaterDelegate:(nullable id )updaterDelegate; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sparkle/SPUResumableUpdate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUResumableUpdate.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/18/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUAppcastItem; 14 | 15 | @protocol SPUResumableUpdate 16 | 17 | @property (nonatomic, readonly) SUAppcastItem *updateItem; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Sparkle/SPUScheduledUpdateDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUScheduledUpdateDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/15/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SPUUpdateDriver.h" 11 | #import "SPUUIBasedUpdateDriver.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @class SUHost; 16 | @protocol SPUUserDriver, SPUUpdaterDelegate; 17 | 18 | @interface SPUScheduledUpdateDriver : NSObject 19 | 20 | - (instancetype)initWithHost:(SUHost *)host applicationBundle:(NSBundle *)applicationBundle sparkleBundle:(NSBundle *)sparkleBundle updater:(id)updater userDriver:(id )userDriver updaterDelegate:(nullable id )updaterDelegate; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Sparkle/SPUSecureCoding.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUSecureCoding.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/24/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | NSData * _Nullable SPUArchiveRootObjectSecurely(id rootObject); 14 | 15 | id _Nullable SPUUnarchiveRootObjectSecurely(NSData *data, Class klass); 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Sparkle/SPUSecureCoding.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUSecureCoding.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/24/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUSecureCoding.h" 10 | #import "SULog.h" 11 | 12 | 13 | #include "AppKitPrevention.h" 14 | 15 | static NSString *SURootObjectArchiveKey = @"SURootObjectArchive"; 16 | 17 | NSData * _Nullable SPUArchiveRootObjectSecurely(id rootObject) 18 | { 19 | NSMutableData *data = [NSMutableData data]; 20 | NSKeyedArchiver *keyedArchiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 21 | keyedArchiver.requiresSecureCoding = YES; 22 | 23 | @try { 24 | [keyedArchiver encodeObject:rootObject forKey:SURootObjectArchiveKey]; 25 | [keyedArchiver finishEncoding]; 26 | return [data copy]; 27 | } @catch (NSException *exception) { 28 | SULog(SULogLevelError, @"Exception while securely archiving object: %@", exception); 29 | [keyedArchiver finishEncoding]; 30 | return nil; 31 | } 32 | } 33 | 34 | id _Nullable SPUUnarchiveRootObjectSecurely(NSData *data, Class klass) 35 | { 36 | NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 37 | unarchiver.requiresSecureCoding = YES; 38 | 39 | @try { 40 | id rootObject = [unarchiver decodeObjectOfClass:klass forKey:SURootObjectArchiveKey]; 41 | [unarchiver finishDecoding]; 42 | return rootObject; 43 | } @catch (NSException *exception) { 44 | SULog(SULogLevelError, @"Exception while securely unarchiving object: %@", exception); 45 | [unarchiver finishDecoding]; 46 | return nil; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sparkle/SPUStandardUserDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUStandardUserDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/14/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Cocoa; 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "SPUUserDriver.h" 16 | #import "SPUStandardUserDriverProtocol.h" 17 | #import "SUExport.h" 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @protocol SPUStandardUserDriverDelegate; 22 | 23 | /*! 24 | Sparkle's standard built-in user driver for updater interactions 25 | */ 26 | SU_EXPORT @interface SPUStandardUserDriver : NSObject 27 | 28 | /*! 29 | Initializes a Sparkle's standard user driver for user update interactions 30 | 31 | @param hostBundle The target bundle of the host that is being updated. 32 | @param delegate The delegate to this user driver. Pass nil if you don't want to provide one. 33 | */ 34 | - (instancetype)initWithHostBundle:(NSBundle *)hostBundle delegate:(nullable id)delegate; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Sparkle/SPUStandardUserDriverDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUStandardUserDriverDelegate.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/3/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "SUExport.h" 16 | 17 | @protocol SUVersionDisplay; 18 | 19 | /*! 20 | A protocol for Sparkle's standard user driver's delegate 21 | 22 | This includes methods related to UI interactions 23 | */ 24 | SU_EXPORT @protocol SPUStandardUserDriverDelegate 25 | 26 | @optional 27 | 28 | /*! 29 | Called before showing a modal alert window, 30 | to give the opportunity to hide attached windows that may get in the way. 31 | */ 32 | - (void)standardUserDriverWillShowModalAlert; 33 | 34 | /*! 35 | Called after showing a modal alert window, 36 | to give the opportunity to hide attached windows that may get in the way. 37 | */ 38 | - (void)standardUserDriverDidShowModalAlert; 39 | 40 | /*! 41 | Returns an object that formats version numbers for display to the user. 42 | If you don't implement this method or return \c nil, 43 | the standard version formatter will be used. 44 | */ 45 | - (_Nullable id )standardUserDriverRequestsVersionDisplayer; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Sparkle/SPUStandardUserDriverProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUStandardUserDriverProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/5/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol SPUStandardUserDriverDelegate; 12 | 13 | /*! 14 | Protocol for Sparkle's standard built-in user driver for updater interactions. 15 | 16 | Other user drivers may wish to implement this protocol. 17 | Note that this protocol does not adopt SUUserDriver because one may want to *only* export properties from this protocol. 18 | */ 19 | @protocol SPUStandardUserDriverProtocol 20 | 21 | /*! 22 | Indicates whether or not an update is in progress as far as the user's perspective is concerned 23 | 24 | A typical application may rely on this property for its check for updates menu item validation 25 | */ 26 | @property (nonatomic, readonly) BOOL canCheckForUpdates; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Sparkle/SPUStatusCompletionResults.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUStatusCompletionResults.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/29/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SPUStatusCompletionResults_h 10 | #define SPUStatusCompletionResults_h 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | 18 | typedef NS_ENUM(NSUInteger, SPUUserInitiatedCheckStatus) { 19 | SPUUserInitiatedCheckDone, 20 | SPUUserInitiatedCheckCanceled 21 | }; 22 | 23 | typedef NS_ENUM(NSUInteger, SPUDownloadUpdateStatus) { 24 | SPUDownloadUpdateDone, 25 | SPUDownloadUpdateCanceled 26 | }; 27 | 28 | typedef NS_ENUM(NSUInteger, SPUInstallUpdateStatus) { 29 | SPUInstallUpdateNow, 30 | SPUInstallAndRelaunchUpdateNow, 31 | SPUDismissUpdateInstallation 32 | }; 33 | 34 | typedef NS_ENUM(NSInteger, SPUUpdateAlertChoice) { 35 | SPUInstallUpdateChoice, 36 | SPUInstallLaterChoice, 37 | SPUSkipThisVersionChoice 38 | }; 39 | 40 | typedef NS_ENUM(NSInteger, SPUInformationalUpdateAlertChoice) { 41 | SPUDismissInformationalNoticeChoice, 42 | SPUSkipThisInformationalVersionChoice 43 | }; 44 | 45 | #endif /* SPUStatusCompletionResults_h */ 46 | -------------------------------------------------------------------------------- /Sparkle/SPUSystemAuthorization.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUSystemAuthorization.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/11/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | BOOL SPUNeedsSystemAuthorizationAccess(NSString *path, NSString *installationType); 14 | 15 | NS_ASSUME_NONNULL_END 16 | -------------------------------------------------------------------------------- /Sparkle/SPUUIBasedUpdateDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUIBasedUpdateDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/18/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SPUUpdateDriver.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @protocol SPUUIBasedUpdateDriverDelegate 15 | 16 | - (void)basicDriverIsRequestingAbortUpdateWithError:(nullable NSError *)error; 17 | - (void)coreDriverIsRequestingAbortUpdateWithError:(nullable NSError *)error; 18 | - (void)uiDriverIsRequestingAbortUpdateWithError:(nullable NSError *)error; 19 | 20 | @optional 21 | 22 | - (void)basicDriverDidFinishLoadingAppcast; 23 | 24 | @end 25 | 26 | @class SUHost; 27 | @protocol SPUUserDriver, SPUUpdaterDelegate; 28 | 29 | @interface SPUUIBasedUpdateDriver : NSObject 30 | 31 | - (instancetype)initWithHost:(SUHost *)host applicationBundle:(NSBundle *)applicationBundle sparkleBundle:(NSBundle *)sparkleBundle updater:(id)updater userDriver:(id )userDriver userInitiated:(BOOL)userInitiated updaterDelegate:(nullable id )updaterDelegate delegate:(id)delegate; 32 | 33 | - (void)prepareCheckForUpdatesWithCompletion:(SPUUpdateDriverCompletion)completionBlock; 34 | 35 | - (void)preflightForUpdatePermissionPreventingInstallerInteraction:(BOOL)preventsInstallerInteraction reply:(void (^)(NSError * _Nullable))reply; 36 | 37 | - (void)checkForUpdatesAtAppcastURL:(NSURL *)appcastURL withUserAgent:(NSString *)userAgent httpHeaders:(NSDictionary * _Nullable)httpHeaders inBackground:(BOOL)background includesSkippedUpdates:(BOOL)includesSkippedUpdates; 38 | 39 | - (void)resumeInstallingUpdateWithCompletion:(SPUUpdateDriverCompletion)completionBlock; 40 | 41 | - (void)resumeUpdate:(id)resumableUpdate completion:(SPUUpdateDriverCompletion)completionBlock; 42 | 43 | - (void)abortUpdateWithError:(nullable NSError *)error; 44 | 45 | @end 46 | 47 | NS_ASSUME_NONNULL_END 48 | -------------------------------------------------------------------------------- /Sparkle/SPUURLDownload.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUURLDownload.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 5/13/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SPUDownloadData; 14 | 15 | // From the completion block, either data or error can be nil, but not both 16 | // The completion block returns on the main queue 17 | void SPUDownloadURLWithRequest(NSURLRequest * request, void (^completionBlock)(SPUDownloadData * _Nullable download, NSError * _Nullable error)); 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Sparkle/SPUURLRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUURLRequest.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 5/19/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | // A class that wraps NSURLRequest and implements NSSecureCoding 14 | // This class exists because NSURLRequest did not support NSSecureCoding in macOS 10.8 15 | // I have not verified if NSURLRequest in 10.9 implements NSSecureCoding or not 16 | @interface SPUURLRequest : NSObject 17 | 18 | // Creates a new URL request 19 | // Only these properties are currently tracked: 20 | // * URL 21 | // * Cache policy 22 | // * Timeout interval 23 | // * HTTP header fields 24 | // * networkServiceType 25 | + (instancetype)URLRequestWithRequest:(NSURLRequest *)request; 26 | 27 | @property (nonatomic, readonly) NSURLRequest *request; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /Sparkle/SPUUpdateDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdateDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/15/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | NS_ASSUME_NONNULL_BEGIN 10 | 11 | @protocol SPUResumableUpdate; 12 | 13 | typedef void (^SPUUpdateDriverCompletion)(BOOL shouldShowUpdateImmediately, id _Nullable resumableUpdate); 14 | 15 | // This protocol describes an update driver that drives updates 16 | // An update driver may have multiple levels of other controller components (eg: basic update driver, core based update driver, ui based update driver, appcast driver, etc) 17 | // The update driver and the components the driver has communicates via parameter passing and delegation.. 18 | // The old Sparkle architecture communicated via subclassing and method overriding, but this lead to bugs due to high coupling, and complexity of not being aware of methods being executed. 19 | // The newer architecture is still complex but should be more reliable to maintain and extend. 20 | @protocol SPUUpdateDriver 21 | 22 | - (void)checkForUpdatesAtAppcastURL:(NSURL *)appcastURL withUserAgent:(NSString *)userAgent httpHeaders:(NSDictionary * _Nullable)httpHeaders preventingInstallerInteraction:(BOOL)preventsInstallerInteraction completion:(SPUUpdateDriverCompletion)completionBlock; 23 | 24 | - (void)resumeInstallingUpdateWithCompletion:(SPUUpdateDriverCompletion)completionBlock; 25 | 26 | - (void)resumeUpdate:(id)resumableUpdate completion:(SPUUpdateDriverCompletion)completionBlock; 27 | 28 | // A likely implementation of -abortUpdate is invoking -abortUpdateWithError: by passing nil 29 | - (void)abortUpdate; 30 | 31 | // This should be invoked on the update driver to finish the update driver's work 32 | - (void)abortUpdateWithError:(NSError * _Nullable)error; 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /Sparkle/SPUUpdatePermissionRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdatePermissionRequest.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/14/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "SUExport.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | /*! 20 | This class represents information needed to make a permission request for checking updates. 21 | */ 22 | SU_EXPORT @interface SPUUpdatePermissionRequest : NSObject 23 | 24 | /*! 25 | Initializes a new update permission request instance. 26 | 27 | @param systemProfile The system profile information. 28 | */ 29 | - (instancetype)initWithSystemProfile:(NSArray *> *)systemProfile; 30 | 31 | /*! 32 | A read-only property for the user's system profile. 33 | */ 34 | @property (nonatomic, readonly) NSArray *> *systemProfile; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Sparkle/SPUUpdatePermissionRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdatePermissionRequest.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/14/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUUpdatePermissionRequest.h" 10 | 11 | 12 | #include "AppKitPrevention.h" 13 | 14 | static NSString *SPUUpdatePermissionRequestSystemProfileKey = @"SPUUpdatePermissionRequestSystemProfile"; 15 | 16 | @implementation SPUUpdatePermissionRequest 17 | 18 | @synthesize systemProfile = _systemProfile; 19 | 20 | + (BOOL)supportsSecureCoding 21 | { 22 | return YES; 23 | } 24 | 25 | - (instancetype)initWithCoder:(NSCoder *)decoder 26 | { 27 | NSArray *> *systemProfile = [decoder decodeObjectOfClasses:[NSSet setWithArray:@[[NSArray class], [NSDictionary class], [NSString class]]] forKey:SPUUpdatePermissionRequestSystemProfileKey]; 28 | if (systemProfile == nil) { 29 | return nil; 30 | } 31 | 32 | return [self initWithSystemProfile:systemProfile]; 33 | } 34 | 35 | - (void)encodeWithCoder:(NSCoder *)encoder 36 | { 37 | [encoder encodeObject:self.systemProfile forKey:SPUUpdatePermissionRequestSystemProfileKey]; 38 | } 39 | 40 | - (instancetype)initWithSystemProfile:(NSArray *> *)systemProfile 41 | { 42 | self = [super init]; 43 | if (self != nil) { 44 | _systemProfile = systemProfile; 45 | } 46 | return self; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Sparkle/SPUUpdaterCycle.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdaterCycle.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 6/11/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SPUUpdaterCycleDelegate 14 | 15 | - (void)resetUpdateCycle; 16 | 17 | @end 18 | 19 | // This notifies the updater for (re-)starting and canceling update cycles 20 | // This class is used so that an updater instance isn't kept alive by a pending update cycle 21 | @interface SPUUpdaterCycle : NSObject 22 | 23 | // This delegate is weakly referenced 24 | - (instancetype)initWithDelegate:(id)delegate; 25 | 26 | - (void)resetUpdateCycleAfterDelay; 27 | 28 | - (void)cancelNextUpdateCycle; 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /Sparkle/SPUUpdaterCycle.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdaterCycle.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 6/11/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUUpdaterCycle.h" 10 | 11 | 12 | #include "AppKitPrevention.h" 13 | 14 | @interface SPUUpdaterCycle () 15 | 16 | @property (nonatomic, weak, readonly) id delegate; 17 | 18 | @end 19 | 20 | @implementation SPUUpdaterCycle 21 | 22 | @synthesize delegate = _delegate; 23 | 24 | - (instancetype)initWithDelegate:(id)delegate 25 | { 26 | self = [super init]; 27 | if (self != nil) { 28 | _delegate = delegate; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)resetUpdateCycle 34 | { 35 | [self.delegate resetUpdateCycle]; 36 | } 37 | 38 | - (void)resetUpdateCycleAfterDelay 39 | { 40 | [self performSelector:@selector(resetUpdateCycle) withObject:nil afterDelay:1]; 41 | } 42 | 43 | - (void)cancelNextUpdateCycle 44 | { 45 | [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Sparkle/SPUUpdaterSettings.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdaterSettings.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/27/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "SUExport.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | /*! 20 | This class can be used for reading certain updater settings. 21 | 22 | It retrieves the settings by first looking into the host's user defaults. 23 | If the setting is not found in there, then the host's Info.plist file is looked at. 24 | */ 25 | SU_EXPORT @interface SPUUpdaterSettings : NSObject 26 | 27 | - (instancetype)initWithHostBundle:(NSBundle *)hostBundle; 28 | 29 | /*! 30 | * Indicates whether or not automatic update checks are enabled. 31 | */ 32 | @property (readonly, nonatomic) BOOL automaticallyChecksForUpdates; 33 | 34 | /*! 35 | * The regular update check interval. 36 | */ 37 | @property (readonly, nonatomic) NSTimeInterval updateCheckInterval; 38 | 39 | /*! 40 | * Indicates whether or not automatically downloading updates is allowed to be turned on by the user. 41 | */ 42 | @property (readonly, nonatomic) BOOL allowsAutomaticUpdates; 43 | 44 | /*! 45 | * Indicates whether or not automatically downloading updates is enabled by the user or developer. 46 | * 47 | * Note this does not indicate whether or not automatic downloading of updates is allowable. 48 | * See `-allowsAutomaticUpdates` property for that. 49 | */ 50 | @property (readonly, nonatomic) BOOL automaticallyDownloadsUpdates; 51 | 52 | /*! 53 | * Indicates whether or not anonymous system profile information is sent when checking for updates. 54 | */ 55 | @property (readonly, nonatomic) BOOL sendsSystemProfile; 56 | 57 | @end 58 | 59 | NS_ASSUME_NONNULL_END 60 | -------------------------------------------------------------------------------- /Sparkle/SPUUpdaterSettings.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdaterSettings.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/27/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUUpdaterSettings.h" 10 | #import "SUHost.h" 11 | #import "SUConstants.h" 12 | 13 | 14 | #include "AppKitPrevention.h" 15 | 16 | @interface SPUUpdaterSettings () 17 | 18 | @property (nonatomic, readonly) SUHost *host; 19 | 20 | @end 21 | 22 | @implementation SPUUpdaterSettings 23 | 24 | @synthesize host = _host; 25 | 26 | - (instancetype)initWithHostBundle:(NSBundle *)hostBundle 27 | { 28 | self = [super init]; 29 | if (self != nil) { 30 | _host = [[SUHost alloc] initWithBundle:hostBundle]; 31 | } 32 | return self; 33 | } 34 | 35 | - (BOOL)automaticallyChecksForUpdates 36 | { 37 | // Don't automatically update when the check interval is 0, to be compatible with 1.1 settings. 38 | if ((NSInteger)[self updateCheckInterval] == 0) { 39 | return NO; 40 | } 41 | return [self.host boolForKey:SUEnableAutomaticChecksKey]; 42 | } 43 | 44 | - (NSTimeInterval)updateCheckInterval 45 | { 46 | // Find the stored check interval. User defaults override Info.plist. 47 | NSNumber *intervalValue = [self.host objectForKey:SUScheduledCheckIntervalKey]; 48 | if (intervalValue) 49 | return [intervalValue doubleValue]; 50 | else 51 | return SUDefaultUpdateCheckInterval; 52 | } 53 | 54 | // For allowing automatic downloaded updates to be turned on or off 55 | - (BOOL)allowsAutomaticUpdates 56 | { 57 | NSNumber *developerAllowsAutomaticUpdates = [self.host objectForInfoDictionaryKey:SUAllowsAutomaticUpdatesKey]; 58 | return (developerAllowsAutomaticUpdates == nil || developerAllowsAutomaticUpdates.boolValue); 59 | } 60 | 61 | - (BOOL)automaticallyDownloadsUpdates 62 | { 63 | return [self.host boolForUserDefaultsKey:SUAutomaticallyUpdateKey]; 64 | } 65 | 66 | - (BOOL)sendsSystemProfile 67 | { 68 | return [self.host boolForKey:SUSendProfileInfoKey]; 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Sparkle/SPUUpdaterTimer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdaterTimer.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/12/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SPUUpdaterTimerDelegate 14 | 15 | - (void)updaterTimerDidFire; 16 | 17 | @end 18 | 19 | // This notifies the updater for scheduled update checks 20 | // This class is used so that an updater instance isn't kept alive by a scheduled update check 21 | @interface SPUUpdaterTimer : NSObject 22 | 23 | - (instancetype)initWithDelegate:(id)delegate; 24 | 25 | - (void)startAndFireAfterDelay:(NSTimeInterval)delay; 26 | 27 | - (void)invalidate; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /Sparkle/SPUUpdaterTimer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdaterTimer.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/12/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUUpdaterTimer.h" 10 | 11 | 12 | #include "AppKitPrevention.h" 13 | 14 | @interface SPUUpdaterTimer () 15 | 16 | @property (nonatomic, readonly, weak) id delegate; 17 | @property (nonatomic, nullable) NSTimer *timer; 18 | 19 | @end 20 | 21 | @implementation SPUUpdaterTimer 22 | 23 | @synthesize delegate = _delegate; 24 | @synthesize timer = _timer; 25 | 26 | - (instancetype)initWithDelegate:(id)delegate 27 | { 28 | self = [super init]; 29 | if (self != nil) { 30 | _delegate = delegate; 31 | } 32 | return self; 33 | } 34 | 35 | - (void)startAndFireAfterDelay:(NSTimeInterval)delay 36 | { 37 | assert(self.timer == nil); 38 | self.timer = [NSTimer scheduledTimerWithTimeInterval:delay target:self selector:@selector(fire:) userInfo:nil repeats:NO]; 39 | } 40 | 41 | - (void)fire:(NSTimer *)__unused timer 42 | { 43 | [self.delegate updaterTimerDidFire]; 44 | self.timer = nil; 45 | } 46 | 47 | - (void)invalidate 48 | { 49 | [self.timer invalidate]; 50 | self.timer = nil; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Sparkle/SPUUserDriverCoreComponent.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUserDriverCoreComponent.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/4/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "SPUStatusCompletionResults.h" 16 | #import "SUExport.h" 17 | 18 | @protocol SPUStandardUserDriverDelegate; 19 | 20 | SU_EXPORT @interface SPUUserDriverCoreComponent : NSObject 21 | 22 | - (void)showCanCheckForUpdates:(BOOL)canCheckForUpdates; 23 | 24 | @property (nonatomic, readonly) BOOL canCheckForUpdates; 25 | 26 | - (void)registerInstallUpdateHandler:(void (^)(SPUInstallUpdateStatus))installUpdateHandler; 27 | - (void)installUpdateWithChoice:(SPUInstallUpdateStatus)choice; 28 | 29 | - (void)registerUpdateCheckStatusHandler:(void (^)(SPUUserInitiatedCheckStatus))updateCheckStatusCompletion; 30 | - (void)cancelUpdateCheckStatus; 31 | - (void)completeUpdateCheckStatus; 32 | 33 | - (void)registerDownloadStatusHandler:(void (^)(SPUDownloadUpdateStatus))downloadUpdateStatusCompletion; 34 | - (void)cancelDownloadStatus; 35 | - (void)completeDownloadStatus; 36 | 37 | - (void)registerAcknowledgement:(void (^)(void))acknowledgement; 38 | - (void)acceptAcknowledgement; 39 | 40 | - (void)dismissUpdateInstallation; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Sparkle/SPUUserInitiatedUpdateDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUserInitiatedUpdateDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/18/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SPUUpdateDriver.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @class SUHost; 15 | @protocol SPUUpdaterDelegate, SPUUserDriver; 16 | 17 | @interface SPUUserInitiatedUpdateDriver : NSObject 18 | 19 | - (instancetype)initWithHost:(SUHost *)host applicationBundle:(NSBundle *)applicationBundle sparkleBundle:(NSBundle *)sparkleBundle updater:(id)updater userDriver:(id )userDriver updaterDelegate:(nullable id )updaterDelegate; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sparkle/SPUXPCServiceInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUXPCServiceInfo.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/17/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | BOOL SPUXPCServiceExists(NSString *bundleName); 14 | 15 | NSBundle * _Nullable SPUXPCServiceBundle(NSString *bundleName); 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Sparkle/SPUXPCServiceInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // SUXPCServiceInfo.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/17/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUXPCServiceInfo.h" 10 | 11 | 12 | #include "AppKitPrevention.h" 13 | 14 | BOOL SPUXPCServiceExists(NSString *bundleName) 15 | { 16 | NSBundle *xpcBundle = SPUXPCServiceBundle(bundleName); 17 | if (xpcBundle == nil) { 18 | return NO; 19 | } 20 | 21 | NSString *version = [xpcBundle objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleVersionKey]; 22 | NSString *projectVersion = @""CURRENT_PROJECT_VERSION; 23 | if (version == nil || ![version isEqualToString:projectVersion]) { 24 | // Use NSLog instead of SULog here because this is a developer configuration error... 25 | NSLog(@"Error: XPC Version mismatch. Framework version is %@ but XPC Service (%@) version is %@", projectVersion, xpcBundle.bundlePath, version); 26 | NSLog(@"Not using XPC Service..."); 27 | return NO; 28 | } 29 | 30 | return YES; 31 | } 32 | 33 | NSBundle * _Nullable SPUXPCServiceBundle(NSString *bundleName) 34 | { 35 | NSBundle *mainBundle = [NSBundle mainBundle]; 36 | NSURL *executableURL = mainBundle.executableURL; 37 | if (executableURL == nil) { 38 | return nil; 39 | } 40 | 41 | NSURL *xpcBundleURL = [[[executableURL.URLByDeletingLastPathComponent.URLByDeletingLastPathComponent URLByAppendingPathComponent:@"XPCServices"] URLByAppendingPathComponent:bundleName] URLByAppendingPathExtension:@"xpc"]; 42 | 43 | return [NSBundle bundleWithURL:xpcBundleURL]; 44 | } 45 | -------------------------------------------------------------------------------- /Sparkle/SUAppcast.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcast.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCAST_H 10 | #define SUAPPCAST_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @class SUAppcastItem; 22 | SU_EXPORT @interface SUAppcast : NSObject 23 | 24 | @property (copy, nullable) NSString *userAgentString; 25 | 26 | #if __has_feature(objc_generics) 27 | @property (copy, nullable) NSDictionary *httpHeaders; 28 | #else 29 | @property (copy, nullable) NSDictionary *httpHeaders; 30 | #endif 31 | 32 | - (void)fetchAppcastFromURL:(NSURL *)url inBackground:(BOOL)bg completionBlock:(void (^)(NSError *_Nullable))err; 33 | - (SUAppcast *)copyWithoutDeltaUpdates; 34 | 35 | @property (readonly, copy, nullable) NSArray *items; 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /Sparkle/SUAppcastDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcastDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/17/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUAppcastItem, SUHost, SUAppcast; 14 | @protocol SPUUpdaterDelegate; 15 | 16 | @protocol SUAppcastDriverDelegate 17 | 18 | - (void)didFailToFetchAppcastWithError:(NSError *)error; 19 | - (void)didFinishLoadingAppcast:(SUAppcast *)appcast; 20 | - (void)didFindValidUpdateWithAppcastItem:(SUAppcastItem *)appcastItem; 21 | - (void)didNotFindUpdate; 22 | 23 | @end 24 | 25 | @interface SUAppcastDriver : NSObject 26 | 27 | - (instancetype)initWithHost:(SUHost *)host updater:(id)updater updaterDelegate:(nullable id )updaterDelegate delegate:(nullable id )delegate; 28 | 29 | - (void)loadAppcastFromURL:(NSURL *)appcastURL userAgent:(NSString *)userAgent httpHeaders:(NSDictionary * _Nullable)httpHeaders inBackground:(BOOL)background includesSkippedUpdates:(BOOL)includesSkippedUpdates; 30 | 31 | @property (nullable, nonatomic, readonly) SUAppcastItem *nonDeltaUpdateItem; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Sparkle/SUAppcastItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcastItem.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCASTITEM_H 10 | #define SUAPPCASTITEM_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | SU_EXPORT @interface SUAppcastItem : NSObject 20 | @property (copy, readonly) NSString *title; 21 | @property (copy, readonly) NSString *dateString; 22 | @property (copy, readonly) NSString *itemDescription; 23 | @property (strong, readonly) NSURL *releaseNotesURL; 24 | @property (copy, readonly) NSString *DSASignature; 25 | @property (copy, readonly) NSString *minimumSystemVersion; 26 | @property (copy, readonly) NSString *maximumSystemVersion; 27 | @property (strong, readonly) NSURL *fileURL; 28 | @property (nonatomic, readonly) uint64_t contentLength; 29 | @property (copy, readonly) NSString *versionString; 30 | @property (copy, readonly) NSString *displayVersionString; 31 | @property (copy, readonly) NSDictionary *deltaUpdates; 32 | @property (strong, readonly) NSURL *infoURL; 33 | @property (nonatomic, copy, readonly) NSString *installationType; 34 | 35 | // Initializes with data from a dictionary provided by the RSS class. 36 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 37 | - (instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString **)error; 38 | 39 | @property (getter=isDeltaUpdate, readonly) BOOL deltaUpdate; 40 | @property (getter=isCriticalUpdate, readonly) BOOL criticalUpdate; 41 | @property (getter=isInformationOnlyUpdate, readonly) BOOL informationOnlyUpdate; 42 | 43 | // Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. 44 | @property (readonly, copy) NSDictionary *propertiesDictionary; 45 | 46 | - (NSURL *)infoURL; 47 | 48 | @end 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /Sparkle/SUApplicationInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUApplicationInfo.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/28/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUHost; 14 | 15 | @interface SUApplicationInfo : NSObject 16 | 17 | + (BOOL)isBackgroundApplication:(NSApplication *)application; 18 | 19 | + (NSImage *)bestIconForHost:(SUHost *)host; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sparkle/SUApplicationInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // SUApplicationInfo.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/28/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SUApplicationInfo.h" 10 | #import "SUBundleIcon.h" 11 | #import "SUHost.h" 12 | 13 | @implementation SUApplicationInfo 14 | 15 | + (BOOL)isBackgroundApplication:(NSApplication *)application 16 | { 17 | return (application.activationPolicy == NSApplicationActivationPolicyAccessory); 18 | } 19 | 20 | + (NSImage *)bestIconForHost:(SUHost *)host 21 | { 22 | NSURL *iconURL = [SUBundleIcon iconURLForHost:host]; 23 | 24 | NSImage *icon = (iconURL == nil) ? nil : [[NSImage alloc] initWithContentsOfURL:iconURL]; 25 | // Use a default icon if none is defined. 26 | if (!icon) { 27 | // this asumption may not be correct (eg. even though we're not the main bundle, it could be still be a regular app) 28 | // but still better than nothing if no icon was included 29 | BOOL isMainBundle = [host.bundle isEqualTo:[NSBundle mainBundle]]; 30 | 31 | NSString *fileType = isMainBundle ? (__bridge NSString *)kUTTypeApplication : (__bridge NSString *)kUTTypeBundle; 32 | icon = [[NSWorkspace sharedWorkspace] iconForFileType:fileType]; 33 | } 34 | return icon; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Sparkle/SUBundleIcon.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUBundleIcon.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/24/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUHost; 14 | 15 | @interface SUBundleIcon : NSObject 16 | 17 | + (NSURL * _Nullable)iconURLForHost:(SUHost *)host; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Sparkle/SUBundleIcon.m: -------------------------------------------------------------------------------- 1 | // 2 | // SUBundleIcon.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/24/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SUBundleIcon.h" 10 | #import "SUHost.h" 11 | 12 | 13 | #include "AppKitPrevention.h" 14 | 15 | @implementation SUBundleIcon 16 | 17 | // Note: To obtain the most current bundle icon file from the Info dictionary, this should take a SUHost, not a NSBundle 18 | + (NSURL *)iconURLForHost:(SUHost *)host 19 | { 20 | NSString *resource = [host objectForInfoDictionaryKey:@"CFBundleIconFile"]; 21 | if (resource == nil || ![resource isKindOfClass:[NSString class]]) { 22 | return nil; 23 | } 24 | 25 | NSURL *iconURL = [host.bundle URLForResource:resource withExtension:@"icns"]; 26 | 27 | // The resource could already be containing the path extension, so try again without the extra extension 28 | if (iconURL == nil) { 29 | iconURL = [host.bundle URLForResource:resource withExtension:nil]; 30 | } 31 | return iconURL; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Sparkle/SUErrors.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUErrors.h 3 | // Sparkle 4 | // 5 | // Created by C.W. Betts on 10/13/14. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUERRORS_H 10 | #define SUERRORS_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | /** 20 | * Error domain used by Sparkle 21 | */ 22 | SU_EXPORT extern NSString *const SUSparkleErrorDomain; 23 | 24 | typedef NS_ENUM(OSStatus, SUError) { 25 | // Configuration phase errors 26 | SUNoPublicDSAFoundError = 0001, 27 | SUInsufficientSigningError = 0002, 28 | SUInsecureFeedURLError = 0003, 29 | SUInvalidFeedURLError = 0004, 30 | SUInvalidUpdaterError = 0005, 31 | SUInvalidHostBundleIdentifierError = 0006, 32 | SUInvalidHostVersionError = 0007, 33 | 34 | // Appcast phase errors. 35 | SUAppcastParseError = 1000, 36 | SUNoUpdateError = 1001, 37 | SUAppcastError = 1002, 38 | SURunningFromDiskImageError = 1003, 39 | SUResumeAppcastError = 1004, 40 | 41 | // Download phase errors. 42 | SUTemporaryDirectoryError = 2000, 43 | SUDownloadError = 2001, 44 | 45 | // Extraction phase errors. 46 | SUUnarchivingError = 3000, 47 | SUSignatureError = 3001, 48 | 49 | // Installation phase errors. 50 | SUFileCopyFailure = 4000, 51 | SUAuthenticationFailure = 4001, 52 | SUMissingUpdateError = 4002, 53 | SUMissingInstallerToolError = 4003, 54 | SURelaunchError = 4004, 55 | SUInstallationError = 4005, 56 | SUDowngradeError = 4006, 57 | SUInstallationCanceledError = 4007, 58 | SUInstallationAuthorizeLaterError = 4008, 59 | SUNotAllowedInteractionError = 4009 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /Sparkle/SUExport.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUExport.h 3 | // Sparkle 4 | // 5 | // Created by Jake Petroules on 2014-08-23. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUEXPORT_H 10 | #define SUEXPORT_H 11 | 12 | #ifdef BUILDING_SPARKLE 13 | #define SU_EXPORT __attribute__((visibility("default"))) 14 | #else 15 | #define SU_EXPORT 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Sparkle/SUHost.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUHost.h 3 | // Sparkle 4 | // 5 | // Copyright 2008 Andy Matuschak. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface SUHost : NSObject 11 | 12 | @property (strong, readonly) NSBundle *bundle; 13 | 14 | - (instancetype)initWithBundle:(NSBundle *)aBundle; 15 | 16 | @property (readonly, copy) NSString *bundlePath; 17 | @property (readonly, copy) NSString *name; 18 | @property (readonly, copy) NSString *version; 19 | @property (readonly, nonatomic) BOOL validVersion; 20 | @property (readonly, copy) NSString *displayVersion; 21 | @property (getter=isRunningOnReadOnlyVolume, readonly) BOOL runningOnReadOnlyVolume; 22 | @property (readonly, copy) NSString *publicDSAKey; 23 | @property (readonly, nonatomic, copy) NSString *publicDSAKeyFileKey; 24 | 25 | - (id)objectForInfoDictionaryKey:(NSString *)key; 26 | - (BOOL)boolForInfoDictionaryKey:(NSString *)key; 27 | - (id)objectForUserDefaultsKey:(NSString *)defaultName; 28 | - (void)setObject:(id)value forUserDefaultsKey:(NSString *)defaultName; 29 | - (BOOL)boolForUserDefaultsKey:(NSString *)defaultName; 30 | - (void)setBool:(BOOL)value forUserDefaultsKey:(NSString *)defaultName; 31 | - (id)objectForKey:(NSString *)key; 32 | - (BOOL)boolForKey:(NSString *)key; 33 | @end 34 | -------------------------------------------------------------------------------- /Sparkle/SUInstallerProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 12/26/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SUInstallerProtocol 14 | 15 | // Any installation work can be done prior to user application being terminated and relaunched 16 | // Currently this is invoked after the user application is terminated, but this may change in the future. 17 | // No UI should occur during this stage (i.e, do not show package installer apps, etc..) 18 | // Should be able to be called from non-main thread 19 | - (BOOL)performInitialInstallation:(NSError **)error; 20 | 21 | // Any installation work after the user application has been terminated. This is where the final installation work can be done. 22 | // After this stage is done, the user application may be relaunched. 23 | // Should be able to be called from non-main thread 24 | - (BOOL)performFinalInstallation:(NSError **)error; 25 | 26 | // Indicates whether or not this installer can install the update silently in the background, without hindering the user 27 | // Should be thread safe 28 | - (BOOL)canInstallSilently; 29 | 30 | // The destination and installation path of the bundle being updated 31 | // Should be thread safe 32 | - (NSString *)installationPath; 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /Sparkle/SULocalizations.h: -------------------------------------------------------------------------------- 1 | // 2 | // SULocalizations.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/28/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SULocalizations_h 10 | #define SULocalizations_h 11 | 12 | #import "SUConstants.h" 13 | 14 | #define SULocalizedString(key, comment) NSLocalizedStringFromTableInBundle(key, @"Sparkle", (NSBundle * _Nonnull)([NSBundle bundleWithIdentifier:SUBundleIdentifier] ? [NSBundle bundleWithIdentifier:SUBundleIdentifier] : [NSBundle mainBundle]), comment) 15 | 16 | #endif /* SULocalizations_h */ 17 | -------------------------------------------------------------------------------- /Sparkle/SULog.h: -------------------------------------------------------------------------------- 1 | // 2 | // SULog.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 5/18/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SULOG_H 10 | #define SULOG_H 11 | 12 | #include 13 | 14 | typedef NS_ENUM(uint8_t, SULogLevel) { 15 | // This level is for information that *might* result a failure 16 | // For now until other levels are added, this may serve as a level for other information as well 17 | SULogLevelDefault, 18 | // This level is for errors that occurred 19 | SULogLevelError 20 | }; 21 | 22 | // Logging utlity function that is thread-safe 23 | // On 10.12 or later this uses os_log 24 | // Otherwise on older systems this uses ASL 25 | // For debugging command line tools, you may have to use Console.app or log(1) to view log messages 26 | // Try to keep log messages as compact/short as possible 27 | void SULog(SULogLevel level, NSString *format, ...) NS_FORMAT_FUNCTION(2, 3); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /Sparkle/SUOperatingSystem.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUOperatingSystem.h 3 | // Sparkle 4 | // 5 | // Copyright © 2015 Sparkle Project. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | #if __MAC_OS_X_VERSION_MAX_ALLOWED < 101000 11 | typedef struct { 12 | NSInteger majorVersion; 13 | NSInteger minorVersion; 14 | NSInteger patchVersion; 15 | } NSOperatingSystemVersion; 16 | #endif 17 | 18 | @interface SUOperatingSystem : NSObject 19 | 20 | + (NSOperatingSystemVersion)operatingSystemVersion; 21 | + (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version; 22 | + (NSString *)systemVersionString; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Sparkle/SUStandardVersionComparator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStandardVersionComparator.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUSTANDARDVERSIONCOMPARATOR_H 10 | #define SUSTANDARDVERSIONCOMPARATOR_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | #import "SUVersionComparisonProtocol.h" 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | 22 | /*! 23 | Sparkle's default version comparator. 24 | 25 | This comparator is adapted from MacPAD, by Kevin Ballard. 26 | It's "dumb" in that it does essentially string comparison, 27 | in components split by character type. 28 | */ 29 | SU_EXPORT @interface SUStandardVersionComparator : NSObject 30 | 31 | /*! 32 | Initializes a new instance of the standard version comparator. 33 | */ 34 | - (instancetype)init; 35 | 36 | /*! 37 | Returns a singleton instance of the comparator. 38 | 39 | It is usually preferred to alloc/init new a comparator instead. 40 | */ 41 | + (SUStandardVersionComparator *)defaultComparator; 42 | 43 | /*! 44 | Compares version strings through textual analysis. 45 | 46 | See the implementation for more details. 47 | */ 48 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; 49 | @end 50 | 51 | NS_ASSUME_NONNULL_END 52 | #endif 53 | -------------------------------------------------------------------------------- /Sparkle/SUStatusController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStatusController.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/14/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUSTATUSCONTROLLER_H 10 | #define SUSTATUSCONTROLLER_H 11 | 12 | #import 13 | 14 | @class SUHost; 15 | @interface SUStatusController : NSWindowController 16 | @property (weak) IBOutlet NSButton *actionButton; 17 | @property (weak) IBOutlet NSProgressIndicator *progressBar; 18 | @property (weak) IBOutlet NSTextField *statusTextField; 19 | 20 | @property (copy) NSString *statusText; 21 | @property double progressValue; 22 | @property (nonatomic) double maxProgressValue; 23 | @property (getter=isButtonEnabled) BOOL buttonEnabled; 24 | 25 | - (instancetype)initWithHost:(SUHost *)host; 26 | 27 | // Pass 0 for the max progress value to get an indeterminate progress bar. 28 | // Pass nil for the status text to not show it. 29 | - (void)beginActionWithTitle:(NSString *)title maxProgressValue:(double)maxProgressValue statusText:(NSString *)statusText; 30 | 31 | // If isDefault is YES, the button's key equivalent will be \r. 32 | - (void)setButtonTitle:(NSString *)buttonTitle target:(id)target action:(SEL)action isDefault:(BOOL)isDefault; 33 | 34 | @end 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /Sparkle/SUSystemProfiler.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUSystemProfiler.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/22/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUSYSTEMPROFILER_H 10 | #define SUSYSTEMPROFILER_H 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @class SUHost; 17 | @interface SUSystemProfiler : NSObject 18 | 19 | + (NSArray *> *)systemProfileArrayForHost:(SUHost *)host; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | #endif 25 | -------------------------------------------------------------------------------- /Sparkle/SUSystemUpdateInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUSystemUpdateInfo.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 12/23/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUHost; 14 | 15 | @interface SUSystemUpdateInfo : NSObject 16 | 17 | + (BOOL)systemAllowsAutomaticUpdatesForHost:(SUHost *)host; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Sparkle/SUTouchBarButtonGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUTouchBarButtonGroup.h 3 | // Sparkle 4 | // 5 | // Created by Yuxin Wang on 05/01/2017. 6 | // Copyright © 2017 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SUTouchBarButtonGroup : NSViewController 14 | 15 | @property (nonatomic, readonly, copy) NSArray *buttons; 16 | 17 | - (instancetype)initByReferencingButtons:(NSArray *)buttons; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Sparkle/SUUpdateAlert.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdateAlert.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUUPDATEALERT_H 10 | #define SUUPDATEALERT_H 11 | 12 | #import 13 | #import "SUVersionDisplayProtocol.h" 14 | #import "SPUStatusCompletionResults.h" 15 | 16 | @protocol SUUpdateAlertDelegate; 17 | 18 | @class SUAppcastItem, SPUDownloadData, SUHost; 19 | @interface SUUpdateAlert : NSWindowController 20 | 21 | @property (nonatomic, weak, readonly) id versionDisplayer; 22 | 23 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)item alreadyDownloaded:(BOOL)alreadyDownloaded host:(SUHost *)aHost versionDisplayer:(id )aVersionDisplayer completionBlock:(void (^)(SPUUpdateAlertChoice))block; 24 | 25 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)item host:(SUHost *)aHost versionDisplayer:(id )aVersionDisplayer resumableCompletionBlock:(void (^)(SPUInstallUpdateStatus))block; 26 | 27 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)item host:(SUHost *)aHost versionDisplayer:(id )aVersionDisplayer informationalCompletionBlock:(void (^)(SPUInformationalUpdateAlertChoice))block; 28 | 29 | - (void)showUpdateReleaseNotesWithDownloadData:(SPUDownloadData *)downloadData; 30 | - (void)showReleaseNotesFailedToDownload; 31 | 32 | - (IBAction)installUpdate:sender; 33 | - (IBAction)skipThisVersion:sender; 34 | - (IBAction)remindMeLater:sender; 35 | 36 | @end 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Sparkle/SUUpdatePermissionPrompt.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdatePermissionPrompt.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 1/24/08. 6 | // Copyright 2008 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUUPDATEPERMISSIONPROMPT_H 10 | #define SUUPDATEPERMISSIONPROMPT_H 11 | 12 | #import 13 | 14 | @class SUHost, SPUUpdatePermissionRequest, SUUpdatePermissionResponse; 15 | 16 | @interface SUUpdatePermissionPrompt : NSWindowController 17 | 18 | + (void)promptWithHost:(SUHost *)host request:(SPUUpdatePermissionRequest *)request reply:(void (^)(SUUpdatePermissionResponse *))reply; 19 | 20 | - (IBAction)toggleMoreInfo:(id)sender; 21 | - (IBAction)finishPrompt:(id)sender; 22 | @end 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Sparkle/SUUpdatePermissionResponse.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdatePermissionResponse.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/8/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "SUExport.h" 16 | 17 | /*! 18 | This class represents a response for permission to check updates. 19 | */ 20 | SU_EXPORT @interface SUUpdatePermissionResponse : NSObject 21 | 22 | /*! 23 | Initializes a new update permission response instance. 24 | 25 | @param automaticUpdateChecks Flag for whether to allow automatic update checks. 26 | @param sendSystemProfile Flag for if system profile information should be sent to the server hosting the appcast. 27 | */ 28 | - (instancetype)initWithAutomaticUpdateChecks:(BOOL)automaticUpdateChecks sendSystemProfile:(BOOL)sendSystemProfile; 29 | 30 | /*! 31 | A read-only property indicating whether automatic update checks are allowed or not. 32 | */ 33 | @property (nonatomic, readonly) BOOL automaticUpdateChecks; 34 | 35 | /*! 36 | A read-only property indicating if system profile should be sent or not. 37 | */ 38 | @property (nonatomic, readonly) BOOL sendSystemProfile; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Sparkle/SUUpdatePermissionResponse.m: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdatePermissionResponse.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/8/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SUUpdatePermissionResponse.h" 10 | 11 | 12 | #include "AppKitPrevention.h" 13 | 14 | static NSString *SUUpdatePermissionAutomaticUpdateChecksKey = @"SUUpdatePermissionAutomaticUpdateChecks"; 15 | static NSString *SUUpdatePermissionSendSystemProfileKey = @"SUUpdatePermissionSendSystemProfile"; 16 | 17 | @implementation SUUpdatePermissionResponse 18 | 19 | @synthesize automaticUpdateChecks = _automaticUpdateChecks; 20 | @synthesize sendSystemProfile = _sendSystemProfile; 21 | 22 | + (BOOL)supportsSecureCoding 23 | { 24 | return YES; 25 | } 26 | 27 | - (instancetype)initWithCoder:(NSCoder *)decoder 28 | { 29 | BOOL automaticUpdateChecks = [decoder decodeBoolForKey:SUUpdatePermissionAutomaticUpdateChecksKey]; 30 | BOOL sendSystemProfile = [decoder decodeBoolForKey:SUUpdatePermissionSendSystemProfileKey]; 31 | return [self initWithAutomaticUpdateChecks:automaticUpdateChecks sendSystemProfile:sendSystemProfile]; 32 | } 33 | 34 | - (void)encodeWithCoder:(NSCoder *)encoder 35 | { 36 | [encoder encodeBool:self.automaticUpdateChecks forKey:SUUpdatePermissionAutomaticUpdateChecksKey]; 37 | [encoder encodeBool:self.sendSystemProfile forKey:SUUpdatePermissionSendSystemProfileKey]; 38 | } 39 | 40 | - (instancetype)initWithAutomaticUpdateChecks:(BOOL)automaticUpdateChecks sendSystemProfile:(BOOL)sendSystemProfile 41 | { 42 | self = [super init]; 43 | if (self != nil) { 44 | _automaticUpdateChecks = automaticUpdateChecks; 45 | _sendSystemProfile = sendSystemProfile; 46 | } 47 | return self; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Sparkle/SUUpdateValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdateValidator.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 12/3/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SUHost; 12 | 13 | @interface SUUpdateValidator : NSObject 14 | 15 | // Pass YES to performingPrevalidation if archive validation must be done immediately, before extraction 16 | - (instancetype)initWithDownloadPath:(NSString *)downloadPath dsaSignature:(NSString *)dsaSignature host:(SUHost *)host performingPrevalidation:(BOOL)performingPrevalidation; 17 | 18 | // Indicates whether we can perform (post) validation later 19 | @property (nonatomic, readonly) BOOL canValidate; 20 | 21 | // precondition: validation must be possible (see -canValidate) 22 | // This is "post" validation, after an archive has been extracted 23 | - (BOOL)validateWithUpdateDirectory:(NSString *)updateDirectory; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Sparkle/SUVersionComparisonProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionComparisonProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUVERSIONCOMPARISONPROTOCOL_H 10 | #define SUVERSIONCOMPARISONPROTOCOL_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | 18 | #import "SUExport.h" 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | 22 | /*! 23 | Provides version comparison facilities for Sparkle. 24 | */ 25 | @protocol SUVersionComparison 26 | 27 | /*! 28 | An abstract method to compare two version strings. 29 | 30 | Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, 31 | and NSOrderedSame if they are equivalent. 32 | */ 33 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD! 34 | 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | #endif 39 | -------------------------------------------------------------------------------- /Sparkle/SUVersionDisplayProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionDisplayProtocol.h 3 | // EyeTV 4 | // 5 | // Created by Uli Kusterer on 08.12.09. 6 | // Copyright 2009 Elgato Systems GmbH. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "SUExport.h" 16 | 17 | /*! 18 | Applies special display formatting to version numbers. 19 | */ 20 | @protocol SUVersionDisplay 21 | 22 | /*! 23 | Formats two version strings. 24 | 25 | Both versions are provided so that important distinguishing information 26 | can be displayed while also leaving out unnecessary/confusing parts. 27 | */ 28 | - (void)formatVersion:(NSString *_Nonnull*_Nonnull)inOutVersionA andVersion:(NSString *_Nonnull*_Nonnull)inOutVersionB; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Sparkle/Sparkle-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | ${CURRENT_PROJECT_VERSION} 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | ${CURRENT_PROJECT_VERSION} 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Sparkle/Sparkle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sparkle.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SPARKLE_H 10 | #define SPARKLE_H 11 | 12 | // This list should include the shared headers. It doesn't matter if some of them aren't shared (unless 13 | // there are name-space collisions) so we can list all of them to start with: 14 | 15 | #import "SUAppcast.h" 16 | #import "SUAppcastItem.h" 17 | #import "SUStandardVersionComparator.h" 18 | #import "SPUUpdater.h" 19 | #import "SPUUpdaterDelegate.h" 20 | #import "SPUUpdaterSettings.h" 21 | #import "SPUStandardUpdaterController.h" 22 | #import "SUVersionComparisonProtocol.h" 23 | #import "SUVersionDisplayProtocol.h" 24 | #import "SUErrors.h" 25 | #import "SPUUpdatePermissionRequest.h" 26 | #import "SUUpdatePermissionResponse.h" 27 | #import "SPUUserDriver.h" 28 | #import "SPUStandardUserDriver.h" 29 | #import "SPUStandardUserDriverDelegate.h" 30 | #import "SPUUserDriverCoreComponent.h" 31 | #import "SPUDownloadData.h" 32 | 33 | #import "SUUpdater.h" // deprecated 34 | #import "SUUpdaterDelegate.h" // deprecated 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /Sparkle/SparkleCore.h: -------------------------------------------------------------------------------- 1 | // 2 | // SparkleCore.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/20/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | // Copied mostly from Sparkle.h 10 | 11 | #ifndef SPARKLE_CORE_H 12 | #define SPARKLE_CORE_H 13 | 14 | // This list should include the shared headers. It doesn't matter if some of them aren't shared (unless 15 | // there are name-space collisions) so we can list all of them to start with: 16 | 17 | #import "SUAppcast.h" 18 | #import "SUAppcastItem.h" 19 | #import "SUStandardVersionComparator.h" 20 | #import "SPUUpdater.h" 21 | #import "SPUUpdaterDelegate.h" 22 | #import "SPUUpdaterSettings.h" 23 | #import "SUVersionComparisonProtocol.h" 24 | #import "SUErrors.h" 25 | #import "SPUUpdatePermissionRequest.h" 26 | #import "SUUpdatePermissionResponse.h" 27 | #import "SPUUserDriver.h" 28 | #import "SPUUserDriverCoreComponent.h" 29 | #import "SPUDownloadData.h" 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Sparkle/ca.lproj/SUUpdateAlert.strings: -------------------------------------------------------------------------------- 1 | /* NSButton (Automatically download and install updates in the future) : (oid:92) */ 2 | "Automatically download and install updates in the future" = "Descarrega i instal·la les actualitzacions automàticament en el futur"; 3 | 4 | /* NSButton (Install Update) : (oid:76) */ 5 | "Install Update" = "Instal·la l'actualització"; 6 | 7 | /* NSTextField (Release Notes:) : (oid:17) */ 8 | "Release Notes:" = "Notes d'aquesta versió:"; 9 | 10 | /* NSButton (Remind Me Later) : (oid:22) */ 11 | "Remind Me Later" = "Recorda-m'ho més tard"; 12 | 13 | /* NSButton (Skip This Version) : (oid:23) */ 14 | "Skip This Version" = "Omet aquesta versió"; 15 | 16 | /* NSWindow (Software Update) : (oid:5) */ 17 | "Software Update" = "Actualització del programari"; 18 | 19 | -------------------------------------------------------------------------------- /Sparkle/fi.lproj/SUUpdateAlert.strings: -------------------------------------------------------------------------------- 1 | /* NSButton (Automatically download and install updates in the future) : (oid:92) */ 2 | "Automatically download and install updates in the future" = "Hae ja asenna päivitykset jatkossa automaattisesti"; 3 | 4 | /* NSButton (Install Update) : (oid:76) */ 5 | "Install Update" = "Asenna päivitys"; 6 | 7 | /* NSTextField (Release Notes:) : (oid:17) */ 8 | "Release Notes:" = "Tietoa päivityksestä:"; 9 | 10 | /* NSButton (Remind Me Later) : (oid:22) */ 11 | "Remind Me Later" = "Muistuta myöhemmin"; 12 | 13 | /* NSButton (Skip This Version) : (oid:23) */ 14 | "Skip This Version" = "Ohita tämä versio"; 15 | 16 | /* NSWindow (Software Update) : (oid:5) */ 17 | "Software Update" = "Ohjelmiston pävitys"; 18 | 19 | -------------------------------------------------------------------------------- /Sparkle/he.lproj/SUUpdateAlert.strings: -------------------------------------------------------------------------------- 1 | /* NSButton (Automatically download and install updates in the future) : (oid:92) */ 2 | "Automatically download and install updates in the future" = "הורד והתקן עדכונים אוטומטית גם בעתיד"; 3 | 4 | /* NSButton (Install Update) : (oid:76) */ 5 | "Install Update" = "התקן עדכון"; 6 | 7 | /* NSTextField (Release Notes:) : (oid:17) */ 8 | "Release Notes:" = "פרטי גרסה:"; 9 | 10 | /* NSButton (Remind Me Later) : (oid:22) */ 11 | "Remind Me Later" = "הזכר לי מאוחר יותר"; 12 | 13 | /* NSButton (Skip This Version) : (oid:23) */ 14 | "Skip This Version" = "דלג על גרסה זו"; 15 | 16 | /* NSWindow (Software Update) : (oid:5) */ 17 | "Software Update" = "עדכון תכנה"; 18 | 19 | -------------------------------------------------------------------------------- /Sparkle/no.lproj/SUUpdateAlert.strings: -------------------------------------------------------------------------------- 1 | /* NSButton (Automatically download and install updates in the future) : (oid:92) */ 2 | "Automatically download and install updates in the future" = "Automatisk nedlastning og installering i fremtiden"; 3 | 4 | /* NSButton (Install Update) : (oid:76) */ 5 | "Install Update" = "Installer oppdatering"; 6 | 7 | /* NSTextField (Release Notes:) : (oid:17) */ 8 | "Release Notes:" = "Vedrørende utgivelsen:"; 9 | 10 | /* NSButton (Remind Me Later) : (oid:22) */ 11 | "Remind Me Later" = "Påminn meg senere"; 12 | 13 | /* NSButton (Skip This Version) : (oid:23) */ 14 | "Skip This Version" = "Hopp over denne versjonen"; 15 | 16 | /* NSWindow (Software Update) : (oid:5) */ 17 | "Software Update" = "Programvareoppdatering"; 18 | 19 | -------------------------------------------------------------------------------- /TestAppHelper/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | TestAppHelper 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSHumanReadableCopyright 26 | Copyright © 2016 Sparkle Project. All rights reserved. 27 | XPCService 28 | 29 | ServiceType 30 | Application 31 | JoinExistingSession 32 | 33 | 34 | NSAppTransportSecurity 35 | 36 | NSAllowsArbitraryLoads 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /TestAppHelper/TestAppHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // TestAppHelper.h 3 | // TestAppHelper 4 | // 5 | // Created by Mayur Pawashe on 3/2/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TestAppHelperProtocol.h" 11 | 12 | @protocol SPUUserDriver; 13 | 14 | // This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection. 15 | @interface TestAppHelper : NSObject 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /TestAppHelper/TestAppHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // TestAppHelper.m 3 | // TestAppHelper 4 | // 5 | // Created by Mayur Pawashe on 3/2/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "TestAppHelper.h" 10 | #import "SUAdHocCodeSigning.h" 11 | 12 | @implementation TestAppHelper 13 | 14 | - (void)codeSignApplicationAtPath:(NSString *)applicationPath reply:(void (^)(BOOL))reply 15 | { 16 | reply([SUAdHocCodeSigning codeSignApplicationAtPath:applicationPath]); 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /TestAppHelper/TestAppHelperProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // TestAppHelperProtocol.h 3 | // TestAppHelper 4 | // 5 | // Created by Mayur Pawashe on 3/2/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // The protocol that this service will vend as its API. This header file will also need to be visible to the process hosting the service. 12 | @protocol TestAppHelperProtocol 13 | 14 | - (void)codeSignApplicationAtPath:(NSString *)applicationPath reply:(void (^)(BOOL))reply; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /TestAppHelper/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TestAppHelper 4 | // 5 | // Created by Mayur Pawashe on 3/2/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TestAppHelper.h" 11 | #import "SPUUserDriver.h" 12 | 13 | @interface ServiceDelegate : NSObject 14 | @end 15 | 16 | @implementation ServiceDelegate 17 | 18 | - (BOOL)listener:(NSXPCListener *)__unused listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { 19 | // This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection. 20 | 21 | // Configure the connection. 22 | // First, set the interface that the exported object implements. 23 | newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(TestAppHelperProtocol)]; 24 | 25 | // Next, set the object that the connection exports. All messages sent on the connection to this service will be sent to the exported object to handle. The connection retains the exported object. 26 | newConnection.exportedObject = [[TestAppHelper alloc] init]; 27 | 28 | // Resuming the connection allows the system to deliver more incoming messages. 29 | [newConnection resume]; 30 | 31 | // Returning YES from this method tells the system that you have accepted this connection. If you want to reject the connection for some reason, call -invalidate on the connection and return NO. 32 | return YES; 33 | } 34 | 35 | @end 36 | 37 | int main(__unused int argc, __unused const char *argv[]) 38 | { 39 | // Create the delegate for the service. 40 | ServiceDelegate *delegate = [ServiceDelegate new]; 41 | 42 | // Set up the one NSXPCListener for this service. It will handle all incoming connections. 43 | NSXPCListener *listener = [NSXPCListener serviceListener]; 44 | listener.delegate = delegate; 45 | 46 | // Resuming the serviceListener starts this service. This method does not return. 47 | [listener resume]; 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /TestApplication/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/SUAdHocCodeSigning.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAdHocCodeSigning.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/4/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SUAdHocCodeSigning : NSObject 12 | 13 | + (BOOL)codeSignApplicationAtPath:(NSString *)applicationPath; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /TestApplication/SUAdHocCodeSigning.m: -------------------------------------------------------------------------------- 1 | // 2 | // SUAdHocCodeSigning.m 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/4/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SUAdHocCodeSigning.h" 10 | 11 | @implementation SUAdHocCodeSigning 12 | 13 | + (BOOL)codeSignApplicationAtPath:(NSString *)applicationPath 14 | { 15 | BOOL success = NO; 16 | @try 17 | { 18 | // ad-hoc signing with the dash 19 | NSArray *arguments = @[ @"--force", @"--deep", @"--sign", @"-", applicationPath ]; 20 | NSTask *task = [NSTask launchedTaskWithLaunchPath:@"/usr/bin/codesign" arguments:arguments]; 21 | [task waitUntilExit]; 22 | success = (task.terminationStatus == 0); 23 | } 24 | @catch (NSException *exception) 25 | { 26 | NSLog(@"Failed to code sign application at %@", applicationPath); 27 | NSLog(@"Exception: %@", exception); 28 | } 29 | return success; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /TestApplication/SUInstallUpdateViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallUpdateViewController.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/5/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SUInstallUpdateViewController : NSViewController 13 | 14 | - (instancetype)initWithAppcastItem:(SUAppcastItem *)appcastItem skippable:(BOOL)skippable reply:(void (^)(SPUUpdateAlertChoice))reply; 15 | 16 | - (void)showReleaseNotesWithDownloadData:(SPUDownloadData *)downloadData; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /TestApplication/SUPopUpTitlebarUserDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUPopUpTitlebarUserDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/5/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SUPopUpTitlebarUserDriver : NSObject 13 | 14 | - (instancetype)initWithWindow:(NSWindow *)window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /TestApplication/SUTestApplicationDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUTestApplicationDelegate.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/25/15. 6 | // Copyright (c) 2015 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SUTestApplicationDelegate : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TestApplication/SUTestWebServer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUTestWebServer.h 3 | // Sparkle 4 | // 5 | // Created by Kevin Wojniak on 10/8/15. 6 | // Copyright © 2015 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SUTestWebServer : NSObject 12 | 13 | - (instancetype)initWithPort:(int)port workingDirectory:(NSString*)workingDirectory; 14 | 15 | - (void)close; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /TestApplication/SUUpdateSettingsWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdateSettingsWindowController.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/25/15. 6 | // Copyright (c) 2015 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SUUpdateSettingsWindowController : NSWindowController 12 | 13 | - (instancetype)initWithCustomUserDriver:(BOOL)customUserDriver; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /TestApplication/Sparkle-Test-App.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.server 8 | 9 | com.apple.security.temporary-exception.shared-preference.read-write 10 | 11 | org.sparkle-project.SparkleTestApp 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /TestApplication/TestApplication-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Sparkle Test App 15 | CFBundlePackageType 16 | APPL 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.5 21 | CFBundleShortVersionString 22 | 1.5 23 | NSMainNibFile 24 | MainMenu 25 | NSPrincipalClass 26 | NSApplication 27 | SUEnableSystemProfiling 28 | 29 | SUFeedURL 30 | http://localhost:1337/sparkletestcast.xml 31 | SUPublicDSAKeyFile 32 | test_app_only_dsa_pub.pem 33 | 34 | 35 | -------------------------------------------------------------------------------- /TestApplication/ar.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/ca.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/cs.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/cy.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/da.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/el.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/fi.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/fr-CA.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/he.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/hu.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/id.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/is.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/it.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/ja.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/ko.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright Andy Matuschak 2006. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char *argv[]) 12 | { 13 | return NSApplicationMain(argc, argv); 14 | } 15 | -------------------------------------------------------------------------------- /TestApplication/nb.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/pl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/pt-BR.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/pt-PT.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/pt.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/ro.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/sk.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/sl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/sparkletestcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sparkle Test App Changelog 5 | Most recent changes with links to updates. 6 | en 7 | 8 | Version 2.0 9 | 10 | 12 |
  • Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  • 13 |
  • Suspendisse sed felis ac ante ultrices rhoncus. Etiam quis elit vel nibh placerat facilisis in id leo.
  • 14 |
  • Vestibulum nec tortor odio, nec malesuada libero. Cras vel convallis nunc.
  • 15 |
  • Suspendisse tristique massa eget velit consequat tincidunt. Praesent sodales hendrerit pretium.
  • 16 | 17 | ]]> 18 |
    19 | Sat, 26 Jul 2014 15:20:11 +0000 20 | 21 |
    22 |
    23 |
    24 | -------------------------------------------------------------------------------- /TestApplication/sv.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/th.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/tr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/uk.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /TestApplication/zh-Hant.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "© Andy Matuschak, 2006"; 4 | -------------------------------------------------------------------------------- /Tests/Resources/SparkleTestCodeSignApp.dmg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Tests/Resources/SparkleTestCodeSignApp.dmg -------------------------------------------------------------------------------- /Tests/Resources/SparkleTestCodeSignApp.enc.dmg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Tests/Resources/SparkleTestCodeSignApp.enc.dmg -------------------------------------------------------------------------------- /Tests/Resources/SparkleTestCodeSignApp.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Tests/Resources/SparkleTestCodeSignApp.tar -------------------------------------------------------------------------------- /Tests/Resources/SparkleTestCodeSignApp.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Tests/Resources/SparkleTestCodeSignApp.tar.bz2 -------------------------------------------------------------------------------- /Tests/Resources/SparkleTestCodeSignApp.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Tests/Resources/SparkleTestCodeSignApp.tar.gz -------------------------------------------------------------------------------- /Tests/Resources/SparkleTestCodeSignApp.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Tests/Resources/SparkleTestCodeSignApp.tar.xz -------------------------------------------------------------------------------- /Tests/Resources/SparkleTestCodeSignApp.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Tests/Resources/SparkleTestCodeSignApp.zip -------------------------------------------------------------------------------- /Tests/Resources/signed-test-file.txt: -------------------------------------------------------------------------------- 1 | Hello World! 2 | -------------------------------------------------------------------------------- /Tests/Resources/test.pkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zorgiepoo/Sparkle/a4eefe6725630ca49cb5041e00b03316083e793c/Tests/Resources/test.pkg -------------------------------------------------------------------------------- /Tests/Resources/testappcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | For unit test only 5 | 6 | Version 2.0 7 | desc 8 | Sat, 26 Jul 2014 15:20:11 +0000 9 | 10 | 11 | 12 | 13 | 14 | Version 3.0 15 | 16 | 17 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | Version 4.0 35 | Sat, 26 Jul 2014 15:20:13 +0000 36 | 37 | 17.0.0 38 | 39 | 40 | 41 | Version 5.0 42 | 43 | 2.0.0 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Tests/Resources/testnamespaces.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | For unit test only 5 | 6 | Version 3.0 7 | Sat, 26 Jul 2014 15:20:12 +0000 8 | https://sparkle-project.org/#works 9 | 10 | 11 | 12 | Version 2.0 13 | desc 14 | Sat, 26 Jul 2014 15:20:11 +0000 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Tests/SUUpdaterTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdaterTest.m 3 | // Sparkle 4 | // 5 | // Created by Jake Petroules on 2014-06-29. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUConstants.h" 11 | #import "SPUUpdater.h" 12 | #import "SPUStandardUserDriver.h" 13 | #import "SPUUpdaterDelegate.h" 14 | 15 | @interface SUUpdaterTest : XCTestCase 16 | @property (strong) SPUUpdater *updater; 17 | @end 18 | 19 | @implementation SUUpdaterTest 20 | 21 | @synthesize updater; 22 | 23 | - (void)setUp 24 | { 25 | [super setUp]; 26 | 27 | NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 28 | #pragma clang diagnostic push 29 | #pragma clang diagnostic ignored "-Wnonnull" 30 | // We really want a useless / not really functional user driver so we will pass nil here 31 | // For real world applications we should pass a valid user driver which is why this is not a nullable parameter 32 | self.updater = [[SPUUpdater alloc] initWithHostBundle:bundle applicationBundle:bundle userDriver:nil delegate:self]; 33 | #pragma clang diagnostic pop 34 | 35 | NSError *error = nil; 36 | if (![self.updater startUpdater:&error]) { 37 | NSLog(@"Updater error: %@", error); 38 | abort(); 39 | } 40 | } 41 | 42 | - (void)tearDown 43 | { 44 | self.updater = nil; 45 | [super tearDown]; 46 | } 47 | 48 | - (NSString *)feedURLStringForUpdater:(id)__unused updater 49 | { 50 | return @"https://test.example.com"; 51 | } 52 | 53 | - (void)testFeedURL 54 | { 55 | [self.updater feedURL]; // this WON'T throw 56 | } 57 | 58 | - (void)testSetTestFeedURL 59 | { 60 | NSURL *emptyURL = [NSURL URLWithString:@""]; 61 | XCTAssertNotNil(emptyURL); 62 | [self.updater setFeedURL:emptyURL]; // this WON'T throw 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Tests/Sparkle Unit Tests-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "SUUnarchiver.h" 6 | #import "SUUnarchiverProtocol.h" 7 | #import "SUBinaryDeltaUnarchiver.h" 8 | #import "SUPipedUnarchiver.h" 9 | #import "SUBinaryDeltaCommon.h" 10 | #import "SUFileManager.h" 11 | #import "SUAppcast.h" 12 | #import "SUAppcastItem.h" 13 | #import "SUAppcastDriver.h" 14 | #import "SUVersionComparisonProtocol.h" 15 | #import "SUStandardVersionComparator.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | // Duplicated to avoid exporting a private symbol from SUFileManager 20 | static const char *SUAppleQuarantineIdentifier = "com.apple.quarantine"; 21 | 22 | @interface SUFileManager (Private) 23 | 24 | - (BOOL)_acquireAuthorizationWithError:(NSError *_Nullable __autoreleasing *_Nullable)error; 25 | 26 | - (BOOL)_itemExistsAtURL:(NSURL *)fileURL; 27 | - (BOOL)_itemExistsAtURL:(NSURL *)fileURL isDirectory:(nullable BOOL *)isDirectory; 28 | 29 | @end 30 | 31 | @interface SUAppcastDriver (Private) 32 | 33 | + (SUAppcastItem *)bestItemFromAppcastItems:(NSArray *)appcastItems getDeltaItem:(SUAppcastItem *_Nullable __autoreleasing *_Nullable)deltaItem withHostVersion:(NSString *)hostVersion comparator:(id)comparator; 34 | 35 | @end 36 | 37 | 38 | @interface SUAppcast (Private) 39 | 40 | -(NSArray * _Nullable)parseAppcastItemsFromXMLData:(NSData *)appcastData error:(NSError *__autoreleasing*)errorp; 41 | 42 | @end 43 | 44 | @interface SUBinaryDeltaUnarchiver (Private) 45 | 46 | + (void)updateSpotlightImportersAtBundlePath:(NSString *)targetPath; 47 | 48 | @end 49 | 50 | NS_ASSUME_NONNULL_END 51 | -------------------------------------------------------------------------------- /Tests/SparkleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | SUEnableAutomaticChecks 20 | 21 | SUEnableSystemProfiling 22 | 23 | SUPublicDSAKeyFile 24 | test-pubkey.pem 25 | 26 | 27 | -------------------------------------------------------------------------------- /UITests/UITests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Vendor/bsdiff/bscommon.c: -------------------------------------------------------------------------------- 1 | /* 2 | * bscommon.c 3 | * Sparkle 4 | * 5 | * Created by Mayur Pawashe on 5/16/16. 6 | */ 7 | 8 | #include "bscommon.h" 9 | #include 10 | 11 | u_char *readfile(const char *filename, off_t *outSize) 12 | { 13 | int success = -1; 14 | u_char *buffer = NULL; 15 | 16 | FILE *file = fopen(filename, "r"); 17 | if (file == NULL) { 18 | goto cleanup; 19 | } 20 | 21 | if (fseek(file, 0L, SEEK_END) != 0) { 22 | goto cleanup; 23 | } 24 | 25 | long offset = ftell(file); 26 | if (offset == -1) { 27 | goto cleanup; 28 | } 29 | 30 | size_t size = (size_t)offset; 31 | 32 | if (outSize != NULL) { 33 | *outSize = (off_t)size; 34 | } 35 | 36 | /* Allocate size + 1 bytes instead of newsize bytes to ensure 37 | that we never try to malloc(0) and get a NULL pointer */ 38 | buffer = malloc(size + 1); 39 | if (buffer == NULL) { 40 | goto cleanup; 41 | } 42 | 43 | if (fseek(file, 0L, SEEK_SET) != 0) { 44 | goto cleanup; 45 | } 46 | 47 | if (fread(buffer, 1, size, file) < size) { 48 | goto cleanup; 49 | } 50 | 51 | success = 0; 52 | cleanup: 53 | if (success == -1) { 54 | free(buffer); 55 | buffer = NULL; 56 | } 57 | if (file != NULL) { 58 | fclose(file); 59 | } 60 | 61 | return buffer; 62 | } 63 | -------------------------------------------------------------------------------- /Vendor/bsdiff/bscommon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * bscommon.h 3 | * Sparkle 4 | * 5 | * Created by Mayur Pawashe on 5/16/16. 6 | */ 7 | 8 | #ifndef BS_COMMON_H 9 | #define BS_COMMON_H 10 | 11 | #include 12 | #include 13 | 14 | u_char *readfile(const char *filename, off_t *outSize); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /Vendor/bsdiff/bspatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * bspatch.h 3 | * Sparkle 4 | * 5 | * Created by Andy Matuschak on 1/11/10. 6 | * Copyright 2010 Andy Matuschak. All rights reserved. 7 | * 8 | */ 9 | 10 | // So that we can use this method in SUBinaryDeltaApply.m. 11 | // Silences the GCC warning that the prototype doesn't exist. 12 | int bspatch(int argc, const char * const argv[]); 13 | -------------------------------------------------------------------------------- /bin/codesign_xpc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os, sys, subprocess 4 | 5 | def log_message(message): 6 | sys.stderr.write(message + "\n") 7 | 8 | #Surround a token with double quotes if it has a space in it 9 | def sanitize(argument): 10 | return ('"' + argument + '"' if ' ' in argument else argument) 11 | 12 | def _codesign_service(identity, path, entitlements_path=None): 13 | command = ["codesign", "-fs", identity, path] + ([] if entitlements_path is None else ["--entitlements", entitlements_path]) 14 | log_message(" ".join(map(sanitize, command))) 15 | 16 | process = subprocess.Popen(command, stdout=subprocess.PIPE) 17 | process.communicate() 18 | if process.returncode != 0: 19 | log_message("Error: Failed to codesign %s" % (path)) 20 | sys.exit(1) 21 | 22 | def codesign_service(service_name, identity, path, entitlements_path=None): 23 | #Sign the auxiliary executables (if any) 24 | executables_path = os.path.join(path, "Contents/MacOS/") 25 | if os.path.exists(executables_path): 26 | for executable in os.listdir(executables_path): 27 | if executable != service_name: 28 | _codesign_service(identity, os.path.join(executables_path, executable), entitlements_path) 29 | 30 | #Sign the service bundle 31 | _codesign_service(identity, path, entitlements_path) 32 | 33 | if __name__ == "__main__": 34 | if len(sys.argv) < 3: 35 | log_message("Usage:\n\t%s code-signing-identity xpc-service xpc-service2 ..." % (sys.argv[0])) 36 | log_message("Example:\n\t%s \"Developer ID Application\" ./XPCServices/*.xpc" % (sys.argv[0])) 37 | sys.exit(1) 38 | 39 | signing_identity = sys.argv[1] 40 | xpc_services = sys.argv[2:] 41 | 42 | for xpc_service in xpc_services: 43 | parent, child = os.path.split(xpc_service) 44 | service_name = os.path.splitext(child)[0] 45 | entitlements_path = os.path.join(parent, service_name + ".entitlements") 46 | codesign_service(service_name, signing_identity, xpc_service, None if not os.path.exists(entitlements_path) else entitlements_path) 47 | -------------------------------------------------------------------------------- /bin/generate_keys: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | for file in "dsaparam.pem" "dsa_priv.pem" "dsa_pub.pem"; do 4 | if [ -e "$file" ]; then 5 | echo "There's already a $file here! Move it aside or be more careful!" 6 | exit 1 7 | fi 8 | done 9 | 10 | openssl="/usr/bin/openssl" 11 | $openssl gendsa <($openssl dsaparam 4096) -out dsa_priv.pem 12 | chmod 0400 dsa_priv.pem 13 | $openssl dsa -in dsa_priv.pem -pubout -out dsa_pub.pem 14 | 15 | echo " 16 | Generated two files: 17 | dsa_priv.pem: your private key. Keep it secret and don't share it! 18 | dsa_pub.pem: public counterpart to include in the app bundle. 19 | 20 | BACK UP YOUR PRIVATE KEY AND KEEP IT SAFE! 21 | If you lose it, your users will be unable to upgrade! 22 | " 23 | 24 | open -R dsa_priv.pem 25 | -------------------------------------------------------------------------------- /bin/sign_update: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | if [ "$#" -ne 2 ]; then 5 | echo "Usage: $0 update_archive private_key" 6 | exit 1 7 | fi 8 | openssl=/usr/bin/openssl 9 | $openssl dgst -sha1 -binary < "$1" | $openssl dgst -dss1 -sign "$2" | $openssl enc -base64 10 | -------------------------------------------------------------------------------- /generate_appcast/Appcast-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "SUStandardVersionComparator.h" 4 | #import "SUConstants.h" 5 | #import "SUErrors.h" 6 | #import "SUUnarchiver.h" 7 | #import "SUBinaryDeltaUnarchiver.h" 8 | #import "SUBinaryDeltaCreate.h" 9 | -------------------------------------------------------------------------------- /generate_appcast/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // Appcast 4 | // 5 | // Created by Kornel on 20/12/2016. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | func main() { 12 | let args = CommandLine.arguments; 13 | if args.count < 3 { 14 | let command = URL(fileURLWithPath: args[0]).lastPathComponent; 15 | print("Generate appcast from a directory of Sparkle updates\nUsage: \(command) \n", 16 | " e.g. \(command) dsa_priv.pem archives/\n", 17 | " Appcast files and deltas will be written to the archives directory.\n", 18 | " Note that pkg-based updates are not supported.\n" 19 | ) 20 | exit(1); 21 | } 22 | 23 | let privateKeyPath = URL(fileURLWithPath: args[1]); 24 | let archivesSourceDir = URL(fileURLWithPath: args[2], isDirectory:true); 25 | 26 | do { 27 | let privateKey = try loadPrivateKey(privateKeyPath: privateKeyPath); 28 | do { 29 | let allUpdates = try makeAppcast(archivesSourceDir: archivesSourceDir, privateKey: privateKey); 30 | 31 | for (appcastFile, updates) in allUpdates { 32 | let appcastDestPath = URL(fileURLWithPath: appcastFile, relativeTo: archivesSourceDir); 33 | try writeAppcast(appcastDestPath:appcastDestPath, updates:updates); 34 | print("Written", appcastDestPath.path, "based on", updates.count, "updates"); 35 | } 36 | } catch { 37 | print("Error generating appcast from directory", archivesSourceDir.path, "\n", error); 38 | exit(1); 39 | } 40 | } catch { 41 | print("Unable to load DSA private key from", privateKeyPath.path, "\n", error); 42 | exit(1); 43 | } 44 | } 45 | 46 | DispatchQueue.global().async(execute: { 47 | main(); 48 | CFRunLoopStop(CFRunLoopGetMain()); 49 | }); 50 | 51 | CFRunLoopRun(); 52 | -------------------------------------------------------------------------------- /sparkle-cli/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | ${CURRENT_PROJECT_VERSION} 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | ${CURRENT_PROJECT_VERSION} 25 | LSUIElement 26 | 1 27 | LSMinimumSystemVersion 28 | $(MACOSX_DEPLOYMENT_TARGET) 29 | NSHumanReadableCopyright 30 | Copyright © 2016 Sparkle Project. All rights reserved. 31 | NSPrincipalClass 32 | NSApplication 33 | NSAppTransportSecurity 34 | 35 | NSAllowsArbitraryLoads 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /sparkle-cli/SPUCommandLineDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUCommandLineDriver.h 3 | // sparkle-cli 4 | // 5 | // Created by Mayur Pawashe on 4/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class SUUpdatePermissionResponse; 14 | 15 | @interface SPUCommandLineDriver : NSObject 16 | 17 | - (nullable instancetype)initWithUpdateBundlePath:(NSString *)updateBundlePath applicationBundlePath:(nullable NSString *)applicationBundlePath customFeedURL:(nullable NSString *)customFeedURL updatePermissionResponse:(nullable SUUpdatePermissionResponse *)updatePermissionResponse deferInstallation:(BOOL)deferInstallation interactiveInstallation:(BOOL)interactiveInstallation verbose:(BOOL)verbose; 18 | 19 | - (void)runAndCheckForUpdatesNow:(BOOL)checkForUpdatesNow; 20 | 21 | - (void)probeForUpdates; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /sparkle-cli/SPUCommandLineUserDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUCommandLineUserDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface SPUCommandLineUserDriver : NSObject 15 | 16 | - (instancetype)initWithUpdatePermissionResponse:(nullable SUUpdatePermissionResponse *)updatePermissionResponse deferInstallation:(BOOL)deferInstallation verbose:(BOOL)verbose; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | --------------------------------------------------------------------------------