Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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