// ================================================================ // Copyright (c) 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ================================================================ // // GMUserFileSystem.h // // Created by ted on 12/29/07. // Based on FUSEFileSystem originally by alcor. // #import @class GMUserFileSystemInternal; @interface GMUserFileSystem : NSObject { @private GMUserFileSystemInternal* internal_; } - (id)initWithDelegate:(id)delegate isThreadSafe:(BOOL)isThreadSafe; - (void)setDelegate:(id)delegate; - (id)delegate; // Mount the filesystem at the given path. The set of available options can // be found at: http://code.google.com/p/macfuse/wiki/OPTIONS // For example, to turn on debug output add @"debug" to the options NSArray. // If the mount fails, a kGMUserFileSystemMountFailed notification will be posted // to the default notification center. See Notifications below. - (void)mountAtPath:(NSString *)mountPath withOptions:(NSArray *)options; // Advanced mount call. You can use this to mount from a command-line program // as follows: // For an app, use: shouldForeground=YES, detachNewThread=YES // For a daemon: shouldForeground=NO, detachNewThread=NO // For debug output: shouldForeground=YES, detachNewThread=NO // For a daemon+runloop: shouldForeground=NO, detachNewThread=YES // - NOTE: I've never tried daemon+runloop; maybe it doesn't make sense? // If the mount fails, a kGMUserFileSystemMountFailed notification will be posted // to the default notification center. See Notifications below. - (void)mountAtPath:(NSString *)mountPath withOptions:(NSArray *)options shouldForeground:(BOOL)shouldForeground // Recommend: YES detachNewThread:(BOOL)detachNewThread; // Recommend: YES // Unmount the filesystem. - (void)unmount; @end #pragma mark Notifications // The GMUserFileSystem will post lifecycle notifications to the defaultCenter. // Since the underlying GMUserFileSystem implementation is multi-threaded, you // should assume that notifications will not be posted on the main thread. The // object will always be the GMUserFileSystem* and the userInfo will always // contain at least the following: // kGMUserFileSystemMountPathkey -> NSString* that is the mount path // Error domain for GMUserFileSystem specific errors. extern NSString* const kGMUserFileSystemErrorDomain; // Key in notification dictionary for mount path (@"mountPath" for legacy) extern NSString* const kGMUserFileSystemMountPathKey; // Key in notification dictionary for an error (@"error" for legacy reasons) extern NSString* const kGMUserFileSystemErrorKey; // Notification sent when the mountAtPath operation fails. The userInfo will // contain an kGMUserFileSystemErrorKey with an NSError*. extern NSString* const kGMUserFileSystemMountFailed; // Notification sent after the filesystem is successfully mounted. extern NSString* const kGMUserFileSystemDidMount; // Notification sent after the filesystem is successfully unmounted. extern NSString* const kGMUserFileSystemDidUnmount; #pragma mark Additional Item Attribute Keys // For st_flags (see man 2 stat). Value is an NSNumber* with uint32 value. extern NSString* const kGMUserFileSystemFileFlagsKey; // For st_ctimespec (see man 2 stat). Last file status change time. extern NSString* const kGMUserFileSystemFileChangeDateKey; // For file backup date. extern NSString* const kGMUserFileSystemFileBackupDateKey; #pragma mark - #pragma mark File Delegate Protocol // The openFileAtPath: and createFileAtPath: operations have fileDelegate as an // out-parameter. Any GMUserFileSystemFileDelegate method that the fileDelegate // implements will be called instead of the corresponding method on the // GMUserFileSystem's delegate. @interface NSObject (GMUserFileSystemFileDelegate) // BSD-equivalent: read(2) - (int)readToBuffer:(char *)buffer size:(size_t)size offset:(off_t)offset error:(NSError **)error; // BSD-equivalent: write(2) - (int)writeFromBuffer:(const char *)buffer size:(size_t)size offset:(off_t)offset error:(NSError **)error; // BSD-equivalent: ftruncate(2) - (BOOL)truncateToOffset:(off_t)offset error:(NSError **)error; @end #pragma mark GMUserFileSystem Delegate Protocols // The GMUserFileSystem's delegate can implement any of the below protocols. // In most cases you can selectively choose which methods of a protocol to // implement. @interface NSObject (GMUserFileSystemLifecycle) - (void)willMount; - (void)willUnmount; @end @interface NSObject (GMUserFileSystemResourceForks) // Implementing any GMUserFileSystemResourceForks method turns on automatic // handling of FinderInfo and ResourceForks. In 10.5 and later these are // provided via extended attributes while in 10.4 we use "._" files. // The Finder flags to use for the given path. Include kHasCustomIcon if you // want to display a custom icon for a file or directory. If you do not // implement this then iconDataForPath will be called instead to probe for the // existence of a custom icon. - (UInt16)finderFlagsAtPath:(NSString *)path; // The raw .icns file data to use as the custom icon for the file/directory. // Return nil if the path does not have a custom icon. - (NSData *)iconDataAtPath:(NSString *)path; // The url for the .webloc file at path. This is only called for .webloc files. - (NSURL *)URLOfWeblocAtPath:(NSString *)path; @end @interface NSObject (GMUserFileSystemOperations) // These are the core methods that your filesystem needs to implement. Unless // otherwise noted, they typically should behave like the NSFileManager // equivalent. However, the error codes that they return should correspond to // the BSD-equivalent call and be in the NSPOSIXErrorDomain. // // For a read-only filesystem, you can typically pick-and-choose which methods // to implement. For example, a minimal read-only filesystem might implement: // // - (NSArray *)contentsOfDirectoryAtPath:(NSString *)path // error:(NSError **)error; // - (NSDictionary *)attributesOfItemAtPath:(NSString *)path // error:(NSError **)error; // - (NSData *)contentsAtPath:(NSString *)path; // // For a writeable filesystem, the Finder can be quite picky unless the majority // of these methods are implemented. However, you can safely skip hard-links, // symbolic links, and extended attributes. #pragma mark Directory Contents // BSD-equivalent: readdir(3) - (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error; #pragma mark Getting and Setting Attributes // Returns a dictionary of attributes at the given path. It is required to // return at least the NSFileType attribute. You may omit the NSFileSize // attribute if contentsAtPath: is implemented, although this is less efficient. // The following keys are currently supported (unknown keys are ignored): // NSFileType [Required] // NSFileSize [Recommended] // NSFileModificationDate // NSFileReferenceCount // NSFilePosixPermissions // NSFileOwnerAccountID // NSFileGroupOwnerAccountID // NSFileCreationDate (if using 'xtimes' option) // kGMUserFileSystemFileBackupDateKey (if using 'xtimes' option) // kGMUserFileSystemFileChangeDateKey // kGMUserFileSystemFileFlagsKey [NSNumber uint32_t for stat st_flags field] // // BSD-equivalent: stat(2) - (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error; // The following keys are currently supported (unknown keys are ignored): // NSFileSystemSize // NSFileSystemFreeSize // NSFileSystemNodes // NSFileSystemFreeNodes // // BSD-equivalent: statvfs(3) - (NSDictionary *)attributesOfFileSystemForPath:(NSString *)path error:(NSError **)error; // The following keys may be present (you must ignore unknown keys): // NSFileOwnerAccountID // NSFileGroupOwnerAccountID // NSFileModificationDate // NSFilePosixPermissions // NSFileCreationDate (if using 'xtimes' option) // kGMUserFileSystemFileBackupDateKey (if using 'xtimes' option) // kGMUserFileSystemFileChangeDateKey // kGMUserFileSystemFileFlagsKey [NSNumber uint32_t for stat st_flags field] // // BSD-equivalent: chown(2), chmod(2), utimes(2), chflags(2) - (BOOL)setAttributes:(NSDictionary *)attributes ofItemAtPath:(NSString *)path error:(NSError **)error; #pragma mark File Contents // If contentsAtPath is implemented then you can skip open/release/read. // Return nil if the file does not exist at the given path. - (NSData *)contentsAtPath:(NSString *)path; // BSD-equivalent: open(2) - (BOOL)openFileAtPath:(NSString *)path mode:(int)mode fileDelegate:(id *)fileDelegate error:(NSError **)error; // BSD-equivalent: close(2) - (void)releaseFileAtPath:(NSString *)path fileDelegate:(id)fileDelegate; // This is only called if the fileDelegate is nil or does not implement the // readToBuffer:size:offset:error: method. // // BSD-equivalent: pread(2) - (int)readFileAtPath:(NSString *)path fileDelegate:(id)fileDelegate buffer:(char *)buffer size:(size_t)size offset:(off_t)offset error:(NSError **)error; // This is only called if the fileDelegate is nil or does not implement the // writeFromBuffer:size:offset:error: method. // // BSD-equivalent: pwrite(2) - (int)writeFileAtPath:(NSString *)path fileDelegate:(id)fileDelegate buffer:(const char *)buffer size:(size_t)size offset:(off_t)offset error:(NSError **)error; // This is only called if the fileDelegate is nil or does not implement the // truncateToOffset:error: method. // // BSD-equivalent: truncate(2) - (BOOL)truncateFileAtPath:(NSString *)path offset:(off_t)offset error:(NSError **)error; // Called to atomically exchange file data between path1 and path2. // // BSD-equivalent: exchangedata(2) - (BOOL)exchangeDataOfItemAtPath:(NSString *)path1 withItemAtPath:(NSString *)path2 error:(NSError **)error; #pragma mark Creating an Item // BSD-equivalent: mkdir(2) - (BOOL)createDirectoryAtPath:(NSString *)path attributes:(NSDictionary *)attributes error:(NSError **)error; // BSD-equivalent: creat(2) - (BOOL)createFileAtPath:(NSString *)path attributes:(NSDictionary *)attributes fileDelegate:(id *)fileDelegate error:(NSError **)error; #pragma mark Moving an Item // BSD-equivalent: rename(2) - (BOOL)moveItemAtPath:(NSString *)source toPath:(NSString *)destination error:(NSError **)error; #pragma mark Removing an Item // BSD-equivalent: rmdir(2), unlink(2) - (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error; #pragma mark Linking an Item // BSD-equivalent: link(2) - (BOOL)linkItemAtPath:(NSString *)path toPath:(NSString *)otherPath error:(NSError **)error; #pragma mark Symbolic Links // BSD-equivalent: symlink(2) - (BOOL)createSymbolicLinkAtPath:(NSString *)path withDestinationPath:(NSString *)otherPath error:(NSError **)error; // BSD-equivalent: readlink(2) - (NSString *)destinationOfSymbolicLinkAtPath:(NSString *)path error:(NSError **)error; #pragma mark Extended Attributes // BSD-equivalent: listxattr(2) - (NSArray *)extendedAttributesOfItemAtPath:path error:(NSError **)error; // BSD-equivalent: getxattr(2) - (NSData *)valueOfExtendedAttribute:(NSString *)name ofItemAtPath:(NSString *)path position:(off_t)position error:(NSError **)error; // BSD-equivalent: setxattr(2) - (BOOL)setExtendedAttribute:(NSString *)name ofItemAtPath:(NSString *)path value:(NSData *)value position:(off_t)position options:(int)options error:(NSError **)error; // BSD-equivalent: removexattr(2) - (BOOL)removeExtendedAttribute:(NSString *)name ofItemAtPath:(NSString *)path error:(NSError **)error; @end