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