/* 23.4.15 */ acl_t acl_get_fd(int fd) { const size_t size_guess = acl_ea_size(16); char *ext_acl_p = alloca(size_guess); int retval; if (!ext_acl_p) return NULL; retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p, size_guess); if (retval == -1 && errno == ERANGE) { retval = fgetxattr(fd, ACL_EA_ACCESS, NULL, 0); if (retval > 0) { ext_acl_p = alloca(retval); if (!ext_acl_p) return NULL; retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p,retval); } } if (retval > 0) { acl_t acl = __acl_from_xattr(ext_acl_p, retval); return acl; } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) { struct stat st; if (fstat(fd, &st) == 0) return acl_from_mode(st.st_mode); else return NULL; } else return NULL; }
int ext4_to_fuse_acl(acl_ea_header **facl, size_t *facl_sz, const ext4_acl_header *eacl, size_t eacl_sz) { int i, eacl_count; acl_ea_header *f; ext4_acl_entry *e; acl_ea_entry *a; size_t f_sz; unsigned char *hptr; int err = 0; eacl_count = ext4_acl_count(eacl_sz); f_sz = acl_ea_size(eacl_count); if (eacl_count < 0 || eacl->a_version != ext2fs_cpu_to_le32(EXT4_ACL_VERSION)) return -EINVAL; f = malloc(f_sz); if (!f) return -ENOMEM; f->a_version = ACL_EA_VERSION; hptr = (unsigned char *) (eacl + 1); for (i = 0, a = f->a_entries; i < eacl_count; i++, a++) { e = (ext4_acl_entry *) hptr; a->e_tag = ext2fs_le16_to_cpu(e->e_tag); a->e_perm = ext2fs_le16_to_cpu(e->e_perm); switch (a->e_tag) { case ACL_USER: case ACL_GROUP: a->e_id = ext2fs_le32_to_cpu(e->e_id); hptr += sizeof(ext4_acl_entry); break; case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_MASK: case ACL_OTHER: hptr += sizeof(ext4_acl_entry_short); break; default: err = -EINVAL; goto out; } } *facl = f; *facl_sz = f_sz; return err; out: free(f); return err; }