Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 403 lines (339 sloc) 18.328 kb
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
1 //
2 // SUBasicUpdateDriver.m
3 // Sparkle
4 //
5 // Created by Andy Matuschak on 4/23/08.
6 // Copyright 2008 Andy Matuschak. All rights reserved.
7 //
8
9 #import "SUBasicUpdateDriver.h"
10
f815eec Andy Matuschak Fixes 243884
andymatuschak authored
11 #import "SUHost.h"
de9be8b Andy Matuschak Fixes 244428
andymatuschak authored
12 #import "SUDSAVerifier.h"
f815eec Andy Matuschak Fixes 243884
andymatuschak authored
13 #import "SUInstaller.h"
14 #import "SUStandardVersionComparator.h"
15 #import "SUUnarchiver.h"
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
16 #import "SUConstants.h"
17 #import "SULog.h"
7cd8974 Uli Kusterer Make Sparkle more robust when the permissions of ~/Library/Application S...
uliwitness authored
18 #import "SUPlainInstaller.h"
19 #import "SUPlainInstallerInternals.h"
4548228 Václav Slavík Fix 10.4 compatiblity broken by delta updates.
vslavik authored
20 #import "SUBinaryDeltaCommon.h"
ba6c3b6 Andy Matuschak Cleaned up SUUpdater.h
andymatuschak authored
21 #import "SUUpdater_Private.h"
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
22
73e96cd Andy Matuschak Updating project for 4.2.1; changing SDK to 10.7
andymatuschak authored
23 @interface SUBasicUpdateDriver () <NSURLDownloadDelegate>; @end
24
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
25
26 @implementation SUBasicUpdateDriver
27
478e0a5 Andy Matuschak Fixed a potential security vulnerability in which the download is transm...
andymatuschak authored
28 - (void)checkForUpdatesAtURL:(NSURL *)URL host:(SUHost *)aHost
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
29 {
478e0a5 Andy Matuschak Fixed a potential security vulnerability in which the download is transm...
andymatuschak authored
30 [super checkForUpdatesAtURL:URL host:aHost];
3146ffb Andy Matuschak Fixes 248929, 244738
andymatuschak authored
31 if ([aHost isRunningOnReadOnlyVolume])
8b3d15b Andy Matuschak Moved the check for whether the host is running from a disk image to SUB...
andymatuschak authored
32 {
3146ffb Andy Matuschak Fixes 248929, 244738
andymatuschak authored
33 [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SURunningFromDiskImageError userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:SULocalizedString(@"%1$@ can't be updated when it's running from a read-only volume like a disk image or an optical drive. Move %1$@ to your Applications folder, relaunch it from there, and try again.", nil), [aHost name]] forKey:NSLocalizedDescriptionKey]]];
8b3d15b Andy Matuschak Moved the check for whether the host is running from a disk image to SUB...
andymatuschak authored
34 return;
35 }
36
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
37 SUAppcast *appcast = [[SUAppcast alloc] init];
38 CFRetain(appcast); // We'll manage the appcast's memory ourselves so we don't have to make it an IV to support GC.
39 [appcast release];
40
41 [appcast setDelegate:self];
dfe0eff Mark Rowe Provide the ability to set a custom user agent string on all HTTP reques...
bdash authored
42 [appcast setUserAgentString:[updater userAgentString]];
478e0a5 Andy Matuschak Fixed a potential security vulnerability in which the download is transm...
andymatuschak authored
43 [appcast fetchAppcastFromURL:URL];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
44 }
45
dab8a36 renamed all methods that start with underscore, since that's reserved by...
Sean McBride authored
46 - (id <SUVersionComparison>)versionComparator
aaa60d2 Andy Matuschak Fixed 244761
andymatuschak authored
47 {
48 id <SUVersionComparison> comparator = nil;
49
50 // Give the delegate a chance to provide a custom version comparator
b3f3944 Andy Matuschak Fixes 244857
andymatuschak authored
51 if ([[updater delegate] respondsToSelector:@selector(versionComparatorForUpdater:)])
52 comparator = [[updater delegate] versionComparatorForUpdater:updater];
aaa60d2 Andy Matuschak Fixed 244761
andymatuschak authored
53
54 // If we don't get a comparator from the delegate, use the default comparator
55 if (!comparator)
56 comparator = [SUStandardVersionComparator defaultComparator];
57
58 return comparator;
59 }
60
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
61 - (BOOL)isItemNewer:(SUAppcastItem *)ui
62 {
dab8a36 renamed all methods that start with underscore, since that's reserved by...
Sean McBride authored
63 return [[self versionComparator] compareVersion:[host version] toVersion:[ui versionString]] == NSOrderedAscending;
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
64 }
65
66 - (BOOL)hostSupportsItem:(SUAppcastItem *)ui
67 {
9662452 Fixes #44: maximumSystemVersion key
Stefan Hoffmann authored
68 if (([ui minimumSystemVersion] == nil || [[ui minimumSystemVersion] isEqualToString:@""]) &&
69 ([ui maximumSystemVersion] == nil || [[ui maximumSystemVersion] isEqualToString:@""])) { return YES; }
70
71 BOOL minimumVersionOK = TRUE;
72 BOOL maximumVersionOK = TRUE;
73
74 // Check minimum and maximum System Version
75 if ([ui minimumSystemVersion] != nil && ![[ui minimumSystemVersion] isEqualToString:@""]) {
76 minimumVersionOK = [[SUStandardVersionComparator defaultComparator] compareVersion:[ui minimumSystemVersion] toVersion:[SUHost systemVersionString]] != NSOrderedDescending;
77 }
78 if ([ui maximumSystemVersion] != nil && ![[ui maximumSystemVersion] isEqualToString:@""]) {
79 maximumVersionOK = [[SUStandardVersionComparator defaultComparator] compareVersion:[ui maximumSystemVersion] toVersion:[SUHost systemVersionString]] != NSOrderedAscending;
80 }
81
82 return minimumVersionOK && maximumVersionOK;
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
83 }
84
85 - (BOOL)itemContainsSkippedVersion:(SUAppcastItem *)ui
86 {
98832c4 Andy Matuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Spa...
andymatuschak authored
87 NSString *skippedVersion = [host objectForUserDefaultsKey:SUSkippedVersionKey];
1264a6b Andy Matuschak Sparkle now finds the newest update in an appcast for which the host mee...
andymatuschak authored
88 if (skippedVersion == nil) { return NO; }
dab8a36 renamed all methods that start with underscore, since that's reserved by...
Sean McBride authored
89 return [[self versionComparator] compareVersion:[ui versionString] toVersion:skippedVersion] != NSOrderedDescending;
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
90 }
91
92 - (BOOL)itemContainsValidUpdate:(SUAppcastItem *)ui
93 {
94 return [self hostSupportsItem:ui] && [self isItemNewer:ui] && ![self itemContainsSkippedVersion:ui];
95 }
96
97 - (void)appcastDidFinishLoading:(SUAppcast *)ac
98 {
b3f3944 Andy Matuschak Fixes 244857
andymatuschak authored
99 if ([[updater delegate] respondsToSelector:@selector(updater:didFinishLoadingAppcast:)])
100 [[updater delegate] updater:updater didFinishLoadingAppcast:ac];
d201803 Andy Matuschak More fixes for 258060
andymatuschak authored
101
102 SUAppcastItem *item = nil;
103
5c32832 Andy Matuschak Fixes bug 228446
andymatuschak authored
104 // Now we have to find the best valid update in the appcast.
b3f3944 Andy Matuschak Fixes 244857
andymatuschak authored
105 if ([[updater delegate] respondsToSelector:@selector(bestValidUpdateInAppcast:forUpdater:)]) // Does the delegate want to handle it?
5c32832 Andy Matuschak Fixes bug 228446
andymatuschak authored
106 {
d201803 Andy Matuschak More fixes for 258060
andymatuschak authored
107 item = [[updater delegate] bestValidUpdateInAppcast:ac forUpdater:updater];
5c32832 Andy Matuschak Fixes bug 228446
andymatuschak authored
108 }
109 else // If not, we'll take care of it ourselves.
110 {
111 // Find the first update we can actually use.
251706d Andy Matuschak Fixed a serious bug which could cause a server to DDoS'd in the case of ...
andymatuschak authored
112 NSEnumerator *updateEnumerator = [[ac items] objectEnumerator];
5c32832 Andy Matuschak Fixes bug 228446
andymatuschak authored
113 do {
d201803 Andy Matuschak More fixes for 258060
andymatuschak authored
114 item = [updateEnumerator nextObject];
115 } while (item && ![self hostSupportsItem:item]);
6e648f1 Mark Rowe Add support for parsing an extended <sparkle:deltas> element in the appc...
bdash authored
116
4548228 Václav Slavík Fix 10.4 compatiblity broken by delta updates.
vslavik authored
117 if (binaryDeltaSupported()) {
118 SUAppcastItem *deltaUpdateItem = [[item deltaUpdates] objectForKey:[host version]];
119 if (deltaUpdateItem && [self hostSupportsItem:deltaUpdateItem]) {
120 nonDeltaUpdateItem = [item retain];
121 item = deltaUpdateItem;
122 }
6e648f1 Mark Rowe Add support for parsing an extended <sparkle:deltas> element in the appc...
bdash authored
123 }
5c32832 Andy Matuschak Fixes bug 228446
andymatuschak authored
124 }
d201803 Andy Matuschak More fixes for 258060
andymatuschak authored
125
126 updateItem = [item retain];
d7774c0 performed a code review, specifically:
Sean McBride authored
127 if (ac) { CFRelease(ac); } // Remember that we're explicitly managing the memory of the appcast.
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
128 if (updateItem == nil) { [self didNotFindUpdate]; return; }
129
130 if ([self itemContainsValidUpdate:updateItem])
131 [self didFindValidUpdate];
132 else
133 [self didNotFindUpdate];
134 }
135
136 - (void)appcast:(SUAppcast *)ac failedToLoadWithError:(NSError *)error
137 {
d7774c0 performed a code review, specifically:
Sean McBride authored
138 if (ac) { CFRelease(ac); } // Remember that we're explicitly managing the memory of the appcast.
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
139 [self abortUpdateWithError:error];
140 }
141
142 - (void)didFindValidUpdate
143 {
b3f3944 Andy Matuschak Fixes 244857
andymatuschak authored
144 if ([[updater delegate] respondsToSelector:@selector(updater:didFindValidUpdate:)])
145 [[updater delegate] updater:updater didFindValidUpdate:updateItem];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
146 [self downloadUpdate];
147 }
148
149 - (void)didNotFindUpdate
150 {
b3f3944 Andy Matuschak Fixes 244857
andymatuschak authored
151 if ([[updater delegate] respondsToSelector:@selector(updaterDidNotFindUpdate:)])
152 [[updater delegate] updaterDidNotFindUpdate:updater];
98832c4 Andy Matuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Spa...
andymatuschak authored
153 [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SUNoUpdateError userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:SULocalizedString(@"You already have the newest version of %@.", nil), [host name]] forKey:NSLocalizedDescriptionKey]]];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
154 }
155
156 - (void)downloadUpdate
157 {
dfe0eff Mark Rowe Provide the ability to set a custom user agent string on all HTTP reques...
bdash authored
158 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[updateItem fileURL]];
159 [request setValue:[updater userAgentString] forHTTPHeaderField:@"User-Agent"];
160 download = [[NSURLDownload alloc] initWithRequest:request delegate:self];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
161 }
162
163 - (void)download:(NSURLDownload *)d decideDestinationWithSuggestedFilename:(NSString *)name
164 {
165 // If name ends in .txt, the server probably has a stupid MIME configuration. We'll give the developer the benefit of the doubt and chop that off.
166 if ([[name pathExtension] isEqualToString:@"txt"])
167 name = [name stringByDeletingPathExtension];
168
fa67107 Andy Matuschak Changing download destination from ~/Desktop to ~/Library/App Support/HO...
andymatuschak authored
169 NSString *downloadFileName = [NSString stringWithFormat:@"%@ %@", [host name], [updateItem versionString]];
170
171
0e609cc Uli Kusterer Make sure we delete the temp directory.
uliwitness authored
172 [tempDir release];
86b6502 Andy Matuschak Fixing a merge error which put finish_installation in /tmp rather than i...
andymatuschak authored
173 tempDir = [[[host appSupportPath] stringByAppendingPathComponent:downloadFileName] retain];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
174 int cnt=1;
7071142 Andy Matuschak Improving Sparkle's robustness against apps without a CFBundleVersion.
andymatuschak authored
175 while ([[NSFileManager defaultManager] fileExistsAtPath:tempDir] && cnt <= 999)
7316a00 Andy Matuschak Removed SL-deprecated NSFileManager methods. Left the old ones around #i...
andymatuschak authored
176 {
0e609cc Uli Kusterer Make sure we delete the temp directory.
uliwitness authored
177 [tempDir release];
86b6502 Andy Matuschak Fixing a merge error which put finish_installation in /tmp rather than i...
andymatuschak authored
178 tempDir = [[[host appSupportPath] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@ %d", downloadFileName, cnt++]] retain];
7316a00 Andy Matuschak Removed SL-deprecated NSFileManager methods. Left the old ones around #i...
andymatuschak authored
179 }
180
095d223 Andy Matuschak Fixes #116: Update error: Can't make a temporary directory
andymatuschak authored
181 // Create the temporary directory if necessary.
4fad530 Change availability checks so that they build on 10.4
Stuart Morgan authored
182 #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
095d223 Andy Matuschak Fixes #116: Update error: Can't make a temporary directory
andymatuschak authored
183 BOOL success = YES;
184 NSEnumerator *pathComponentEnumerator = [[tempDir pathComponents] objectEnumerator];
185 NSString *pathComponentAccumulator = @"";
186 NSString *currentPathComponent;
187 while ((currentPathComponent = [pathComponentEnumerator nextObject])) {
188 pathComponentAccumulator = [pathComponentAccumulator stringByAppendingPathComponent:currentPathComponent];
189 if ([[NSFileManager defaultManager] fileExistsAtPath:pathComponentAccumulator]) continue;
190 success &= [[NSFileManager defaultManager] createDirectoryAtPath:pathComponentAccumulator attributes:nil];
191 }
54299d7 added #ifdef's for Tiger support
August Joki authored
192 #else
f2a7b4b Fixed deprecated APIs to use replacements.
August Joki authored
193 BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:tempDir withIntermediateDirectories:YES attributes:nil error:NULL];
54299d7 added #ifdef's for Tiger support
August Joki authored
194 #endif
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
195 if (!success)
196 {
fa67107 Andy Matuschak Changing download destination from ~/Desktop to ~/Library/App Support/HO...
andymatuschak authored
197 // Okay, something's really broken with this user's file structure.
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
198 [download cancel];
199 [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SUTemporaryDirectoryError userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Can't make a temporary directory for the update download at %@.",tempDir] forKey:NSLocalizedDescriptionKey]]];
200 }
201
202 downloadPath = [[tempDir stringByAppendingPathComponent:name] retain];
203 [download setDestination:downloadPath allowOverwrite:YES];
204 }
205
206 - (void)downloadDidFinish:(NSURLDownload *)d
207 {
d0b802e Uli Kusterer Added preprocessor defines to SUConstants.h for turning on/off DSA and d...
uliwitness authored
208 #if !ENDANGER_USERS_WITH_INSECURE_UPDATES
7e9fc0f Andy Matuschak Changed the security policy once more:
andymatuschak authored
209 // New in Sparkle 1.5: we're now checking signatures on all non-secure downloads, where "secure" is defined as both the appcast and the download being transmitted over SSL.
478e0a5 Andy Matuschak Fixed a potential security vulnerability in which the download is transm...
andymatuschak authored
210 NSURL *downloadURL = [[d request] URL];
799b002 Andy Matuschak Fixing Bug #338324: "Unsigned updates delivered over https fail"
andymatuschak authored
211 if (!(([[downloadURL scheme] isEqualToString:@"https"] && [[appcastURL scheme] isEqualToString:@"https"]) ||
212 ([downloadURL isFileURL] && [appcastURL isFileURL])))
1d3ab8d Andy Matuschak Alright, guys. No more Mr. Nice Sparklepants. Sparkle now requires eithe...
andymatuschak authored
213 {
799b002 Andy Matuschak Fixing Bug #338324: "Unsigned updates delivered over https fail"
andymatuschak authored
214 if (![host publicDSAKey] || ![SUDSAVerifier validatePath:downloadPath withEncodedDSASignature:[updateItem DSASignature] withPublicDSAKey:[host publicDSAKey]])
1d3ab8d Andy Matuschak Alright, guys. No more Mr. Nice Sparklepants. Sparkle now requires eithe...
andymatuschak authored
215 {
1509564 Andy Matuschak Fixing Bug #400536: @"The update is improperly signed." does not localiz...
andymatuschak authored
216 [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SUSignatureError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:SULocalizedString(@"An error occurred while extracting the archive. Please try again later.", nil), NSLocalizedDescriptionKey, @"The update is improperly signed.", NSLocalizedFailureReasonErrorKey, nil]]];
1d3ab8d Andy Matuschak Alright, guys. No more Mr. Nice Sparklepants. Sparkle now requires eithe...
andymatuschak authored
217 return;
218 }
219 }
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
220 #endif
1d3ab8d Andy Matuschak Alright, guys. No more Mr. Nice Sparklepants. Sparkle now requires eithe...
andymatuschak authored
221
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
222 [self extractUpdate];
223 }
224
225 - (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error
226 {
8dfd93e Andy Matuschak Made the error displayed on download failure human-friendly.
andymatuschak authored
227 [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SURelaunchError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:SULocalizedString(@"An error occurred while downloading the update. Please try again later.", nil), NSLocalizedDescriptionKey, [error localizedDescription], NSLocalizedFailureReasonErrorKey, nil]]];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
228 }
229
c9bd132 Andy Matuschak Fixes 246469
andymatuschak authored
230 - (BOOL)download:(NSURLDownload *)download shouldDecodeSourceDataOfMIMEType:(NSString *)encodingType
231 {
0af86bb Andy Matuschak Hopefully actually fixing 246469: it seems that while Cocoa documents it...
andymatuschak authored
232 // We don't want the download system to extract our gzips.
233 // Note that we use a substring matching here instead of direct comparison because the docs say "application/gzip" but the system *uses* "application/x-gzip". This is a documentation bug.
898216a Andy Matuschak Final fix for 246469 (I hope). Fixed a mind-bogglingly stupid typo which...
andymatuschak authored
234 return ([encodingType rangeOfString:@"gzip"].location == NSNotFound);
c9bd132 Andy Matuschak Fixes 246469
andymatuschak authored
235 }
236
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
237 - (void)extractUpdate
1d3ab8d Andy Matuschak Alright, guys. No more Mr. Nice Sparklepants. Sparkle now requires eithe...
andymatuschak authored
238 {
6e648f1 Mark Rowe Add support for parsing an extended <sparkle:deltas> element in the appc...
bdash authored
239 SUUnarchiver *unarchiver = [SUUnarchiver unarchiverForPath:downloadPath updatingHost:host];
441a538 Andy Matuschak Oops! Fixed a warning that caused Sparkle not to compile. Made the unarc...
andymatuschak authored
240 if (!unarchiver)
241 {
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
242 SULog(@"Sparkle Error: No valid unarchiver for %@!", downloadPath);
441a538 Andy Matuschak Oops! Fixed a warning that caused Sparkle not to compile. Made the unarc...
andymatuschak authored
243 [self unarchiverDidFail:nil];
764bed3 Andy Matuschak Okay, *really* fixing the bug this time. Thanks for watching my back, Sc...
andymatuschak authored
244 return;
441a538 Andy Matuschak Oops! Fixed a warning that caused Sparkle not to compile. Made the unarc...
andymatuschak authored
245 }
3daa88d Andy Matuschak --fixes lp:242525 --fixes lp:242561 --fixes lp:242564
andymatuschak authored
246 CFRetain(unarchiver); // Manage this memory manually so we don't have to make it an IV.
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
247 [unarchiver setDelegate:self];
93ea93d Andy Matuschak Fixes 236695
andymatuschak authored
248 [unarchiver start];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
249 }
250
6e648f1 Mark Rowe Add support for parsing an extended <sparkle:deltas> element in the appc...
bdash authored
251 - (void)failedToApplyDeltaUpdate
252 {
253 // When a delta update fails to apply we fall back on updating via a full install.
254 [updateItem release];
255 updateItem = nonDeltaUpdateItem;
256 nonDeltaUpdateItem = nil;
257
258 [self downloadUpdate];
259 }
260
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
261 - (void)unarchiverDidFinish:(SUUnarchiver *)ua
262 {
441a538 Andy Matuschak Oops! Fixed a warning that caused Sparkle not to compile. Made the unarc...
andymatuschak authored
263 if (ua) { CFRelease(ua); }
c96aa2e Andy Matuschak The finish_installation tool will not relaunch the host app if it's usin...
andymatuschak authored
264 [self installWithToolAndRelaunch:YES];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
265 }
266
267 - (void)unarchiverDidFail:(SUUnarchiver *)ua
268 {
441a538 Andy Matuschak Oops! Fixed a warning that caused Sparkle not to compile. Made the unarc...
andymatuschak authored
269 if (ua) { CFRelease(ua); }
6e648f1 Mark Rowe Add support for parsing an extended <sparkle:deltas> element in the appc...
bdash authored
270
271 if ([updateItem isDeltaUpdate]) {
272 [self failedToApplyDeltaUpdate];
273 return;
274 }
275
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
276 [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SUUnarchivingError userInfo:[NSDictionary dictionaryWithObject:SULocalizedString(@"An error occurred while extracting the archive. Please try again later.", nil) forKey:NSLocalizedDescriptionKey]]];
277 }
278
6d8f5be Andy Matuschak Merging in David Smith's branch to fix bug #230123. We now copy the rela...
andymatuschak authored
279 - (BOOL)shouldInstallSynchronously { return NO; }
280
c96aa2e Andy Matuschak The finish_installation tool will not relaunch the host app if it's usin...
andymatuschak authored
281 - (void)installWithToolAndRelaunch:(BOOL)relaunch
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
282 {
c96aa2e Andy Matuschak The finish_installation tool will not relaunch the host app if it's usin...
andymatuschak authored
283 if (![updater mayUpdateAndRestart])
284 {
285 [self abortUpdate];
286 return;
287 }
288
289 // Give the host app an opportunity to postpone the install and relaunch.
290 static BOOL postponedOnce = NO;
291 if (!postponedOnce && [[updater delegate] respondsToSelector:@selector(updater:shouldPostponeRelaunchForUpdate:untilInvoking:)])
292 {
293 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[self class] instanceMethodSignatureForSelector:@selector(installWithToolAndRelaunch:)]];
294 [invocation setSelector:@selector(installWithToolAndRelaunch:)];
4d00e8c Andy Matuschak Fixes #157: Delayed relaunch not working
andymatuschak authored
295 [invocation setArgument:&relaunch atIndex:2];
c96aa2e Andy Matuschak The finish_installation tool will not relaunch the host app if it's usin...
andymatuschak authored
296 [invocation setTarget:self];
297 postponedOnce = YES;
298 if ([[updater delegate] updater:updater shouldPostponeRelaunchForUpdate:updateItem untilInvoking:invocation])
299 return;
300 }
301
302
b3f3944 Andy Matuschak Fixes 244857
andymatuschak authored
303 if ([[updater delegate] respondsToSelector:@selector(updater:willInstallUpdate:)])
304 [[updater delegate] updater:updater willInstallUpdate:updateItem];
d7774c0 performed a code review, specifically:
Sean McBride authored
305
6d8f5be Andy Matuschak Merging in David Smith's branch to fix bug #230123. We now copy the rela...
andymatuschak authored
306 // Copy the relauncher into a temporary directory so we can get to it after the new version's installed.
a885437 Uli Kusterer Manually merge project file (recreating the finish_installation applicat...
uliwitness authored
307 NSString *relaunchPathToCopy = [SPARKLE_BUNDLE pathForResource:@"finish_installation" ofType:@"app"];
86b6502 Andy Matuschak Fixing a merge error which put finish_installation in /tmp rather than i...
andymatuschak authored
308 NSString *targetPath = [[host appSupportPath] stringByAppendingPathComponent:[relaunchPathToCopy lastPathComponent]];
7316a00 Andy Matuschak Removed SL-deprecated NSFileManager methods. Left the old ones around #i...
andymatuschak authored
309 // Only the paranoid survive: if there's already a stray copy of relaunch there, we would have problems.
310 NSError *error = nil;
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
311 #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
312 [[NSFileManager defaultManager] createDirectoryAtPath: [targetPath stringByDeletingLastPathComponent] attributes: [NSDictionary dictionary]];
313 #else
a885437 Uli Kusterer Manually merge project file (recreating the finish_installation applicat...
uliwitness authored
314 [[NSFileManager defaultManager] createDirectoryAtPath: [targetPath stringByDeletingLastPathComponent] withIntermediateDirectories: YES attributes: [NSDictionary dictionary] error: &error];
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
315 #endif
bbcfe7e Uli Kusterer - More WIP creating finish_installation that waits
uliwitness authored
316
7316a00 Andy Matuschak Removed SL-deprecated NSFileManager methods. Left the old ones around #i...
andymatuschak authored
317 // Only the paranoid survive: if there's already a stray copy of relaunch there, we would have problems.
7cd8974 Uli Kusterer Make Sparkle more robust when the permissions of ~/Library/Application S...
uliwitness authored
318 if( [SUPlainInstaller copyPathWithAuthentication: relaunchPathToCopy overPath: targetPath temporaryName: nil error: &error] )
6d8f5be Andy Matuschak Merging in David Smith's branch to fix bug #230123. We now copy the rela...
andymatuschak authored
319 relaunchPath = [targetPath retain];
7316a00 Andy Matuschak Removed SL-deprecated NSFileManager methods. Left the old ones around #i...
andymatuschak authored
320 else
321 [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SURelaunchError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:SULocalizedString(@"An error occurred while extracting the archive. Please try again later.", nil), NSLocalizedDescriptionKey, [NSString stringWithFormat:@"Couldn't copy relauncher (%@) to temporary path (%@)! %@", relaunchPathToCopy, targetPath, (error ? [error localizedDescription] : @"")], NSLocalizedFailureReasonErrorKey, nil]]];
6d8f5be Andy Matuschak Merging in David Smith's branch to fix bug #230123. We now copy the rela...
andymatuschak authored
322
c96aa2e Andy Matuschak The finish_installation tool will not relaunch the host app if it's usin...
andymatuschak authored
323 [[NSNotificationCenter defaultCenter] postNotificationName:SUUpdaterWillRestartNotification object:self];
324 if ([[updater delegate] respondsToSelector:@selector(updaterWillRelaunchApplication:)])
325 [[updater delegate] updaterWillRelaunchApplication:updater];
326
327 if(!relaunchPath || ![[NSFileManager defaultManager] fileExistsAtPath:relaunchPath])
328 {
329 // Note that we explicitly use the host app's name here, since updating plugin for Mail relaunches Mail, not just the plugin.
330 [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SURelaunchError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:SULocalizedString(@"An error occurred while relaunching %1$@, but the new version will be available next time you run %1$@.", nil), [host name]], NSLocalizedDescriptionKey, [NSString stringWithFormat:@"Couldn't find the relauncher (expected to find it at %@)", relaunchPath], NSLocalizedFailureReasonErrorKey, nil]]];
331 // We intentionally don't abandon the update here so that the host won't initiate another.
332 return;
333 }
334
335 NSString *pathToRelaunch = [host bundlePath];
336 if ([[updater delegate] respondsToSelector:@selector(pathToRelaunchForUpdater:)])
337 pathToRelaunch = [[updater delegate] pathToRelaunchForUpdater:updater];
338 NSString *relaunchToolPath = [relaunchPath stringByAppendingPathComponent: @"/Contents/MacOS/finish_installation"];
bf07a94 Matt Stevens Pass both host and executable paths to finish_installation
mattstevens authored
339 [NSTask launchedTaskWithLaunchPath: relaunchToolPath arguments:[NSArray arrayWithObjects:[host bundlePath], pathToRelaunch, [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]], tempDir, relaunch ? @"1" : @"0", nil]];
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
340
c96aa2e Andy Matuschak The finish_installation tool will not relaunch the host app if it's usin...
andymatuschak authored
341 [NSApp terminate:self];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
342 }
343
fa67107 Andy Matuschak Changing download destination from ~/Desktop to ~/Library/App Support/HO...
andymatuschak authored
344 - (void)cleanUpDownload
46f9b4a Andy Matuschak Fixes 242566
andymatuschak authored
345 {
fa67107 Andy Matuschak Changing download destination from ~/Desktop to ~/Library/App Support/HO...
andymatuschak authored
346 if (tempDir != nil) // tempDir contains downloadPath, so we implicitly delete both here.
347 {
348 BOOL success = NO;
4fad530 Change availability checks so that they build on 10.4
Stuart Morgan authored
349 #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
fa67107 Andy Matuschak Changing download destination from ~/Desktop to ~/Library/App Support/HO...
andymatuschak authored
350 success = [[NSFileManager defaultManager] removeFileAtPath: tempDir handler: nil]; // Clean up the copied relauncher
54299d7 added #ifdef's for Tiger support
August Joki authored
351 #else
fa67107 Andy Matuschak Changing download destination from ~/Desktop to ~/Library/App Support/HO...
andymatuschak authored
352 NSError * error = nil;
353 success = [[NSFileManager defaultManager] removeItemAtPath: tempDir error: &error]; // Clean up the copied relauncher
54299d7 added #ifdef's for Tiger support
August Joki authored
354 #endif
fa67107 Andy Matuschak Changing download destination from ~/Desktop to ~/Library/App Support/HO...
andymatuschak authored
355 if( !success )
356 [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:[tempDir stringByDeletingLastPathComponent] destination:@"" files:[NSArray arrayWithObject:[tempDir lastPathComponent]] tag:NULL];
357 }
46f9b4a Andy Matuschak Fixes 242566
andymatuschak authored
358 }
359
98832c4 Andy Matuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Spa...
andymatuschak authored
360 - (void)installerForHost:(SUHost *)aHost failedWithError:(NSError *)error
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
361 {
98832c4 Andy Matuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Spa...
andymatuschak authored
362 if (aHost != host) { return; }
67d53c0 Uli Kusterer Get rid of deprecation warnings on 10.6/Xcode 4 while still allowing to ...
uliwitness authored
363 #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
364 [[NSFileManager defaultManager] removeFileAtPath: relaunchPath handler: nil]; // Clean up the copied relauncher
365 #else
366 NSError * dontThrow = nil;
367 [[NSFileManager defaultManager] removeItemAtPath: relaunchPath error: &dontThrow]; // Clean up the copied relauncher
368 #endif
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
369 [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SUInstallationError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:SULocalizedString(@"An error occurred while installing the update. Please try again later.", nil), NSLocalizedDescriptionKey, [error localizedDescription], NSLocalizedFailureReasonErrorKey, nil]]];
370 }
371
372 - (void)abortUpdate
373 {
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
374 [[self retain] autorelease]; // In case the notification center was the last one holding on to us.
fa67107 Andy Matuschak Changing download destination from ~/Desktop to ~/Library/App Support/HO...
andymatuschak authored
375 [self cleanUpDownload];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
376 [[NSNotificationCenter defaultCenter] removeObserver:self];
377 [super abortUpdate];
378 }
379
380 - (void)abortUpdateWithError:(NSError *)error
381 {
382 if ([error code] != SUNoUpdateError) // Let's not bother logging this.
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
383 SULog(@"Sparkle Error: %@", [error localizedDescription]);
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
384 if ([error localizedFailureReason])
43a0a7d Uli Kusterer Merge of changes from SVN repository:
uliwitness authored
385 SULog(@"Sparkle Error (continued): %@", [error localizedFailureReason]);
0a4bc65 Andy Matuschak No longer leaking the NSURLDownload of the update archive.
andymatuschak authored
386 if (download)
387 [download cancel];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
388 [self abortUpdate];
389 }
390
391 - (void)dealloc
392 {
46312a2 Andy Matuschak Fixes 258060
andymatuschak authored
393 [updateItem release];
6e648f1 Mark Rowe Add support for parsing an extended <sparkle:deltas> element in the appc...
bdash authored
394 [nonDeltaUpdateItem release];
0a4bc65 Andy Matuschak No longer leaking the NSURLDownload of the update archive.
andymatuschak authored
395 [download release];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
396 [downloadPath release];
0e609cc Uli Kusterer Make sure we delete the temp directory.
uliwitness authored
397 [tempDir release];
6d8f5be Andy Matuschak Merging in David Smith's branch to fix bug #230123. We now copy the rela...
andymatuschak authored
398 [relaunchPath release];
bc3be9a Touched practically every line of code in a super-monster-awesome refact...
andym authored
399 [super dealloc];
400 }
401
402 @end
Something went wrong with that request. Please try again.