Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 132 lines (110 sloc) 4.476 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"
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
12 #import "SULog.h"
2fc1b66 @andymatuschak Fixing:
andymatuschak authored
13 #import <CoreServices/CoreServices.h>
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
14
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
15
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
16 @implementation SUDiskImageUnarchiver
17
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
18 + (BOOL)canUnarchivePath:(NSString *)path
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
19 {
58a05e2 @andymatuschak Fixes 243533 (for real this time, I hope)
andymatuschak authored
20 return [[path pathExtension] isEqualToString:@"dmg"];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
21 }
22
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
23 - (void)extractDMG
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
24 {
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
25 // GETS CALLED ON NON-MAIN THREAD!!!
26
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
27 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
28 BOOL mountedSuccessfully = NO;
29
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
30 SULog(@"Extracting %@ as a DMG", archivePath);
31
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
32 // get a unique mount point path
2fc1b66 @andymatuschak Fixing:
andymatuschak authored
33 NSString *mountPointName = nil;
34 NSString *mountPoint = nil;
35 FSRef tmpRef;
36 do
37 {
38 CFUUIDRef uuid = CFUUIDCreate(NULL);
d7774c0 performed a code review, specifically:
Sean McBride authored
39 if (uuid)
40 {
41 CFStringRef uuidString = CFUUIDCreateString(NULL, uuid);
756b37d code review of CFRelease usage, minor changes
Sean McBride authored
42 if (uuidString)
43 {
44 mountPoint = [@"/Volumes" stringByAppendingPathComponent:(NSString*)uuidString];
45 CFRelease(uuidString);
46 }
d7774c0 performed a code review, specifically:
Sean McBride authored
47 CFRelease(uuid);
48 }
2fc1b66 @andymatuschak Fixing:
andymatuschak authored
49 }
50 while (noErr == FSPathMakeRefWithOptions((UInt8 *)[mountPoint fileSystemRepresentation], kFSPathMakeRefDoNotFollowLeafSymlink, &tmpRef, NULL));
51
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
52 NSArray* arguments = [NSArray arrayWithObjects:@"attach", archivePath, @"-mountpoint", mountPoint, /*@"-noverify",*/ @"-nobrowse", @"-noautoopen", nil];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
53 // set up a pipe and push "yes" (y works too), this will accept any license agreement crap
54 // not every .dmg needs this, but this will make sure it works with everyone
55 NSData* yesData = [[[NSData alloc] initWithBytes:"yes\n" length:4] autorelease];
56
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
57 NSData *output = nil;
58 int returnCode = [NTSynchronousTask task:@"/usr/bin/hdiutil" directory:@"/" withArgs:arguments input:yesData output: &output];
59 if ( returnCode != 0 )
60 {
61 NSString* resultStr = output ? [[[NSString alloc] initWithData: output encoding: NSUTF8StringEncoding] autorelease] : nil;
62 SULog( @"hdiutil failed with code: %d data: <<%@>>", returnCode, resultStr );
63 goto reportError;
64 }
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
65 mountedSuccessfully = YES;
66
67 // Now that we've mounted it, we need to copy out its contents.
613b759 @cocoabythefire Fixed issues that led to crashes on Mac OS X 10.7 Lion.
cocoabythefire authored
68 if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
69 // On 10.6 and later we don't want to use the File Manager API and instead want to use NSFileManager (fixes #827357).
5457476 @andymatuschak Fixes #109: Error extracting dmg archives
andymatuschak authored
70 NSFileManager *manager = [[[NSFileManager alloc] init] autorelease];
71 NSError *error = nil;
72 NSArray *contents = [manager contentsOfDirectoryAtPath:mountPoint error:&error];
73 if (error)
74 {
75 SULog(@"Couldn't enumerate contents of archive mounted at %@: %@", mountPoint, error);
76 goto reportError;
77 }
78
d092ae9 @andymatuschak Resolved merge
andymatuschak authored
79 NSEnumerator *contentsEnumerator = [contents objectEnumerator];
80 NSString *item;
81 while ((item = [contentsEnumerator nextObject]))
5457476 @andymatuschak Fixes #109: Error extracting dmg archives
andymatuschak authored
82 {
d092ae9 @andymatuschak Resolved merge
andymatuschak authored
83 NSString *fromPath = [mountPoint stringByAppendingPathComponent:item];
84 NSString *toPath = [[archivePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:item];
5457476 @andymatuschak Fixes #109: Error extracting dmg archives
andymatuschak authored
85
86 SULog(@"copyItemAtPath:%@ toPath:%@", fromPath, toPath);
87
88 if (![manager copyItemAtPath:fromPath toPath:toPath error:&error])
89 {
90 SULog(@"Couldn't copy item: %@", error);
91 goto reportError;
92 }
93 }
613b759 @cocoabythefire Fixed issues that led to crashes on Mac OS X 10.7 Lion.
cocoabythefire authored
94 }
95 else {
96 FSRef srcRef, dstRef;
97 OSStatus err;
98 err = FSPathMakeRef((UInt8 *)[mountPoint fileSystemRepresentation], &srcRef, NULL);
99 if (err != noErr) goto reportError;
100 err = FSPathMakeRef((UInt8 *)[[archivePath stringByDeletingLastPathComponent] fileSystemRepresentation], &dstRef, NULL);
101 if (err != noErr) goto reportError;
102
103 err = FSCopyObjectSync(&srcRef, &dstRef, (CFStringRef)mountPointName, NULL, kFSFileOperationSkipSourcePermissionErrors);
104 if (err != noErr) goto reportError;
105 }
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
106
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
107 [self performSelectorOnMainThread:@selector(notifyDelegateOfSuccess) withObject:nil waitUntilDone:NO];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
108 goto finally;
109
110 reportError:
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
111 [self performSelectorOnMainThread:@selector(notifyDelegateOfFailure) withObject:nil waitUntilDone:NO];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
112
113 finally:
114 if (mountedSuccessfully)
dc249c1 @andymatuschak Fixes 246805
andymatuschak authored
115 [NSTask launchedTaskWithLaunchPath:@"/usr/bin/hdiutil" arguments:[NSArray arrayWithObjects:@"detach", mountPoint, @"-force", nil]];
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
116 else
117 SULog(@"Can't mount DMG %@",archivePath);
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
118 [pool drain];
119 }
120
d726066 fixed warning by moving private methods higher in the source file
Sean McBride authored
121 - (void)start
122 {
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
123 [NSThread detachNewThreadSelector:@selector(extractDMG) toTarget:self withObject:nil];
d726066 fixed warning by moving private methods higher in the source file
Sean McBride authored
124 }
125
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
126 + (void)load
127 {
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
128 [self registerImplementation:self];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
129 }
130
131 @end
Something went wrong with that request. Please try again.