@@ -38,10 +38,11 @@ #include #if defined(OF_LINUX) || defined(OF_MACOS) # include #endif #ifdef OF_HAIKU +# include # include #endif #ifdef OF_WINDOWS # include #endif @@ -1613,20 +1614,21 @@ return true; } #ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES -- (OFData *)extendedAttributeDataForName: (OFString *)name - ofItemAtIRI: (OFIRI *)IRI +- (void)getExtendedAttributeData: (OFData **)data + andType: (id *)type + forName: (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]; void *value = NULL; - OFData *data; # if defined(OF_LINUX) || defined(OF_MACOS) # if defined(OF_LINUX) ssize_t size = lgetxattr(cPath, cName, NULL, 0); # elif defined(OF_MACOS) ssize_t size = getxattr(cPath, cName, NULL, 0, 0, XATTR_NOFOLLOW); @@ -1647,17 +1649,20 @@ # endif @throw [OFGetItemAttributesFailedException exceptionWithIRI: IRI errNo: errno]; - data = [OFData dataWithItemsNoCopy: value - count: size - freeWhenDone: true]; + *data = [OFData dataWithItemsNoCopy: value + count: size + freeWhenDone: true]; value = NULL; } @finally { OFFreeMemory(value); } + + if (type != NULL) + *type = nil; # elif defined(OF_HAIKU) int fd = open(cPath, O_RDONLY); struct attr_info info; if (fd == -1) @@ -1681,28 +1686,30 @@ (size_t)info.size) != (ssize_t)info.size) @throw [OFGetItemAttributesFailedException exceptionWithIRI: IRI errNo: errno]; - data = [OFData dataWithItemsNoCopy: value - count: (size_t)info.size - freeWhenDone: true]; + *data = [OFData dataWithItemsNoCopy: value + count: (size_t)info.size + freeWhenDone: true]; value = NULL; + + if (type != NULL) + *type = [OFNumber numberWithUnsignedLong: info.type]; } @finally { OFFreeMemory(value); close(fd); } # endif - [data retain]; + [*data retain]; objc_autoreleasePoolPop(pool); - - return [data autorelease]; } - (void)setExtendedAttributeData: (OFData *)data + andType: (id)type forName: (OFString *)name ofItemAtIRI: (OFIRI *)IRI { void *pool = objc_autoreleasePoolPush(); OFString *path = IRI.fileSystemRepresentation; @@ -1710,10 +1717,14 @@ const char *cPath = [path cStringWithEncoding: encoding]; const char *cName = [name cStringWithEncoding: encoding]; size_t size = data.count * data.itemSize; # if defined(OF_LINUX) || defined(OF_MACOS) + if (type != nil) + @throw [OFNotImplementedException exceptionWithSelector: _cmd + object: self]; + # if defined(OF_LINUX) if (lsetxattr(cPath, cName, data.items, size, 0) != 0) { # elif defined(OF_MACOS) if (setxattr(cPath, cName, data.items, size, 0, XATTR_NOFOLLOW) != 0) { # endif @@ -1725,11 +1736,19 @@ attributes: [OFDictionary dictionary] failedAttribute: @"" errNo: errNo]; } # elif defined(OF_HAIKU) + unsigned long long typeInt; int fd; + + if (type != nil && ![type isKindOfClass: [OFNumber class]]) + @throw [OFInvalidArgumentException exception]; + + typeInt = (type != nil ? [type unsignedLongLongValue] : 0); + if (typeInt > UINT32_MAX) + @throw [OFInvalidArgumentException exception]; if (size > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if ((fd = open(cPath, O_WRONLY)) == -1) { @@ -1742,12 +1761,12 @@ failedAttribute: @"" errNo: errNo]; } @try { - if (fs_write_attr(fd, cName, B_RAW_TYPE, 0, data.items, size) != - (ssize_t)size) { + if (fs_write_attr(fd, cName, (uint32_t)typeInt, 0, + data.items, size) != (ssize_t)size) { int errNo = errno; /* * TODO: Add an attribute (prefix?) for extended * attributes?