Tweaking the license text a bit more.
[rsync/rsync.git] / lib / sysxattrs.c
1 /*
2  * Extended attribute support for rsync.
3  *
4  * Copyright (C) 2004 Red Hat, Inc.
5  * Written by Jay Fenlason.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, visit the http://fsf.org website.
19  */
20
21 #include "rsync.h"
22 #include "sysxattrs.h"
23
24 #ifdef SUPPORT_XATTRS
25
26 #if defined HAVE_LINUX_XATTRS
27
28 ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
29 {
30         return lgetxattr(path, name, value, size);
31 }
32
33 ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
34 {
35         return fgetxattr(filedes, name, value, size);
36 }
37
38 int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
39 {
40         return lsetxattr(path, name, value, size, 0);
41 }
42
43 int sys_lremovexattr(const char *path, const char *name)
44 {
45         return lremovexattr(path, name);
46 }
47
48 ssize_t sys_llistxattr(const char *path, char *list, size_t size)
49 {
50         return llistxattr(path, list, size);
51 }
52
53 #elif HAVE_OSX_XATTRS
54
55 ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
56 {
57         return getxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
58 }
59
60 ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
61 {
62         return fgetxattr(filedes, name, value, size, 0, 0);
63 }
64
65 int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
66 {
67         return setxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
68 }
69
70 int sys_lremovexattr(const char *path, const char *name)
71 {
72         return removexattr(path, name, XATTR_NOFOLLOW);
73 }
74
75 ssize_t sys_llistxattr(const char *path, char *list, size_t size)
76 {
77         return listxattr(path, list, size, XATTR_NOFOLLOW);
78 }
79
80 #elif HAVE_FREEBSD_XATTRS
81
82 ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
83 {
84         return extattr_get_link(path, EXTATTR_NAMESPACE_USER, name, value, size);
85 }
86
87 ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
88 {
89         return extattr_get_fd(filedes, EXTATTR_NAMESPACE_USER, name, value, size);
90 }
91
92 int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
93 {
94         return extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, value, size);
95 }
96
97 int sys_lremovexattr(const char *path, const char *name)
98 {
99         return extattr_delete_link(path, EXTATTR_NAMESPACE_USER, name);
100 }
101
102 ssize_t sys_llistxattr(const char *path, char *list, size_t size)
103 {
104         unsigned char keylen;
105         ssize_t off, len = extattr_list_link(path, EXTATTR_NAMESPACE_USER, list, size);
106
107         if (len <= 0 || (size_t)len > size)
108                 return len;
109
110         /* FreeBSD puts a single-byte length before each string, with no '\0'
111          * terminator.  We need to change this into a series of null-terminted
112          * strings.  Since the size is the same, we can simply transform the
113          * output in place. */
114         for (off = 0; off < len; off += keylen + 1) {
115                 keylen = ((unsigned char*)list)[off];
116                 if (off + keylen >= len) {
117                         /* Should be impossible, but kernel bugs happen! */
118                         errno = EINVAL;
119                         return -1;
120                 }
121                 memmove(list+off, list+off+1, keylen);
122                 list[off+keylen] = '\0';
123         }
124
125         return len;
126 }
127
128 #else
129
130 #error You need to create xattr compatibility functions.
131
132 #endif
133
134 #endif /* SUPPORT_XATTRS */