Skip to content

Commit

Permalink
Added DTExtendedFileAttributes
Browse files Browse the repository at this point in the history
  • Loading branch information
odrobnik committed Mar 6, 2012
1 parent 5f64daa commit afcd623
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 1 deletion.
61 changes: 61 additions & 0 deletions Core/Source/DTExtendedFileAttributes.h
@@ -0,0 +1,61 @@
//
// DTExtendedFileAttributes.h
// DTFoundation
//
// Created by Oliver Drobnik on 3/6/12.
// Copyright (c) 2012 Cocoanetics. All rights reserved.
//

/**
This class providse read/write access to extended file attributes of a file or folder. It wraps the standard xattr Posix functions to do that.
Because the file system does not keep track of the data types saved in extended attributes this API so far reads and writes strings.
*/
@interface DTExtendedFileAttributes : NSObject


/**
@name Creating an Extended File Attribute Manager
*/


/**
Creates an Extended File Attribute Manager.
@param path The file path
*/
- (id)initWithPath:(NSString *)path;


/**
@name: Reading/Writing extended attributes
*/

/**
Removes an extended file attribute from the receiver.
@returns `YES` if successful.
*/
- (BOOL)removeAttribute:(NSString *)attribute;


/**
Sets the value of an extended file attribute for the receiver.
If the value is `nil` then this is the same as calling <removeAttribute:>.
@param attribute The name of the attribute.
@returns `YES` if successful.
*/
- (BOOL)setValue:(NSString *)value forAttribute:(NSString *)attribute;


/**
Gets the value of an extended file attribute from the receiver.
@param attribute The name of the attribute.
@returns The string for the value or `nil` if the value is not set.
*/
- (NSString *)valueForAttribute:(NSString *)attribute;

@end
100 changes: 100 additions & 0 deletions Core/Source/DTExtendedFileAttributes.m
@@ -0,0 +1,100 @@
//
// DTExtendedFileAttributes.m
// DTFoundation
//
// Created by Oliver Drobnik on 3/6/12.
// Copyright (c) 2012 Cocoanetics. All rights reserved.
//

#import "DTExtendedFileAttributes.h"

#import <sys/xattr.h>

@implementation DTExtendedFileAttributes
{
NSString *_path;
}

- (id)initWithPath:(NSString *)path
{
self = [super init];
if (self)
{
if (![path length])
{
return nil;
}

_path = path;
}

return self;
}

- (BOOL)removeAttribute:(NSString *)attribute
{
const char *attrName = [attribute UTF8String];
const char *filePath = [_path fileSystemRepresentation];

int result = removexattr(filePath, attrName, 0);

return (result==0);
}

- (BOOL)setValue:(NSString *)value forAttribute:(NSString *)attribute
{
if (![attribute length])
{
return NO;
}

if (!value)
{
// remove it instead
return [self removeAttribute:attribute];
}

const char *attrName = [attribute UTF8String];
const char *filePath = [_path fileSystemRepresentation];

const char *val = [value UTF8String];

int result = setxattr(filePath, attrName, val, strlen(val), 0, 0);

return (result==0);
}

- (NSString *)valueForAttribute:(NSString *)attribute
{
if (![attribute length])
{
return nil;
}

const char *attrName = [attribute UTF8String];
const char *filePath = [_path fileSystemRepresentation];

// get size of needed buffer
int bufferLength = getxattr(filePath, attrName, NULL, 0, 0, 0);

if (bufferLength<=0)
{
return nil;
}

// make a buffer of sufficient length
char *buffer = malloc(bufferLength);

// now actually get the attribute string
getxattr(filePath, attrName, buffer, 255, 0, 0);

// convert to NSString
NSString *retString = [[NSString alloc] initWithBytes:buffer length:bufferLength encoding:NSUTF8StringEncoding];

// release buffer
free(buffer);

return retString;
}

@end
20 changes: 19 additions & 1 deletion DTFoundation.xcodeproj/project.pbxproj
Expand Up @@ -83,6 +83,10 @@
A7A7CC7A14866CAF00EC2EE4 /* NSString+DTFormatNumbers.m in Sources */ = {isa = PBXBuildFile; fileRef = A70B4CCB1486621B00873A4A /* NSString+DTFormatNumbers.m */; };
A7A7CC7B14866CAF00EC2EE4 /* NSURL+DTAppLinks.m in Sources */ = {isa = PBXBuildFile; fileRef = A70B4CCD1486621B00873A4A /* NSURL+DTAppLinks.m */; };
A7A7CC7C14866CAF00EC2EE4 /* NSURL+DTPrefLinks.m in Sources */ = {isa = PBXBuildFile; fileRef = A70B4CCF1486621B00873A4A /* NSURL+DTPrefLinks.m */; };
A7D6F2E515063448001CACDD /* DTExtendedFileAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */; };
A7D6F2E615063448001CACDD /* DTExtendedFileAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */; };
A7D6F2E715063448001CACDD /* DTExtendedFileAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D6F2E415063448001CACDD /* DTExtendedFileAttributes.m */; };
A7D6F2E815063448001CACDD /* DTExtendedFileAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D6F2E415063448001CACDD /* DTExtendedFileAttributes.m */; };
A7D8628114EBF65C001436AF /* NSString+DTPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8627F14EBF65C001436AF /* NSString+DTPaths.h */; };
A7D8628214EBF65C001436AF /* NSString+DTPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8627F14EBF65C001436AF /* NSString+DTPaths.h */; };
A7D8628314EBF65C001436AF /* NSString+DTPaths.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8628014EBF65C001436AF /* NSString+DTPaths.m */; };
Expand Down Expand Up @@ -125,6 +129,8 @@
A7949A3814C963F500A8CCDE /* DTHTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTHTMLParser.h; sourceTree = "<group>"; };
A7949A3914C963F500A8CCDE /* DTHTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTHTMLParser.m; sourceTree = "<group>"; };
A7BAD10E1483F934000E2B6A /* DTFoundation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DTFoundation.framework; sourceTree = BUILT_PRODUCTS_DIR; };
A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTExtendedFileAttributes.h; sourceTree = "<group>"; };
A7D6F2E415063448001CACDD /* DTExtendedFileAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTExtendedFileAttributes.m; sourceTree = "<group>"; };
A7D8627F14EBF65C001436AF /* NSString+DTPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+DTPaths.h"; sourceTree = "<group>"; };
A7D8628014EBF65C001436AF /* NSString+DTPaths.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+DTPaths.m"; sourceTree = "<group>"; };
A7F4DFF8147FD08900F4059A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -186,6 +192,8 @@
A77DD40714E81AEE00F34B03 /* DTZipArchive.m */,
A7D8627F14EBF65C001436AF /* NSString+DTPaths.h */,
A7D8628014EBF65C001436AF /* NSString+DTPaths.m */,
A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */,
A7D6F2E415063448001CACDD /* DTExtendedFileAttributes.m */,
);
path = Source;
sourceTree = "<group>";
Expand Down Expand Up @@ -276,6 +284,7 @@
A77DD42714E825FC00F34B03 /* zip.h in Headers */,
A7D8628214EBF65C001436AF /* NSString+DTPaths.h in Headers */,
A760F52D14F24B9F00AD1B0E /* DTASN1Parser.h in Headers */,
A7D6F2E615063448001CACDD /* DTExtendedFileAttributes.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -301,6 +310,7 @@
A77DD42614E825FC00F34B03 /* zip.h in Headers */,
A7D8628114EBF65C001436AF /* NSString+DTPaths.h in Headers */,
A760F52C14F24B9F00AD1B0E /* DTASN1Parser.h in Headers */,
A7D6F2E515063448001CACDD /* DTExtendedFileAttributes.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -350,7 +360,7 @@
A7F4DF9A147FB61500F4059A /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
LastUpgradeCheck = 0430;
ORGANIZATIONNAME = Cocoanetics;
};
buildConfigurationList = A7F4DF9D147FB61500F4059A /* Build configuration list for PBXProject "DTFoundation" */;
Expand Down Expand Up @@ -445,6 +455,7 @@
A77DD42514E825FC00F34B03 /* zip.c in Sources */,
A7D8628414EBF65C001436AF /* NSString+DTPaths.m in Sources */,
A760F52F14F24B9F00AD1B0E /* DTASN1Parser.m in Sources */,
A7D6F2E815063448001CACDD /* DTExtendedFileAttributes.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -466,6 +477,7 @@
A77DD42414E825FC00F34B03 /* zip.c in Sources */,
A7D8628314EBF65C001436AF /* NSString+DTPaths.m in Sources */,
A760F52E14F24B9F00AD1B0E /* DTASN1Parser.m in Sources */,
A7D6F2E715063448001CACDD /* DTExtendedFileAttributes.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -482,6 +494,7 @@
DSTROOT = /tmp/DTFoundation.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Core/DTFoundation-Prefix.pch";
GCC_THUMB_SUPPORT = NO;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = DTFoundation;
PUBLIC_HEADERS_FOLDER_PATH = ../../DTFoundation;
Expand All @@ -499,6 +512,7 @@
DSTROOT = /tmp/DTFoundation.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Core/DTFoundation-Prefix.pch";
GCC_THUMB_SUPPORT = NO;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = DTFoundation;
PUBLIC_HEADERS_FOLDER_PATH = ../../DTFoundation;
Expand Down Expand Up @@ -572,6 +586,7 @@
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_THUMB_SUPPORT = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
Expand All @@ -593,6 +608,7 @@
CLANG_ENABLE_OBJC_ARC = YES;
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_THUMB_SUPPORT = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
Expand All @@ -607,13 +623,15 @@
A7F4DFEF147FBAC600F4059A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_THUMB_SUPPORT = NO;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
A7F4DFF0147FBAC600F4059A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_THUMB_SUPPORT = NO;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
Expand Down

0 comments on commit afcd623

Please sign in to comment.