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