source: trunk/Sparkle/SUInstaller.m @ 1046

Revision 630, 4.2 KB checked in by speck, 3 years ago (diff)

Sparkle update with latest bug fixes.

Line 
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"
12#import "SUHost.h"
13
14@implementation SUInstaller
15
16+ (BOOL)_isAliasFolderAtPath:(NSString *)path
17{
18    FSRef fileRef;
19    OSStatus err = noErr;
20    Boolean aliasFileFlag, folderFlag;
21    NSURL *fileURL = [NSURL fileURLWithPath:path];
22   
23    if (FALSE == CFURLGetFSRef((CFURLRef)fileURL, &fileRef))
24        err = coreFoundationUnknownErr;
25   
26    if (noErr == err)
27        err = FSIsAliasFile(&fileRef, &aliasFileFlag, &folderFlag);
28   
29    if (noErr == err)
30        return (BOOL)(aliasFileFlag && folderFlag);
31    else
32        return NO; 
33}
34
35
36+ (void)installFromUpdateFolder:(NSString *)updateFolder overHost:(SUHost *)host delegate:delegate synchronously:(BOOL)synchronously versionComparator:(id <SUVersionComparison>)comparator updater:(SUUpdater*)updater
37{
38    // Search subdirectories for the application
39    NSString *currentFile, *newAppDownloadPath = nil, *bundleFileName = [[host bundlePath] lastPathComponent], *alternateBundleFileName = [[host name] stringByAppendingPathExtension:[[host bundlePath] pathExtension]];
40    BOOL isPackage = NO;
41    NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:updateFolder];
42    while ((currentFile = [dirEnum nextObject]))
43    {
44        NSString *currentPath = [updateFolder stringByAppendingPathComponent:currentFile];     
45        if ([[currentFile lastPathComponent] isEqualToString:bundleFileName] ||
46            [[currentFile lastPathComponent] isEqualToString:alternateBundleFileName]) // We found one!
47        {
48            isPackage = NO;
49            newAppDownloadPath = currentPath;
50            break;
51        }
52        else if (([[currentFile pathExtension] isEqualToString:@"pkg"] || [[currentFile pathExtension] isEqualToString:@"mpkg"]) &&
53                 [[[currentFile lastPathComponent] stringByDeletingPathExtension] isEqualToString:[bundleFileName stringByDeletingPathExtension]])
54        {
55            isPackage = YES;
56            newAppDownloadPath = currentPath;
57            break;
58        }
59        else
60        {
61            // Try matching on bundle identifiers in case the user has changed the name of the host app
62            NSBundle *incomingBundle = [NSBundle bundleWithPath:currentPath];
63            if(incomingBundle && [[incomingBundle bundleIdentifier] isEqualToString:[[host bundle] bundleIdentifier]])
64            {
65                isPackage = NO;
66                newAppDownloadPath = currentPath;
67                break;
68            }
69        }
70       
71        // Some DMGs have symlinks into /Applications! That's no good! And there's no point in looking in bundles.
72        if ([self _isAliasFolderAtPath:currentPath] ||
73            [[currentFile pathExtension] isEqualToString:[[host bundlePath] pathExtension]] ||
74            [[currentFile pathExtension] isEqualToString:@"pkg"] ||
75            [[currentFile pathExtension] isEqualToString:@"mpkg"])
76        {
77            [dirEnum skipDescendents];
78        }       
79    }
80   
81    if (newAppDownloadPath == nil)
82    {
83        [self _finishInstallationWithResult: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];
84    }
85    else
86    {
87        if ([delegate respondsToSelector:@selector(installUpdateWithPath:isPackage:)]) {
88            if ([delegate installUpdateWithPath:newAppDownloadPath isPackage:isPackage]) {
89                [self _finishInstallationWithResult:YES host:host error:NULL delegate:delegate];
90                return;
91            }
92        }
93        [(isPackage ? [SUPackageInstaller class] : [SUPlainInstaller class]) performInstallationWithPath:newAppDownloadPath host:host delegate:delegate synchronously:synchronously versionComparator:comparator];
94    }
95}
96
97+ (void)_mdimportHost:(SUHost *)host
98{
99    NSTask *mdimport = [[[NSTask alloc] init] autorelease];
100    [mdimport setLaunchPath:@"/usr/bin/mdimport"];
101    [mdimport setArguments:[NSArray arrayWithObject:[host bundlePath]]];
102    [mdimport launch];
103}
104
105+ (void)_finishInstallationWithResult:(BOOL)result host:(SUHost *)host error:(NSError *)error delegate:delegate
106{
107    if (result == YES)
108    {
109        [self _mdimportHost:host];
110        if ([delegate respondsToSelector:@selector(installerFinishedForHost:)])
111            [delegate installerFinishedForHost:host];
112    }
113    else
114    {
115        if ([delegate respondsToSelector:@selector(installerForHost:failedWithError:)])
116            [delegate installerForHost:host failedWithError:error];
117    }       
118}
119
120@end
Note: See TracBrowser for help on using the repository browser.