2 Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
23 #include <attr/xattr.h>
24 #elif HAVE_SYS_XATTR_H
25 #include <sys/xattr.h>
32 #ifdef HAVE_SYS_EXTATTR_H
33 #include <sys/extattr.h>
36 /* FIXME: are the ACL includes really neccessary here ? */
37 #ifdef HAVE_SOLARIS_ACLS
40 #ifdef HAVE_FREEBSD_SUNACL
45 #define ENOATTR ENODATA
48 #include <atalk/vfs.h>
51 * This seems to be the current limit fo HFS+, we arbitrarily force that
52 * which also safes us from buffer overflows
54 #define MAX_EA_SIZE 3802
57 * At time of writing the 10.5.6 client adds 8 bytes to the
58 * length of the EA that we send him
60 #define MAX_REPLY_EXTRA_BYTES 8
63 * Library user must provide a static buffer of size ATTRNAMEBUFSIZ.
64 * It's used when listing EAs as intermediate buffer. For afpd it's
65 * defined in extattrs.c.
67 #define ATTRNAMEBUFSIZ 4096
75 #if !defined(HAVE_SETXATTR)
76 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
77 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
80 /* Names for our Extended Attributes adouble data */
81 #define AD_EA_META "org.netatalk.Metadata"
82 #define AD_EA_RESO "org.netatalk.ResourceFork"
83 #define NOT_NETATALK_EA(a) (strcmp((a), AD_EA_META) != 0) && (strcmp((a), AD_EA_RESO) != 0)
85 /****************************************************************************************
86 * Wrappers for native EA functions taken from Samba
87 ****************************************************************************************/
88 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size);
89 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size);
90 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size);
91 ssize_t sys_listxattr (const char *path, char *list, size_t size);
92 ssize_t sys_llistxattr (const char *path, char *list, size_t size);
93 /* ssize_t sys_flistxattr (int filedes, char *list, size_t size); */
94 ssize_t sys_flistxattr (int filedes, const char *path, char *list, size_t size);
95 int sys_removexattr (const char *path, const char *name);
96 int sys_lremovexattr (const char *path, const char *name);
97 /* int sys_fremovexattr (int filedes, const char *name); */
98 int sys_fremovexattr (int filedes, const char *path, const char *name);
99 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags);
100 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags);
101 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags);
102 int sys_copyxattr (const char *src, const char *dst);
103 int sys_getxattrfd(int fd, const char *uname, int oflag, ...);
105 /****************************************************************************************
106 * Stuff for our implementation of storing EAs in files in .AppleDouble dirs
107 ****************************************************************************************/
109 #define EA_INITED 0xea494e54 /* ea"INT", for interfacing ea_open w. ea_close */
110 #define EA_MAGIC 0x61644541 /* "adEA" */
111 #define EA_VERSION1 0x01
112 #define EA_VERSION EA_VERSION1
116 EA_CREATE = (1<<1), /* create if not existing on ea_open */
117 EA_RDONLY = (1<<2), /* open read only */
118 EA_RDWR = (1<<3), /* open read/write */
119 /* ea_open internal flags */
120 EA_DIR = (1<<4) /* ea header file is for a dir, ea_open adds it as appropiate */
123 #define EA_MAGIC_OFF 0
124 #define EA_MAGIC_LEN 4
125 #define EA_VERSION_OFF (EA_MAGIC_OFF + EA_MAGIC_LEN)
126 #define EA_VERSION_LEN 2
127 #define EA_COUNT_OFF (EA_VERSION_OFF + EA_VERSION_LEN)
128 #define EA_COUNT_LEN 2
129 #define EA_HEADER_SIZE (EA_MAGIC_LEN + EA_VERSION_LEN + EA_COUNT_LEN)
132 * structs describing the layout of the Extended Attributes bookkeeping file.
133 * This isn't really an AppleDouble structure, it's just a binary blob that
134 * lives in our .AppleDouble directory too.
138 size_t ea_namelen; /* len of ea_name without terminating 0 ie. strlen(ea_name)*/
139 size_t ea_size; /* size of EA*/
140 char *ea_name; /* name of the EA */
143 /* We read the on-disk data into *ea_data and parse it into this*/
145 uint32_t ea_inited; /* needed for interfacing ea_open w. ea_close */
146 const struct vol *vol; /* vol handle, ea_close needs it */
147 int dirfd; /* for *at (cf openat) semantics, -1 means ignore */
148 char *filename; /* name of file, needed by ea_close too */
149 unsigned int ea_count; /* number of EAs in ea_entries array */
150 struct ea_entry (*ea_entries)[]; /* malloced and realloced as needed by ea_count*/
151 int ea_fd; /* open fd for ea_data */
152 eaflags_t ea_flags; /* flags */
153 size_t ea_size; /* size of header file = size of ea_data buffer */
154 char *ea_data; /* pointer to buffer into that we actually *
155 * read the disc file into */
158 /* On-disk format, just for reference ! */
160 struct ea_entry_ondisk {
162 char ea_name[]; /* zero terminated string */
167 u_int16_t ea_version;
169 struct ea_entry_ondisk ea_entries[ea_count];
173 /* VFS inderected funcs ... : */
175 /* Default adouble EAs */
176 extern int get_easize(VFS_FUNC_ARGS_EA_GETSIZE);
177 extern int get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT);
178 extern int list_eas(VFS_FUNC_ARGS_EA_LIST);
179 extern int set_ea(VFS_FUNC_ARGS_EA_SET);
180 extern int remove_ea(VFS_FUNC_ARGS_EA_REMOVE);
181 /* ... EA VFS funcs that deal with file/dir cp/mv/rm */
182 extern int ea_deletefile(VFS_FUNC_ARGS_DELETEFILE);
183 extern int ea_renamefile(VFS_FUNC_ARGS_RENAMEFILE);
184 extern int ea_copyfile(VFS_FUNC_ARGS_COPYFILE);
185 extern int ea_chown(VFS_FUNC_ARGS_CHOWN);
186 extern int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE);
187 extern int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE);
190 extern int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE);
191 extern int sys_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT);
192 extern int sys_list_eas(VFS_FUNC_ARGS_EA_LIST);
193 extern int sys_set_ea(VFS_FUNC_ARGS_EA_SET);
194 extern int sys_remove_ea(VFS_FUNC_ARGS_EA_REMOVE);
195 /* native EA VFSfile/dir cp/mv/rm */
196 extern int sys_ea_copyfile(VFS_FUNC_ARGS_COPYFILE);
198 /* dbd needs access to these */
199 extern int ea_open(const struct vol * restrict vol,
200 const char * restrict uname,
202 struct ea * restrict ea);
203 extern int ea_openat(const struct vol * restrict vol,
205 const char * restrict uname,
207 struct ea * restrict ea);
208 extern int ea_close(struct ea * restrict ea);
209 extern char *ea_path(const struct ea * restrict ea, const char * restrict eaname, int macname);
211 #endif /* ATALK_EA_H */