@@ -28,10 +28,13 @@ #include "platform.h" #ifdef HAVE_SYS_STAT_H # include #endif #include +#ifdef OF_LINUX +# include +#endif #ifdef OF_WINDOWS # include #endif #ifdef OF_DJGPP # include @@ -44,10 +47,11 @@ # include #endif #import "OFFileIRIHandler.h" #import "OFArray.h" +#import "OFData.h" #import "OFDate.h" #import "OFFile.h" #import "OFFileManager.h" #import "OFIRI.h" #import "OFLocale.h" @@ -535,10 +539,48 @@ CloseHandle(handle); } # endif } #endif + +#ifdef OF_LINUX +static void +setExtendedAttributes(OFMutableFileAttributes attributes, OFIRI *IRI) +{ + OFString *path = IRI.fileSystemRepresentation; + OFStringEncoding encoding = [OFLocale encoding]; + const char *cPath = [path cStringWithEncoding: encoding]; + ssize_t size = llistxattr(cPath, NULL, 0); + char *list = OFAllocMemory(1, size); + OFMutableArray *names = nil; + + @try { + char *name; + + if ((size = llistxattr(cPath, list, size)) < 0) + return; + + names = [OFMutableArray array]; + name = list; + + while (size > 0) { + size_t length = strlen(name); + + [names addObject: [OFString stringWithCString: name + encoding: encoding + length: length]]; + + name += length + 1; + size -= length + 1; + } + } @finally { + OFFreeMemory(list); + } + + [attributes setObject: names forKey: OFFileExtendedAttributesNames]; +} +#endif @implementation OFFileIRIHandler + (void)initialize { #ifdef OF_WINDOWS @@ -639,10 +681,14 @@ #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS if (S_ISLNK(s.st_mode)) setSymbolicLinkDestinationAttribute(ret, IRI); #endif + +#ifdef OF_LINUX + setExtendedAttributes(ret, IRI); +#endif objc_autoreleasePoolPop(pool); return ret; } @@ -1486,6 +1532,37 @@ objc_autoreleasePoolPop(pool); return true; } + +#ifdef OF_LINUX +- (OFData *)extendedAttributeForName: (OFString *)name ofItemAtIRI: (OFIRI *)IRI +{ + void *pool = objc_autoreleasePoolPush(); + OFString *path = IRI.fileSystemRepresentation; + OFStringEncoding encoding = [OFLocale encoding]; + const char *cPath = [path cStringWithEncoding: encoding]; + const char *cName = [name cStringWithEncoding: encoding]; + ssize_t size = lgetxattr(cPath, cName, NULL, 0); + void *value = OFAllocMemory(1, size); + OFData *data; + + @try { + if ((size = lgetxattr(cPath, cName, value, size)) < 0) + @throw [OFGetItemAttributesFailedException + exceptionWithIRI: IRI + errNo: errno]; + + data = [OFData dataWithItems: value count: size]; + } @finally { + OFFreeMemory(value); + } + + [data retain]; + + objc_autoreleasePoolPop(pool); + + return [data autorelease]; +} +#endif @end