source: trunk/Sparkle/SUDiskImageUnarchiver.m @ 1046

Revision 128, 3.2 KB checked in by speck, 4 years ago (diff)

Fixed missing display of update notes in Sparkle. Embedded Sparkle so subversion has the proper version instead of having to download Sparkle and apply several patches.

Line 
1//
2//  SUDiskImageUnarchiver.m
3//  Sparkle
4//
5//  Created by Andy Matuschak on 6/16/08.
6//  Copyright 2008 Andy Matuschak. All rights reserved.
7//
8
9#import "SUDiskImageUnarchiver.h"
10#import "SUUnarchiver_Private.h"
11#import "NTSynchronousTask.h"
12
13@implementation SUDiskImageUnarchiver
14
15+ (BOOL)_canUnarchivePath:(NSString *)path
16{
17    return [[path pathExtension] isEqualToString:@"dmg"];
18}
19
20- (void)start
21{
22    [NSThread detachNewThreadSelector:@selector(_extractDMG) toTarget:self withObject:nil];
23}
24
25- (void)_extractDMG
26{       
27    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
28    BOOL mountedSuccessfully = NO;
29   
30    // get a unique mount point path
31    NSString *mountPoint = [@"/Volumes" stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
32   
33    if ([[NSFileManager defaultManager] fileExistsAtPath:mountPoint]) goto reportError;
34
35    // create mount point folder
36    [[NSFileManager defaultManager] createDirectoryAtPath:mountPoint attributes:nil];
37    if (![[NSFileManager defaultManager] fileExistsAtPath:mountPoint]) goto reportError;
38
39    NSArray* arguments = [NSArray arrayWithObjects:@"attach", archivePath, @"-mountpoint", mountPoint, @"-noverify", @"-nobrowse", @"-noautoopen", nil];
40    // set up a pipe and push "yes" (y works too), this will accept any license agreement crap
41    // not every .dmg needs this, but this will make sure it works with everyone
42    NSData* yesData = [[[NSData alloc] initWithBytes:"yes\n" length:4] autorelease];
43   
44    NSData *result = [NTSynchronousTask task:@"/usr/bin/hdiutil" directory:@"/" withArgs:arguments input:yesData];
45    if (!result) goto reportError;
46    mountedSuccessfully = YES;
47   
48    // Now that we've mounted it, we need to copy out its contents.
49    NSString *targetPath = [[archivePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:[mountPoint lastPathComponent]];
50    if (![[NSFileManager defaultManager] createDirectoryAtPath:targetPath attributes:nil]) goto reportError;
51   
52    // We can't just copyPath: from the volume root because that always fails. Seems to be a bug.
53    id subpathEnumerator = [[[NSFileManager defaultManager] directoryContentsAtPath:mountPoint] objectEnumerator], currentSubpath;
54    while ((currentSubpath = [subpathEnumerator nextObject]))
55    {
56        NSString *currentFullPath = [mountPoint stringByAppendingPathComponent:currentSubpath];
57        // Don't bother trying (and failing) to copy out files we can't read. That's not going to be the app anyway.
58        if (![[NSFileManager defaultManager] isReadableFileAtPath:currentFullPath]) continue;
59        if (![[NSFileManager defaultManager] copyPath:currentFullPath toPath:[targetPath stringByAppendingPathComponent:currentSubpath] handler:nil])
60            goto reportError;
61    }
62           
63    [self performSelectorOnMainThread:@selector(_notifyDelegateOfSuccess) withObject:nil waitUntilDone:NO];
64    goto finally;
65   
66reportError:
67    [self performSelectorOnMainThread:@selector(_notifyDelegateOfFailure) withObject:nil waitUntilDone:NO];
68
69finally:
70    if (mountedSuccessfully)
71        [NSTask launchedTaskWithLaunchPath:@"/usr/bin/hdiutil" arguments:[NSArray arrayWithObjects:@"detach", mountPoint, @"-force", nil]];
72    else
73        [[NSFileManager defaultManager] removeFileAtPath:mountPoint handler:nil];
74    [pool drain];
75}
76
77+ (void)load
78{
79    [self _registerImplementation:self];
80}
81
82@end
Note: See TracBrowser for help on using the repository browser.