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
Skim-app-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to