Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 136 lines (113 sloc) 4.641 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
55eed9e @andymatuschak Fixes #113: Need to check isReadableFileAtPath: when copying out DMG …
andymatuschak authored
86 // We skip any files in the DMG which are not readable.
87 if (![manager isReadableFileAtPath:fromPath])
88 continue;
89
5457476 @andymatuschak Fixes #109: Error extracting dmg archives
andymatuschak authored
90 SULog(@"copyItemAtPath:%@ toPath:%@", fromPath, toPath);
91
92 if (![manager copyItemAtPath:fromPath toPath:toPath error:&error])
93 {
94 SULog(@"Couldn't copy item: %@", error);
95 goto reportError;
96 }
97 }
613b759 @cocoabythefire Fixed issues that led to crashes on Mac OS X 10.7 Lion.
cocoabythefire authored
98 }
99 else {
100 FSRef srcRef, dstRef;
101 OSStatus err;
102 err = FSPathMakeRef((UInt8 *)[mountPoint fileSystemRepresentation], &srcRef, NULL);
103 if (err != noErr) goto reportError;
104 err = FSPathMakeRef((UInt8 *)[[archivePath stringByDeletingLastPathComponent] fileSystemRepresentation], &dstRef, NULL);
105 if (err != noErr) goto reportError;
106
107 err = FSCopyObjectSync(&srcRef, &dstRef, (CFStringRef)mountPointName, NULL, kFSFileOperationSkipSourcePermissionErrors);
108 if (err != noErr) goto reportError;
109 }
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
110
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
111 [self performSelectorOnMainThread:@selector(notifyDelegateOfSuccess) withObject:nil waitUntilDone:NO];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
112 goto finally;
113
114 reportError:
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
115 [self performSelectorOnMainThread:@selector(notifyDelegateOfFailure) withObject:nil waitUntilDone:NO];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
116
117 finally:
118 if (mountedSuccessfully)
dc249c1 @andymatuschak Fixes 246805
andymatuschak authored
119 [NSTask launchedTaskWithLaunchPath:@"/usr/bin/hdiutil" arguments:[NSArray arrayWithObjects:@"detach", mountPoint, @"-force", nil]];
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
120 else
121 SULog(@"Can't mount DMG %@",archivePath);
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
122 [pool drain];
123 }
124
d726066 fixed warning by moving private methods higher in the source file
Sean McBride authored
125 - (void)start
126 {
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
127 [NSThread detachNewThreadSelector:@selector(extractDMG) toTarget:self withObject:nil];
d726066 fixed warning by moving private methods higher in the source file
Sean McBride authored
128 }
129
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
130 + (void)load
131 {
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
132 [self registerImplementation:self];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
133 }
134
135 @end
Something went wrong with that request. Please try again.