mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r24304: patch from Bjoern JAcke <bj@SerNet.DE>:
attached patches add EA support for Solaris. If no one disagrees, can someone check this in please? metze
This commit is contained in:
parent
30f9171cca
commit
81e5afc363
@ -1747,6 +1747,14 @@ case "$host_os" in
|
||||
;;
|
||||
esac
|
||||
|
||||
########################################################
|
||||
# Check if attropen() is present if this is Solaris
|
||||
case "$host_os" in
|
||||
*solaris*)
|
||||
AC_CHECK_FUNCS(attropen)
|
||||
;;
|
||||
esac
|
||||
|
||||
########################################################
|
||||
# Do xattr functions take additional options like on Darwin?
|
||||
if test x"$ac_cv_func_getxattr" = x"yes" ; then
|
||||
|
@ -224,6 +224,10 @@ typedef int ber_int_t;
|
||||
#include <sys/attributes.h>
|
||||
#endif
|
||||
|
||||
#ifndef ENOATTR
|
||||
#define ENOATTR ENODATA
|
||||
#endif
|
||||
|
||||
/* mutually exclusive (SuSE 8.2) */
|
||||
#if HAVE_ATTR_XATTR_H
|
||||
#include <attr/xattr.h>
|
||||
|
@ -4,6 +4,7 @@
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
Copyright (C) Jeremy Allison 1998-2005
|
||||
Copyright (C) Timur Bakeyev 2005
|
||||
Copyright (C) Bjoern Jacke 2006-2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -1682,6 +1683,17 @@ int sys_dup2(int oldfd, int newfd)
|
||||
SAFE_FREE(msgbuf);
|
||||
}
|
||||
|
||||
/******** Solaris EA helper function prototypes ********/
|
||||
#ifdef HAVE_ATTROPEN
|
||||
#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
|
||||
int solaris_write_xattr(int attrfd, const char *value, size_t size);
|
||||
ssize_t solaris_read_xattr(int attrfd, void *value, size_t size);
|
||||
ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size);
|
||||
int solaris_unlinkat(int attrdirfd, const char *name);
|
||||
int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode);
|
||||
int solaris_openat(int fildes, const char *path, int oflag, mode_t mode);
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
Wrappers for extented attribute calls. Based on the Linux package with
|
||||
support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
|
||||
@ -1730,6 +1742,14 @@ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t si
|
||||
retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
|
||||
|
||||
return retval ? retval : valuelength;
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
ssize_t ret = -1;
|
||||
int attrfd = solaris_attropen(path, name, O_RDONLY, 0);
|
||||
if (attrfd >= 0) {
|
||||
ret = solaris_read_xattr(attrfd, value, size);
|
||||
close(attrfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -1773,6 +1793,14 @@ ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t s
|
||||
retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
|
||||
|
||||
return retval ? retval : valuelength;
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
ssize_t ret = -1;
|
||||
int attrfd = solaris_attropen(path, name, O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
|
||||
if (attrfd >= 0) {
|
||||
ret = solaris_read_xattr(attrfd, value, size);
|
||||
close(attrfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -1818,6 +1846,14 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
|
||||
retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
|
||||
|
||||
return retval ? retval : valuelength;
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
ssize_t ret = -1;
|
||||
int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0);
|
||||
if (attrfd >= 0) {
|
||||
ret = solaris_read_xattr(attrfd, value, size);
|
||||
close(attrfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -2002,6 +2038,14 @@ ssize_t sys_listxattr (const char *path, char *list, size_t size)
|
||||
return bsd_attr_list(0, arg, list, size);
|
||||
#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
|
||||
return irix_attr_list(path, 0, list, size, 0);
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
ssize_t ret = -1;
|
||||
int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
|
||||
if (attrdirfd >= 0) {
|
||||
ret = solaris_list_xattr(attrdirfd, list, size);
|
||||
close(attrdirfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -2023,6 +2067,14 @@ ssize_t sys_llistxattr (const char *path, char *list, size_t size)
|
||||
return bsd_attr_list(1, arg, list, size);
|
||||
#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
|
||||
return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
ssize_t ret = -1;
|
||||
int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
|
||||
if (attrdirfd >= 0) {
|
||||
ret = solaris_list_xattr(attrdirfd, list, size);
|
||||
close(attrdirfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -2046,6 +2098,14 @@ ssize_t sys_flistxattr (int filedes, char *list, size_t size)
|
||||
return bsd_attr_list(2, arg, list, size);
|
||||
#elif defined(HAVE_ATTR_LISTF)
|
||||
return irix_attr_list(NULL, filedes, list, size, 0);
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
ssize_t ret = -1;
|
||||
int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
|
||||
if (attrdirfd >= 0) {
|
||||
ret = solaris_list_xattr(attrdirfd, list, size);
|
||||
close(attrdirfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -2077,6 +2137,14 @@ int sys_removexattr (const char *path, const char *name)
|
||||
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
|
||||
|
||||
return attr_remove(path, attrname, flags);
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
int ret = -1;
|
||||
int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
|
||||
if (attrdirfd >= 0) {
|
||||
ret = solaris_unlinkat(attrdirfd, name);
|
||||
close(attrdirfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -2106,6 +2174,14 @@ int sys_lremovexattr (const char *path, const char *name)
|
||||
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
|
||||
|
||||
return attr_remove(path, attrname, flags);
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
int ret = -1;
|
||||
int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
|
||||
if (attrdirfd >= 0) {
|
||||
ret = solaris_unlinkat(attrdirfd, name);
|
||||
close(attrdirfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -2137,6 +2213,14 @@ int sys_fremovexattr (int filedes, const char *name)
|
||||
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
|
||||
|
||||
return attr_removef(filedes, attrname, flags);
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
int ret = -1;
|
||||
int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
|
||||
if (attrdirfd >= 0) {
|
||||
ret = solaris_unlinkat(attrdirfd, name);
|
||||
close(attrdirfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -2195,6 +2279,17 @@ int sys_setxattr (const char *path, const char *name, const void *value, size_t
|
||||
if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
|
||||
|
||||
return attr_set(path, attrname, (const char *)value, size, myflags);
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
int ret = -1;
|
||||
int myflags = O_RDWR;
|
||||
if (flags & XATTR_CREATE) myflags |= O_EXCL;
|
||||
if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
|
||||
int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
|
||||
if (attrfd >= 0) {
|
||||
ret = solaris_write_xattr(attrfd, value, size);
|
||||
close(attrfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -2247,6 +2342,17 @@ int sys_lsetxattr (const char *path, const char *name, const void *value, size_t
|
||||
if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
|
||||
|
||||
return attr_set(path, attrname, (const char *)value, size, myflags);
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
int ret = -1;
|
||||
int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW;
|
||||
if (flags & XATTR_CREATE) myflags |= O_EXCL;
|
||||
if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
|
||||
int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
|
||||
if (attrfd >= 0) {
|
||||
ret = solaris_write_xattr(attrfd, value, size);
|
||||
close(attrfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -2300,12 +2406,148 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size
|
||||
if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
|
||||
|
||||
return attr_setf(filedes, attrname, (const char *)value, size, myflags);
|
||||
#elif defined(HAVE_ATTROPEN)
|
||||
int ret = -1;
|
||||
int myflags = O_RDWR | O_XATTR;
|
||||
if (flags & XATTR_CREATE) myflags |= O_EXCL;
|
||||
if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
|
||||
int attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE);
|
||||
if (attrfd >= 0) {
|
||||
ret = solaris_write_xattr(attrfd, value, size);
|
||||
close(attrfd);
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
helper functions for Solaris' EA support
|
||||
****************************************************************************/
|
||||
#ifdef HAVE_ATTROPEN
|
||||
static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size)
|
||||
{
|
||||
struct stat sbuf;
|
||||
|
||||
if (fstat(attrfd, &sbuf) == -1) {
|
||||
errno = ENOATTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This is to return the current size of the named extended attribute */
|
||||
if (size == 0) {
|
||||
return sbuf.st_size;
|
||||
}
|
||||
|
||||
/* check size and read xattr */
|
||||
if (sbuf.st_size > size) {
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read(attrfd, value, sbuf.st_size);
|
||||
}
|
||||
|
||||
static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
|
||||
{
|
||||
ssize_t len = 0;
|
||||
int stop = 0;
|
||||
DIR *dirp;
|
||||
struct dirent *de;
|
||||
int newfd = dup(attrdirfd);
|
||||
/* CAUTION: The originating file descriptor should not be
|
||||
used again following the call to fdopendir().
|
||||
For that reason we dup() the file descriptor
|
||||
here to make things more clear. */
|
||||
dirp = fdopendir(newfd);
|
||||
|
||||
while ((de = readdir(dirp))) {
|
||||
size_t listlen = strlen(de->d_name);
|
||||
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
|
||||
/* we don't want "." and ".." here: */
|
||||
DEBUG(10,("skipped EA %s\n",de->d_name));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
/* return the current size of the list of extended attribute names*/
|
||||
len += listlen + 1;
|
||||
} else {
|
||||
/* check size and copy entrieѕ + nul into list. */
|
||||
if ((len + listlen + 1) > size) {
|
||||
errno = ERANGE;
|
||||
len = -1;
|
||||
break;
|
||||
} else {
|
||||
safe_strcpy(list + len, de->d_name, listlen);
|
||||
pstrcpy(list + len, de->d_name);
|
||||
len += listlen;
|
||||
list[len] = '\0';
|
||||
++len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(dirp) == -1) {
|
||||
DEBUG(0,("closedir dirp failed: %s\n",strerror(errno)));
|
||||
return -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int solaris_unlinkat(int attrdirfd, const char *name)
|
||||
{
|
||||
if (unlinkat(attrdirfd, name, 0) == -1) {
|
||||
if (errno == ENOENT) {
|
||||
errno = ENOATTR;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode)
|
||||
{
|
||||
int filedes = attropen(path, attrpath, oflag, mode);
|
||||
if (filedes == -1) {
|
||||
DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path,attrpath,strerror(errno)));
|
||||
if (errno == EINVAL) {
|
||||
errno = ENOTSUP;
|
||||
} else {
|
||||
errno = ENOATTR;
|
||||
}
|
||||
}
|
||||
return filedes;
|
||||
}
|
||||
|
||||
static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode)
|
||||
{
|
||||
int filedes = openat(fildes, path, oflag, mode);
|
||||
if (filedes == -1) {
|
||||
DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes,path,strerror(errno)));
|
||||
if (errno == EINVAL) {
|
||||
errno = ENOTSUP;
|
||||
} else {
|
||||
errno = ENOATTR;
|
||||
}
|
||||
}
|
||||
return filedes;
|
||||
}
|
||||
|
||||
static int solaris_write_xattr(int attrfd, const char *value, size_t size)
|
||||
{
|
||||
if ((ftruncate(attrfd, 0) == 0) && (write(attrfd, value, size) == size)) {
|
||||
return 0;
|
||||
} else {
|
||||
DEBUG(10,("solaris_write_xattr FAILED!\n"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif /*HAVE_ATTROPEN*/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Return the major devicenumber for UNIX extensions.
|
||||
****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user