diff --git a/Squirrel/SQRLUpdater.m b/Squirrel/SQRLUpdater.m index 2c860bb1..51b4deae 100644 --- a/Squirrel/SQRLUpdater.m +++ b/Squirrel/SQRLUpdater.m @@ -6,6 +6,7 @@ // Copyright (c) 2013 GitHub. All rights reserved. // +#import #import "SQRLUpdater.h" #import "NSBundle+SQRLVersionExtensions.h" #import "NSError+SQRLVerbosityExtensions.h" @@ -53,6 +54,10 @@ @interface SQRLUpdater () // Sends completed or error. @property (nonatomic, strong, readonly) RACSignal *shipItLauncher; +/// Was the app quarantined when we tried checking for updates? Will be nil if +/// we haven't checked yet. +@property (atomic, copy) NSNumber *wasQuarantined; + // Parses an update model from downloaded data. // // data - JSON data representing an update manifest. This must not be nil. @@ -171,9 +176,16 @@ - (id)initWithUpdateRequest:(NSURLRequest *)updateRequest { NSMutableURLRequest *request = [self.updateRequest mutableCopy]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; - return [[[[[[[[self + return [[[[[[[[[self performHousekeeping] then:^{ + return [self unquarantineApp]; + }] + flattenMap:^(NSNumber *quarantined) { + // If we were quarantined then we can't check for updates until + // the app is relaunched. + if (quarantined.boolValue) return [RACSignal empty]; + self.state = SQRLUpdaterStateCheckingForUpdate; return [NSURLConnection rac_sendAsynchronousRequest:request]; @@ -240,6 +252,21 @@ - (id)initWithUpdateRequest:(NSURLRequest *)updateRequest { #pragma mark Checking for Updates +- (RACSignal *)unquarantineApp { + return [RACSignal createSignal:^ RACDisposable * (id subscriber) { + if (self.wasQuarantined == nil) { + NSURL *targetURL = NSRunningApplication.currentApplication.bundleURL; + const char *path = targetURL.path.fileSystemRepresentation; + int result = removexattr(path, "com.apple.quarantine", XATTR_NOFOLLOW); + self.wasQuarantined = @(result == 0); + } + + [subscriber sendNext:self.wasQuarantined]; + [subscriber sendCompleted]; + return nil; + }]; +} + - (RACDisposable *)startAutomaticChecksWithInterval:(NSTimeInterval)interval { @weakify(self);