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#ifdef HAVE_SOLARIS_ACLS 37#include <sys/acl.h> 38#endif 39 40#ifndef ENOATTR 41#define ENOATTR ENODATA 42#endif 43 44#include <atalk/vfs.h> 45 46/* 47 * This seems to be the current limit fo HFS+, we arbitrarily force that 48 * which also safes us from buffer overflows 49 */ 50#define MAX_EA_SIZE 3802 51 52/* 53 * At time of writing the 10.5.6 client adds 8 bytes to the 54 * length of the EA that we send him 55*/ 56#define MAX_REPLY_EXTRA_BYTES 8 57 58/* 59 * Library user must provide a static buffer of size ATTRNAMEBUFSIZ. 60 * It's used when listing EAs as intermediate buffer. For afpd it's 61 * defined in extattrs.c. 62 */ 63#define ATTRNAMEBUFSIZ 4096 64 65enum { 66 kXAttrNoFollow = 0x1, 67 kXAttrCreate = 0x2, 68 kXAttrReplace = 0x4 69}; 70 71#if !defined(HAVE_SETXATTR) 72#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ 73#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ 74#endif 75 76/* Names for our Extended Attributes adouble data */ 77#define AD_EA_META "org.netatalk.Metadata" 78#define AD_EA_RESO "org.netatalk.ResourceFork" 79#define NOT_NETATALK_EA(a) (strcmp((a), AD_EA_META) != 0) && (strcmp((a), AD_EA_RESO) != 0) 80 81/**************************************************************************************** 82 * Wrappers for native EA functions taken from Samba 83 ****************************************************************************************/ 84ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size); 85ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size); 86ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size); 87ssize_t sys_listxattr (const char *path, char *list, size_t size); 88ssize_t sys_llistxattr (const char *path, char *list, size_t size); 89ssize_t sys_flistxattr (int filedes, char *list, size_t size); 90int sys_removexattr (const char *path, const char *name); 91int sys_lremovexattr (const char *path, const char *name); 92int sys_fremovexattr (int filedes, const char *name); 93int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags); 94int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags); 95int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags); 96int sys_copyxattr (const char *src, const char *dst); 97int sys_getxattrfd(int fd, const char *uname, int oflag, ...); 98 99/**************************************************************************************** 100 * Stuff for our implementation of storing EAs in files in .AppleDouble dirs 101 ****************************************************************************************/ 102 103#define EA_INITED 0xea494e54 /* ea"INT", for interfacing ea_open w. ea_close */ 104#define EA_MAGIC 0x61644541 /* "adEA" */ 105#define EA_VERSION1 0x01 106#define EA_VERSION EA_VERSION1 107 108typedef enum { 109 /* ea_open flags */ 110 EA_CREATE = (1<<1), /* create if not existing on ea_open */ 111 EA_RDONLY = (1<<2), /* open read only */ 112 EA_RDWR = (1<<3), /* open read/write */ 113 /* ea_open internal flags */ 114 EA_DIR = (1<<4) /* ea header file is for a dir, ea_open adds it as appropiate */ 115} eaflags_t; 116 117#define EA_MAGIC_OFF 0 118#define EA_MAGIC_LEN 4 119#define EA_VERSION_OFF (EA_MAGIC_OFF + EA_MAGIC_LEN) 120#define EA_VERSION_LEN 2 121#define EA_COUNT_OFF (EA_VERSION_OFF + EA_VERSION_LEN) 122#define EA_COUNT_LEN 2 123#define EA_HEADER_SIZE (EA_MAGIC_LEN + EA_VERSION_LEN + EA_COUNT_LEN) 124 125/* 126 * structs describing the layout of the Extended Attributes bookkeeping file. 127 * This isn't really an AppleDouble structure, it's just a binary blob that 128 * lives in our .AppleDouble directory too. 129 */ 130 131struct ea_entry { 132 size_t ea_namelen; /* len of ea_name without terminating 0 ie. strlen(ea_name)*/ 133 size_t ea_size; /* size of EA*/ 134 char *ea_name; /* name of the EA */ 135}; 136 137/* We read the on-disk data into *ea_data and parse it into this*/ 138struct ea { 139 uint32_t ea_inited; /* needed for interfacing ea_open w. ea_close */ 140 const struct vol *vol; /* vol handle, ea_close needs it */ 141 int dirfd; /* for *at (cf openat) semantics, -1 means ignore */ 142 char *filename; /* name of file, needed by ea_close too */ 143 unsigned int ea_count; /* number of EAs in ea_entries array */ 144 struct ea_entry (*ea_entries)[]; /* malloced and realloced as needed by ea_count*/ 145 int ea_fd; /* open fd for ea_data */ 146 eaflags_t ea_flags; /* flags */ 147 size_t ea_size; /* size of header file = size of ea_data buffer */ 148 char *ea_data; /* pointer to buffer into that we actually * 149 * read the disc file into */ 150}; 151 152/* On-disk format, just for reference ! */ 153#if 0 154struct ea_entry_ondisk { 155 uint32_t ea_size; 156 char ea_name[]; /* zero terminated string */ 157}; 158 159struct ea_ondisk { 160 u_int32_t ea_magic; 161 u_int16_t ea_version; 162 u_int16_t ea_count; 163 struct ea_entry_ondisk ea_entries[ea_count]; 164}; 165#endif /* 0 */ 166 167/* VFS inderected funcs ... : */ 168 169/* Default adouble EAs */ 170extern int get_easize(VFS_FUNC_ARGS_EA_GETSIZE); 171extern int get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT); 172extern int list_eas(VFS_FUNC_ARGS_EA_LIST); 173extern int set_ea(VFS_FUNC_ARGS_EA_SET); 174extern int remove_ea(VFS_FUNC_ARGS_EA_REMOVE); 175/* ... EA VFS funcs that deal with file/dir cp/mv/rm */ 176extern int ea_deletefile(VFS_FUNC_ARGS_DELETEFILE); 177extern int ea_renamefile(VFS_FUNC_ARGS_RENAMEFILE); 178extern int ea_copyfile(VFS_FUNC_ARGS_COPYFILE); 179extern int ea_chown(VFS_FUNC_ARGS_CHOWN); 180extern int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE); 181extern int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE); 182 183/* native EAs */ 184extern int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE); 185extern int sys_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT); 186extern int sys_list_eas(VFS_FUNC_ARGS_EA_LIST); 187extern int sys_set_ea(VFS_FUNC_ARGS_EA_SET); 188extern int sys_remove_ea(VFS_FUNC_ARGS_EA_REMOVE); 189/* native EA VFSfile/dir cp/mv/rm */ 190extern int sys_ea_copyfile(VFS_FUNC_ARGS_COPYFILE); 191 192/* dbd needs access to these */ 193extern int ea_open(const struct vol * restrict vol, 194 const char * restrict uname, 195 eaflags_t eaflags, 196 struct ea * restrict ea); 197extern int ea_openat(const struct vol * restrict vol, 198 int dirfd, 199 const char * restrict uname, 200 eaflags_t eaflags, 201 struct ea * restrict ea); 202extern int ea_close(struct ea * restrict ea); 203extern char *ea_path(const struct ea * restrict ea, const char * restrict eaname, int macname); 204 205#endif /* ATALK_EA_H */ 206