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
17static const char* kAttributeNamespace = "haiku.";
18static const int kAttributeNamespaceLen = 6;
19
20
21static ssize_t
22list_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
54static ssize_t
55get_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
67static int
68set_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
80static int
81remove_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