]> arthur.barton.de Git - netatalk.git/blob - include/atalk/ea.h
Writing metadata xattr on directories with sticky bit set, FR#94
[netatalk.git] / include / atalk / ea.h
1 /*
2    Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
3
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.
8  
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.
13 */
14
15 #ifndef ATALK_EA_H
16 #define ATALK_EA_H
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #if HAVE_ATTR_XATTR_H
23 #include <attr/xattr.h>
24 #elif HAVE_SYS_XATTR_H
25 #include <sys/xattr.h>
26 #endif
27
28 #ifdef HAVE_SYS_EA_H
29 #include <sys/ea.h>
30 #endif
31
32 #ifdef HAVE_SYS_EXTATTR_H
33 #include <sys/extattr.h>
34 #endif
35
36 /* FIXME: are the ACL includes really neccessary here ? */
37 #ifdef HAVE_SOLARIS_ACLS
38 #include <sys/acl.h>
39 #endif
40 #ifdef HAVE_FREEBSD_SUNACL
41 #include <sunacl.h>
42 #endif
43
44 #ifndef ENOATTR
45 #define ENOATTR ENODATA
46 #endif
47
48 #include <atalk/vfs.h>
49
50 /*
51  * This seems to be the current limit fo HFS+, we arbitrarily force that
52  *  which also safes us from buffer overflows
53  */
54 #define MAX_EA_SIZE 3802
55
56 /*
57  * At time of writing the 10.5.6 client adds 8 bytes to the
58  * length of the EA that we send him 
59 */
60 #define MAX_REPLY_EXTRA_BYTES 8
61
62 /* 
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.
66  */
67 #define ATTRNAMEBUFSIZ 4096
68
69 enum {
70     kXAttrNoFollow = 0x1,
71     kXAttrCreate = 0x2,
72     kXAttrReplace = 0x4
73 };
74
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 */
78 #endif
79
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)
84
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 int sys_removexattr (const char *path, const char *name);
95 int sys_lremovexattr (const char *path, const char *name);
96 int sys_fremovexattr (int filedes, const char *name);
97 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags);
98 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags);
99 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags);
100 int sys_copyxattr (const char *src, const char *dst);
101 int sys_getxattrfd(int fd, const char *uname, int oflag, ...);
102
103 /****************************************************************************************
104  * Stuff for our implementation of storing EAs in files in .AppleDouble dirs
105  ****************************************************************************************/
106
107 #define EA_INITED   0xea494e54  /* ea"INT", for interfacing ea_open w. ea_close */
108 #define EA_MAGIC    0x61644541 /* "adEA" */
109 #define EA_VERSION1 0x01
110 #define EA_VERSION  EA_VERSION1
111
112 typedef enum {
113     /* ea_open flags */
114     EA_CREATE    = (1<<1),      /* create if not existing on ea_open */
115     EA_RDONLY    = (1<<2),      /* open read only */
116     EA_RDWR      = (1<<3),      /* open read/write */
117     /* ea_open internal flags */
118     EA_DIR       = (1<<4)       /* ea header file is for a dir, ea_open adds it as appropiate */
119 } eaflags_t;
120
121 #define EA_MAGIC_OFF   0
122 #define EA_MAGIC_LEN   4
123 #define EA_VERSION_OFF (EA_MAGIC_OFF + EA_MAGIC_LEN)
124 #define EA_VERSION_LEN 2
125 #define EA_COUNT_OFF   (EA_VERSION_OFF + EA_VERSION_LEN)
126 #define EA_COUNT_LEN   2
127 #define EA_HEADER_SIZE (EA_MAGIC_LEN + EA_VERSION_LEN + EA_COUNT_LEN)
128
129 /* 
130  * structs describing the layout of the Extended Attributes bookkeeping file.
131  * This isn't really an AppleDouble structure, it's just a binary blob that
132  * lives in our .AppleDouble directory too.
133  */
134
135 struct ea_entry {
136     size_t       ea_namelen; /* len of ea_name without terminating 0 ie. strlen(ea_name)*/
137     size_t       ea_size;    /* size of EA*/
138     char         *ea_name;   /* name of the EA */
139 };
140
141 /* We read the on-disk data into *ea_data and parse it into this*/
142 struct ea {
143     uint32_t             ea_inited;       /* needed for interfacing ea_open w. ea_close */
144     const struct vol     *vol;            /* vol handle, ea_close needs it */
145     int                  dirfd;           /* for *at (cf openat) semantics, -1 means ignore */
146     char                 *filename;       /* name of file, needed by ea_close too */
147     unsigned int         ea_count;        /* number of EAs in ea_entries array */
148     struct ea_entry      (*ea_entries)[]; /* malloced and realloced as needed by ea_count*/
149     int                  ea_fd;           /* open fd for ea_data */
150     eaflags_t            ea_flags;        /* flags */
151     size_t               ea_size;         /* size of header file = size of ea_data buffer */
152     char                 *ea_data;        /* pointer to buffer into that we actually *
153                                            * read the disc file into                 */
154 };
155
156 /* On-disk format, just for reference ! */
157 #if 0
158 struct ea_entry_ondisk {
159     uint32_t               ea_size;
160     char                   ea_name[]; /* zero terminated string */
161 };
162
163 struct ea_ondisk {
164     u_int32_t              ea_magic;
165     u_int16_t              ea_version;
166     u_int16_t              ea_count;
167     struct ea_entry_ondisk ea_entries[ea_count];
168 };
169 #endif /* 0 */
170
171 /* VFS inderected funcs ... : */
172
173 /* Default adouble EAs */
174 extern int get_easize(VFS_FUNC_ARGS_EA_GETSIZE);
175 extern int get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT);
176 extern int list_eas(VFS_FUNC_ARGS_EA_LIST);
177 extern int set_ea(VFS_FUNC_ARGS_EA_SET);
178 extern int remove_ea(VFS_FUNC_ARGS_EA_REMOVE);
179 /* ... EA VFS funcs that deal with file/dir cp/mv/rm */
180 extern int ea_deletefile(VFS_FUNC_ARGS_DELETEFILE);
181 extern int ea_renamefile(VFS_FUNC_ARGS_RENAMEFILE);
182 extern int ea_copyfile(VFS_FUNC_ARGS_COPYFILE);
183 extern int ea_chown(VFS_FUNC_ARGS_CHOWN);
184 extern int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE);
185 extern int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE);
186
187 /* native EAs */
188 extern int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE);
189 extern int sys_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT);
190 extern int sys_list_eas(VFS_FUNC_ARGS_EA_LIST);
191 extern int sys_set_ea(VFS_FUNC_ARGS_EA_SET);
192 extern int sys_remove_ea(VFS_FUNC_ARGS_EA_REMOVE);
193 /* native EA VFSfile/dir cp/mv/rm */
194 extern int sys_ea_copyfile(VFS_FUNC_ARGS_COPYFILE);
195
196 /* dbd needs access to these */
197 extern int ea_open(const struct vol * restrict vol,
198                    const char * restrict uname,
199                    eaflags_t eaflags,
200                    struct ea * restrict ea);
201 extern int ea_openat(const struct vol * restrict vol,
202                      int dirfd,
203                      const char * restrict uname,
204                      eaflags_t eaflags,
205                      struct ea * restrict ea);
206 extern int ea_close(struct ea * restrict ea);
207 extern char *ea_path(const struct ea * restrict ea, const char * restrict eaname, int macname);
208
209 #endif /* ATALK_EA_H */