1 /* 2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef FS_ATTR_EXTATTR_H 6 #define FS_ATTR_EXTATTR_H 7 8 /*! Included by fs_attr_untyped.cpp. Interfaces with FreeBSD extattr support. 9 */ 10 11 12 #include <string.h> 13 #include <sys/extattr.h> 14 15 16 // the namespace all attributes live in 17 static const char* kAttributeNamespace = "haiku."; 18 static const int kAttributeNamespaceLen = 6; 19 20 21 static ssize_t 22 list_attributes(int fd, const char* path, char* buffer, size_t bufferSize) 23 { 24 ssize_t bytesRead; 25 if (fd >= 0) { 26 bytesRead = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, buffer, 27 bufferSize); 28 } else { 29 bytesRead = extattr_list_link(path, EXTATTR_NAMESPACE_USER, buffer, 30 bufferSize); 31 } 32 33 if (bytesRead <= 0) 34 return bytesRead; 35 36 // The listing is in a different format than expected by the caller. Here 37 // we get a sequence of (<namelen>, <unterminated name>) pairs, but expected 38 // is a sequence of null-terminated names. Let's convert it. 39 int index = *buffer; 40 memmove(buffer, buffer + 1, bytesRead - 1); 41 42 while (index < bytesRead - 1) { 43 int len = buffer[index]; 44 buffer[index] = '\0'; 45 index += len + 1; 46 } 47 48 buffer[bytesRead - 1] = '\0'; 49 50 return bytesRead; 51 } 52 53 54 static ssize_t 55 get_attribute(int fd, const char* path, const char* attribute, void* buffer, 56 size_t bufferSize) 57 { 58 if (fd >= 0) { 59 return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, attribute, buffer, 60 bufferSize); 61 } 62 return extattr_get_link(path, EXTATTR_NAMESPACE_USER, attribute, buffer, 63 bufferSize); 64 } 65 66 67 static int 68 set_attribute(int fd, const char* path, const char* attribute, 69 const void* buffer, size_t bufferSize) 70 { 71 if (fd >= 0) { 72 return extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, attribute, buffer, 73 bufferSize); 74 } 75 return extattr_set_link(path, EXTATTR_NAMESPACE_USER, attribute, buffer, 76 bufferSize); 77 } 78 79 80 static int 81 remove_attribute(int fd, const char* path, const char* attribute) 82 { 83 if (fd >= 0) 84 return extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, attribute); 85 return extattr_delete_link(path, EXTATTR_NAMESPACE_USER, attribute); 86 } 87 88 89 #endif // FS_ATTR_EXTATTR_H 90