Revision: 2684
http://skim-app.svn.sourceforge.net/skim-app/?rev=2684&view=rev
Author: hofman
Date: 2007-08-19 04:28:18 -0700 (Sun, 19 Aug 2007)
Log Message:
-----------
Use carbon file manager to copy and delete items for disk image creation.
Modified Paths:
--------------
trunk/Files_SKExtensions.h
trunk/Files_SKExtensions.m
trunk/SKDocument.m
Modified: trunk/Files_SKExtensions.h
===================================================================
--- trunk/Files_SKExtensions.h 2007-08-18 19:40:05 UTC (rev 2683)
+++ trunk/Files_SKExtensions.h 2007-08-19 11:28:18 UTC (rev 2684)
@@ -43,4 +43,9 @@
extern BOOL SKFileIsInTrash(NSURL *fileURL);
extern BOOL SKFileExistsAtPath(NSString *path);
extern NSDate *SKFileModificationDateAtPath(NSString *path);
-extern NSString *SKTemporaryDirectoryCreating(BOOL create);
+extern NSString *SKUniqueDirectoryCreating(NSString *basePath, BOOL create);
+
+extern OSErr FSDeleteContainerContents(const FSRef *container);
+extern OSErr FSDeleteContainer(const FSRef *container);
+extern OSErr FSPathDeleteContainer(const UInt8 *containerPath);
+
\ No newline at end of file
Modified: trunk/Files_SKExtensions.m
===================================================================
--- trunk/Files_SKExtensions.m 2007-08-18 19:40:05 UTC (rev 2683)
+++ trunk/Files_SKExtensions.m 2007-08-19 11:28:18 UTC (rev 2684)
@@ -81,22 +81,160 @@
return nil;
}
-NSString *SKTemporaryDirectoryCreating(BOOL create) {
- NSString *baseTmpDir = [NSTemporaryDirectory()
stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]];
- NSString *tmpDir = baseTmpDir;
- NSString *tmpDirName;
- int i = 0;
+NSString *SKUniqueDirectoryCreating(NSString *basePath, BOOL create) {
+ CFUUIDRef uuid = CFUUIDCreate(NULL);
+ NSString *tmpDirName = [(NSString *)CFUUIDCreateString(NULL, uuid)
autorelease];
+ CFRelease(uuid);
+
BOOL success = YES;
- while (SKFileExistsAtPath(tmpDir))
- tmpDir = [baseTmpDir stringByAppendingFormat:@"-%i", ++i];
-
- tmpDirName = [tmpDir lastPathComponent];
- if (success && create) {
+ if (create) {
FSRef tmpRef;
- success = noErr == FSPathMakeRef((UInt8 *)[NSTemporaryDirectory()
fileSystemRepresentation], &tmpRef, NULL) &&
+ success = noErr == FSPathMakeRef((UInt8 *)[basePath
fileSystemRepresentation], &tmpRef, NULL) &&
noErr == FSCreateDirectoryUnicode(&tmpRef, [tmpDirName
length], (const UniChar *)[tmpDirName
cStringUsingEncoding:NSUnicodeStringEncoding], kFSCatInfoNone, NULL, NULL,
NULL, NULL);
}
- return success ? tmpDir : nil;
+ return success ? [basePath stringByAppendingPathComponent:tmpDirName] :
nil;
}
+
+// These are taken from MoreFilesX
+
+struct FSDeleteContainerGlobals
+{
+ OSErr result;
/* result */
+ ItemCount actualObjects;
/* number of objects returned */
+ FSCatalogInfo catalogInfo; /*
FSCatalogInfo */
+};
+typedef struct FSDeleteContainerGlobals FSDeleteContainerGlobals;
+
+static
+void
+FSDeleteContainerLevel(
+ const FSRef *container,
+ FSDeleteContainerGlobals *theGlobals)
+{
+ /* level locals */
+ FSIterator iterator;
+ FSRef itemToDelete;
+ UInt16 nodeFlags;
+
+ /* Open FSIterator for flat access and give delete optimization hint */
+ theGlobals->result = FSOpenIterator(container, kFSIterateFlat +
kFSIterateDelete, &iterator);
+ require_noerr(theGlobals->result, FSOpenIterator);
+
+ /* delete the contents of the directory */
+ do
+ {
+ /* get 1 item to delete */
+ theGlobals->result = FSGetCatalogInfoBulk(iterator, 1,
&theGlobals->actualObjects,
+ NULL,
kFSCatInfoNodeFlags, &theGlobals->catalogInfo,
+ &itemToDelete,
NULL, NULL);
+ if ( (noErr == theGlobals->result) && (1 ==
theGlobals->actualObjects) )
+ {
+ /* save node flags in local in case we have to recurse
*/
+ nodeFlags = theGlobals->catalogInfo.nodeFlags;
+
+ /* is it a file or directory? */
+ if ( 0 != (nodeFlags & kFSNodeIsDirectoryMask) )
+ {
+ /* it's a directory -- delete its contents
before attempting to delete it */
+ FSDeleteContainerLevel(&itemToDelete,
theGlobals);
+ }
+ /* are we still OK to delete? */
+ if ( noErr == theGlobals->result )
+ {
+ /* is item locked? */
+ if ( 0 != (nodeFlags & kFSNodeLockedMask) )
+ {
+ /* then attempt to unlock it (ignore
result since FSDeleteObject will set it correctly) */
+ theGlobals->catalogInfo.nodeFlags =
nodeFlags & ~kFSNodeLockedMask;
+ (void) FSSetCatalogInfo(&itemToDelete,
kFSCatInfoNodeFlags, &theGlobals->catalogInfo);
+ }
+ /* delete the item */
+ theGlobals->result =
FSDeleteObject(&itemToDelete);
+ }
+ }
+ } while ( noErr == theGlobals->result );
+
+ /* we found the end of the items normally, so return noErr */
+ if ( errFSNoMoreItems == theGlobals->result )
+ {
+ theGlobals->result = noErr;
+ }
+
+ /* close the FSIterator (closing an open iterator should never fail) */
+ verify_noerr(FSCloseIterator(iterator));
+
+FSOpenIterator:
+
+ return;
+}
+
+OSErr
+FSDeleteContainerContents(
+ const FSRef *container)
+{
+ FSDeleteContainerGlobals theGlobals;
+
+ /* delete container's contents */
+ FSDeleteContainerLevel(container, &theGlobals);
+
+ return ( theGlobals.result );
+}
+
+OSErr
+FSDeleteContainer(
+ const FSRef *container)
+{
+ OSErr result;
+ FSCatalogInfo catalogInfo;
+
+ /* get nodeFlags for container */
+ result = FSGetCatalogInfo(container, kFSCatInfoNodeFlags, &catalogInfo,
NULL, NULL,NULL);
+ require_noerr(result, FSGetCatalogInfo);
+
+ /* make sure container is a directory */
+ require_action(0 != (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask),
ContainerNotDirectory, result = dirNFErr);
+
+ /* delete container's contents */
+ result = FSDeleteContainerContents(container);
+ require_noerr(result, FSDeleteContainerContents);
+
+ /* is container locked? */
+ if ( 0 != (catalogInfo.nodeFlags & kFSNodeLockedMask) )
+ {
+ /* then attempt to unlock container (ignore result since
FSDeleteObject will set it correctly) */
+ catalogInfo.nodeFlags &= ~kFSNodeLockedMask;
+ (void) FSSetCatalogInfo(container, kFSCatInfoNodeFlags,
&catalogInfo);
+ }
+
+ /* delete the container */
+ result = FSDeleteObject(container);
+
+FSDeleteContainerContents:
+ContainerNotDirectory:
+FSGetCatalogInfo:
+
+ return ( result );
+}
+
+OSErr
+FSPathDeleteContainer(
+ const UInt8 *containerPath)
+{
+ OSErr result;
+ FSRef container;
+ Boolean isDirectory;
+
+ result = FSPathMakeRef(containerPath, &container, &isDirectory);
+ if (isDirectory == false)
+ result = errFSNotAFolder;
+ require_noerr(result, FSPathMakeRef);
+
+ /* delete the container recursively */
+ result = FSDeleteContainer(&container);
+
+FSPathMakeRef:
+
+ return ( result );
+}
Modified: trunk/SKDocument.m
===================================================================
--- trunk/SKDocument.m 2007-08-18 19:40:05 UTC (rev 2683)
+++ trunk/SKDocument.m 2007-08-19 11:28:18 UTC (rev 2684)
@@ -591,7 +591,7 @@
NSAutoreleasePool *pool = [NSAutoreleasePool new];
- NSString *tmpDir = SKTemporaryDirectoryCreating(YES);
+ NSString *tmpDir = SKUniqueDirectoryCreating(NSTemporaryDirectory(),
YES);
BOOL success = tmpDir != nil;
NSString *sourcePath = [[[info objectForKey:@"sourcePath"] copy]
autorelease];
@@ -599,9 +599,11 @@
NSString *name = [[targetPath lastPathComponent]
stringByDeletingPathExtension];
NSString *tmpImagePath1 = [[tmpDir
stringByAppendingPathComponent:name]
stringByAppendingPathExtension:@"sparseimage"];
NSString *tmpImagePath2 = [[tmpDir
stringByAppendingPathComponent:name] stringByAppendingPathExtension:@"dmg"];
- NSString *tmpMountPath = [tmpDir stringByAppendingPathComponent:name];
+ NSString *tmpMountPath = SKUniqueDirectoryCreating(@"/tmp", NO); // we
don't use tmpDir because the mountpath has a maximum length of 90
BOOL didAttach = NO;
+
+
@try {
if (success) {
success = [NSTask runTaskWithLaunchPath:@"/usr/bin/hdiutil"
@@ -619,10 +621,7 @@
}
if (success) {
- // we can't use NSFileManager because it's not thread safe,
while FSPathCopyObjectSync complains about not enough space
- success = [NSTask runTaskWithLaunchPath:@"/bin/cp"
- arguments:[NSArray
arrayWithObjects:@"-f", sourcePath, tmpMountPath, nil]
- currentDirectoryPath:tmpDir];
+ success = noErr == FSPathCopyObjectSync((const char
*)[sourcePath fileSystemRepresentation], (const char *)[tmpMountPath
fileSystemRepresentation], (CFStringRef)[sourcePath lastPathComponent], NULL,
kFSFileOperationOverwrite);
}
if (didAttach) {
@@ -638,13 +637,10 @@
}
if (success) {
- success = [NSTask runTaskWithLaunchPath:@"/bin/cp"
- arguments:[NSArray
arrayWithObjects:@"-f", tmpImagePath2, targetPath, nil]
- currentDirectoryPath:tmpDir];
+ success = noErr == FSPathCopyObjectSync((const char
*)[tmpImagePath2 fileSystemRepresentation], (const char *)[[targetPath
stringByDeletingLastPathComponent] fileSystemRepresentation],
(CFStringRef)[targetPath lastPathComponent], NULL, kFSFileOperationOverwrite);
}
- // easier than FSDeleteObject, because that cannot delete the
directory recursively
- [NSTask launchedTaskWithLaunchPath:@"/bin/rm" arguments:[NSArray
arrayWithObjects:@"-rf", tmpDir, nil]];
+ FSPathDeleteContainer((const UInt8 *)[tmpDir
fileSystemRepresentation]);
}
@catch(id exception) {
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit