Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 83 lines (65 sloc) 3.263 kb
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
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
58a05e2 @andymatuschak Fixes 243533 (for real this time, I hope)
andymatuschak authored
15 + (BOOL)_canUnarchivePath:(NSString *)path
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
16 {
58a05e2 @andymatuschak Fixes 243533 (for real this time, I hope)
andymatuschak authored
17 return [[path pathExtension] isEqualToString:@"dmg"];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
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
dc249c1 @andymatuschak Fixes 246805
andymatuschak authored
31 NSString *mountPoint = [@"/Volumes" stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
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 {
dc249c1 @andymatuschak Fixes 246805
andymatuschak authored
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])
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
60 goto reportError;
61 }
62
63 [self performSelectorOnMainThread:@selector(_notifyDelegateOfSuccess) withObject:nil waitUntilDone:NO];
64 goto finally;
65
66 reportError:
67 [self performSelectorOnMainThread:@selector(_notifyDelegateOfFailure) withObject:nil waitUntilDone:NO];
68
69 finally:
70 if (mountedSuccessfully)
dc249c1 @andymatuschak Fixes 246805
andymatuschak authored
71 [NSTask launchedTaskWithLaunchPath:@"/usr/bin/hdiutil" arguments:[NSArray arrayWithObjects:@"detach", mountPoint, @"-force", nil]];
72 else
73 [[NSFileManager defaultManager] removeFileAtPath:mountPoint handler:nil];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
74 [pool drain];
75 }
76
77 + (void)load
78 {
79 [self _registerImplementation:self];
80 }
81
82 @end
Something went wrong with that request. Please try again.