Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 168 lines (141 sloc) 5.448 kB
49e3d81 Major refactoring, yay.
andym authored
1 //
2 // SUInstaller.m
3 // Sparkle
4 //
5 // Created by Andy Matuschak on 4/10/08.
6 // Copyright 2008 Andy Matuschak. All rights reserved.
7 //
8
9 #import "SUInstaller.h"
10 #import "SUPlainInstaller.h"
11 #import "SUPackageInstaller.h"
bbcfe7e @uliwitness - More WIP creating finish_installation that waits
uliwitness authored
12 #import "SUHost.h"
13 #import "SUConstants.h"
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
14 #import "SULog.h"
15
49e3d81 Major refactoring, yay.
andym authored
16
17 @implementation SUInstaller
18
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
19 static NSString* sUpdateFolder = nil;
20
21 +(NSString*) updateFolder
22 {
23 return sUpdateFolder;
24 }
25
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
26 + (BOOL)isAliasFolderAtPath:(NSString *)path
de9be8b @andymatuschak Fixes 244428
andymatuschak authored
27 {
28 FSRef fileRef;
29 OSStatus err = noErr;
30 Boolean aliasFileFlag, folderFlag;
31 NSURL *fileURL = [NSURL fileURLWithPath:path];
32
33 if (FALSE == CFURLGetFSRef((CFURLRef)fileURL, &fileRef))
34 err = coreFoundationUnknownErr;
35
36 if (noErr == err)
37 err = FSIsAliasFile(&fileRef, &aliasFileFlag, &folderFlag);
38
39 if (noErr == err)
40 return (BOOL)(aliasFileFlag && folderFlag);
41 else
42 return NO;
43 }
44
45
7a283bf @andymatuschak Fixes #133: Sparkle deleting/replacing the wrong executable when it u…
andymatuschak authored
46 + (void)installFromUpdateFolder:(NSString *)inUpdateFolder overHost:(SUHost *)host installationPath:(NSString *)installationPath delegate:delegate synchronously:(BOOL)synchronously versionComparator:(id <SUVersionComparison>)comparator
49e3d81 Major refactoring, yay.
andym authored
47 {
48 // Search subdirectories for the application
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
49 NSString *currentFile,
50 *newAppDownloadPath = nil,
bbcfe7e @uliwitness - More WIP creating finish_installation that waits
uliwitness authored
51 *bundleFileName = [[host bundlePath] lastPathComponent],
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
52 *alternateBundleFileName = [[host name] stringByAppendingPathExtension:[[host bundlePath] pathExtension]];
49e3d81 Major refactoring, yay.
andym authored
53 BOOL isPackage = NO;
65b071e If no suitable packages or bundles are found to be installed, Sparkle…
Grant Erickson authored
54 NSString *fallbackPackagePath = nil;
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
55 NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath: inUpdateFolder];
56
57 [sUpdateFolder release];
58 sUpdateFolder = [inUpdateFolder retain];
bbcfe7e @uliwitness - More WIP creating finish_installation that waits
uliwitness authored
59
49e3d81 Major refactoring, yay.
andym authored
60 while ((currentFile = [dirEnum nextObject]))
61 {
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
62 NSString *currentPath = [inUpdateFolder stringByAppendingPathComponent:currentFile];
0e99700 Added fetching of CFBundleName as a fallback for CFBundleDisplayName …
andym authored
63 if ([[currentFile lastPathComponent] isEqualToString:bundleFileName] ||
64 [[currentFile lastPathComponent] isEqualToString:alternateBundleFileName]) // We found one!
49e3d81 Major refactoring, yay.
andym authored
65 {
66 isPackage = NO;
67 newAppDownloadPath = currentPath;
68 break;
69 }
65b071e If no suitable packages or bundles are found to be installed, Sparkle…
Grant Erickson authored
70 else if ([[currentFile pathExtension] isEqualToString:@"pkg"] ||
71 [[currentFile pathExtension] isEqualToString:@"mpkg"])
49e3d81 Major refactoring, yay.
andym authored
72 {
65b071e If no suitable packages or bundles are found to be installed, Sparkle…
Grant Erickson authored
73 if ([[[currentFile lastPathComponent] stringByDeletingPathExtension] isEqualToString:[bundleFileName stringByDeletingPathExtension]])
74 {
75 isPackage = YES;
76 newAppDownloadPath = currentPath;
77 break;
78 }
79 else
80 {
81 // Remember any other non-matching packages we have seen should we need to use one of them as a fallback.
82 fallbackPackagePath = currentPath;
83 }
49e3d81 Major refactoring, yay.
andym authored
84 }
13deac9 @andymatuschak Fixes 271378
andymatuschak authored
85 else
86 {
87 // Try matching on bundle identifiers in case the user has changed the name of the host app
88 NSBundle *incomingBundle = [NSBundle bundleWithPath:currentPath];
89 if(incomingBundle && [[incomingBundle bundleIdentifier] isEqualToString:[[host bundle] bundleIdentifier]])
90 {
91 isPackage = NO;
92 newAppDownloadPath = currentPath;
93 break;
94 }
95 }
49e3d81 Major refactoring, yay.
andym authored
96
e743596 @andymatuschak Fixing Bug #421608: "Update fails if more than one .app exists in the…
andymatuschak authored
97 // Some DMGs have symlinks into /Applications! That's no good!
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
98 if ([self isAliasFolderAtPath:currentPath])
49e3d81 Major refactoring, yay.
andym authored
99 [dirEnum skipDescendents];
100 }
bbcfe7e @uliwitness - More WIP creating finish_installation that waits
uliwitness authored
101
65b071e If no suitable packages or bundles are found to be installed, Sparkle…
Grant Erickson authored
102 // We don't have a valid path. Try to use the fallback package.
103
104 if (newAppDownloadPath == nil && fallbackPackagePath != nil)
105 {
106 isPackage = YES;
107 newAppDownloadPath = fallbackPackagePath;
108 }
49e3d81 Major refactoring, yay.
andym authored
109
110 if (newAppDownloadPath == nil)
111 {
7a283bf @andymatuschak Fixes #133: Sparkle deleting/replacing the wrong executable when it u…
andymatuschak authored
112 [self finishInstallationToPath:installationPath withResult:NO host:host error:[NSError errorWithDomain:SUSparkleErrorDomain code:SUMissingUpdateError userInfo:[NSDictionary dictionaryWithObject:@"Couldn't find an appropriate update in the downloaded package." forKey:NSLocalizedDescriptionKey]] delegate:delegate];
49e3d81 Major refactoring, yay.
andym authored
113 }
114 else
115 {
7a283bf @andymatuschak Fixes #133: Sparkle deleting/replacing the wrong executable when it u…
andymatuschak authored
116 [(isPackage ? [SUPackageInstaller class] : [SUPlainInstaller class]) performInstallationToPath:installationPath fromPath:newAppDownloadPath host:host delegate:delegate synchronously:synchronously versionComparator:comparator];
49e3d81 Major refactoring, yay.
andym authored
117 }
118 }
119
7a283bf @andymatuschak Fixes #133: Sparkle deleting/replacing the wrong executable when it u…
andymatuschak authored
120 + (void)mdimportInstallationPath:(NSString *)installationPath
072a73b Run mdimport on bundles after installing them
David Smith authored
121 {
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
122 // *** GETS CALLED ON NON-MAIN THREAD!
123
4f8d745 @uliwitness Changed a few NSLogs() to SULogs().
uliwitness authored
124 SULog( @"mdimporting" );
125
072a73b Run mdimport on bundles after installing them
David Smith authored
126 NSTask *mdimport = [[[NSTask alloc] init] autorelease];
127 [mdimport setLaunchPath:@"/usr/bin/mdimport"];
7a283bf @andymatuschak Fixes #133: Sparkle deleting/replacing the wrong executable when it u…
andymatuschak authored
128 [mdimport setArguments:[NSArray arrayWithObject:installationPath]];
05b75aa @andymatuschak Fixes Bug #321761: Update crashes below NSTask if /usr/bin/mdimport d…
andymatuschak authored
129 @try
130 {
131 [mdimport launch];
4d70069 @uliwitness Make sure mdimport is run synchronously, not asynchronously.
uliwitness authored
132 [mdimport waitUntilExit];
05b75aa @andymatuschak Fixes Bug #321761: Update crashes below NSTask if /usr/bin/mdimport d…
andymatuschak authored
133 }
134 @catch (NSException * launchException)
135 {
136 // No big deal.
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
137 SULog(@"Sparkle Error: %@", [launchException description]);
05b75aa @andymatuschak Fixes Bug #321761: Update crashes below NSTask if /usr/bin/mdimport d…
andymatuschak authored
138 }
072a73b Run mdimport on bundles after installing them
David Smith authored
139 }
140
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
141
142 #define SUNotifyDictHostKey @"SUNotifyDictHost"
143 #define SUNotifyDictErrorKey @"SUNotifyDictError"
144 #define SUNotifyDictDelegateKey @"SUNotifyDictDelegate"
145
7a283bf @andymatuschak Fixes #133: Sparkle deleting/replacing the wrong executable when it u…
andymatuschak authored
146 + (void)finishInstallationToPath:(NSString *)installationPath withResult:(BOOL)result host:(SUHost *)host error:(NSError *)error delegate:delegate
49e3d81 Major refactoring, yay.
andym authored
147 {
d7774c0 performed a code review, specifically:
Sean McBride authored
148 if (result)
49e3d81 Major refactoring, yay.
andym authored
149 {
7a283bf @andymatuschak Fixes #133: Sparkle deleting/replacing the wrong executable when it u…
andymatuschak authored
150 [self mdimportInstallationPath:installationPath];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
151 if ([delegate respondsToSelector:@selector(installerFinishedForHost:)])
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
152 [delegate performSelectorOnMainThread: @selector(installerFinishedForHost:) withObject: host waitUntilDone: NO];
49e3d81 Major refactoring, yay.
andym authored
153 }
154 else
155 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
156 if ([delegate respondsToSelector:@selector(installerForHost:failedWithError:)])
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
157 [self performSelectorOnMainThread: @selector(notifyDelegateOfFailure:) withObject: [NSDictionary dictionaryWithObjectsAndKeys: host, SUNotifyDictHostKey, error, SUNotifyDictErrorKey, delegate, SUNotifyDictDelegateKey, nil] waitUntilDone: NO];
49e3d81 Major refactoring, yay.
andym authored
158 }
159 }
160
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
161
162 +(void) notifyDelegateOfFailure: (NSDictionary*)dict
163 {
164 [[dict objectForKey: SUNotifyDictDelegateKey] installerForHost: [dict objectForKey: SUNotifyDictHostKey] failedWithError: [dict objectForKey: SUNotifyDictErrorKey]];
165 }
166
49e3d81 Major refactoring, yay.
andym authored
167 @end
Something went wrong with that request. Please try again.