X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fvfs%2Fextattr.c;h=5206aa6d69d16698f62f8c2d9fd4c2c770ab7bf3;hb=dbaae078efa0b9c4559fd85bb8b139508751bf15;hp=bdae873e6c05ef3682a9db708167addd890ddf0c;hpb=313b5f94348618d65523c1d8bde1fba9988f040a;p=netatalk.git diff --git a/libatalk/vfs/extattr.c b/libatalk/vfs/extattr.c index bdae873e..5206aa6d 100644 --- a/libatalk/vfs/extattr.c +++ b/libatalk/vfs/extattr.c @@ -60,10 +60,11 @@ #include #include #include +#include /******** Solaris EA helper function prototypes ********/ #ifdef HAVE_ATTROPEN -#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP +#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH static int solaris_write_xattr(int attrfd, const char *value, size_t size); static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size); static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size); @@ -88,6 +89,31 @@ static const char *prefix(const char *uname) #endif } +int sys_getxattrfd(int fd, const char *uname, int oflag, ...) +{ +#if defined HAVE_ATTROPEN + int eafd; + va_list args; + mode_t mode = 0; + + if (oflag & O_CREAT) { + va_start(args, oflag); + mode = va_arg(args, mode_t); + va_end(args); + } + + if (oflag & O_CREAT) + eafd = solaris_openat(fd, uname, oflag | O_XATTR, mode); + else + eafd = solaris_openat(fd, uname, oflag | O_XATTR, mode); + + return eafd; +#else + errno = ENOSYS; + return -1; +#endif +} + ssize_t sys_getxattr (const char *path, const char *uname, void *value, size_t size) { const char *name = prefix(uname); @@ -164,7 +190,7 @@ ssize_t sys_fgetxattr (int filedes, const char *uname, void *value, size_t size) ssize_t retval; int attrnamespace = (strncmp(name, "system", 6) == 0) ? EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER; - const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1; + const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1; if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) { if(retval > size) { @@ -175,8 +201,7 @@ ssize_t sys_fgetxattr (int filedes, const char *uname, void *value, size_t size) return retval; } - LOG(log_debug, logtype_default, "sys_fgetxattr: extattr_get_fd(): %s", - strerror(errno))); + LOG(log_debug, logtype_default, "sys_fgetxattr: extattr_get_fd(): %s", strerror(errno)); return -1; #elif defined(HAVE_ATTR_GETF) int retval, flags = 0; @@ -238,7 +263,7 @@ ssize_t sys_lgetxattr (const char *path, const char *uname, void *value, size_t return retval ? retval : valuelength; #elif defined(HAVE_ATTROPEN) ssize_t ret = -1; - int attrfd = solaris_attropen(path, name, O_RDONLY|AT_SYMLINK_NOFOLLOW, 0); + int attrfd = solaris_attropen(path, name, O_RDONLY | O_NOFOLLOW, 0); if (attrfd >= 0) { ret = solaris_read_xattr(attrfd, value, size); close(attrfd); @@ -488,7 +513,7 @@ ssize_t sys_llistxattr (const char *path, char *list, size_t size) 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); + int attrdirfd = solaris_attropen(path, ".", O_RDONLY | O_NOFOLLOW, 0); if (attrdirfd >= 0) { ret = solaris_list_xattr(attrdirfd, list, size); close(attrdirfd); @@ -556,7 +581,7 @@ int sys_lremovexattr (const char *path, const char *uname) return attr_remove(path, attrname, flags); #elif defined(HAVE_ATTROPEN) int ret = -1; - int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0); + int attrdirfd = solaris_attropen(path, ".", O_RDONLY | O_NOFOLLOW, 0); if (attrdirfd >= 0) { ret = solaris_unlinkat(attrdirfd, name); close(attrdirfd); @@ -648,7 +673,7 @@ int sys_fsetxattr (int filedes, const char *uname, const void *value, size_t siz int retval = 0; int attrnamespace = (strncmp(name, "system", 6) == 0) ? EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER; - const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1; + const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1; if (flags) { /* Check attribute existence */ retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0); @@ -661,7 +686,6 @@ int sys_fsetxattr (int filedes, const char *uname, const void *value, size_t siz /* Ignore other errors */ } else { - log_error, logtype_default /* CREATE attribute, that already exists */ if (flags & XATTR_CREATE) { errno = EEXIST; return -1; @@ -742,7 +766,7 @@ int sys_lsetxattr (const char *path, const char *uname, const void *value, size_ return attr_set(path, attrname, (const char *)value, size, myflags); #elif defined(HAVE_ATTROPEN) int ret = -1; - int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW; + int myflags = O_RDWR | O_NOFOLLOW; int attrfd; if (flags & XATTR_CREATE) myflags |= O_EXCL; if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; @@ -841,22 +865,58 @@ static int solaris_unlinkat(int attrdirfd, const char *name) 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) { - if (errno != ENOENT) - LOG(log_error, logtype_default, "attropen(\"%s\", ea:'%s'): %s", - path, attrpath, strerror(errno)); - errno = ENOATTR; + EC_INIT; + int filedes = -1, eafd = -1; + + if ((filedes = open(path, O_RDONLY | (oflag & O_NOFOLLOW), mode)) == -1) { + switch (errno) { + case ENOENT: + case EEXIST: + case OPEN_NOFOLLOW_ERRNO: + EC_FAIL; + default: + LOG(log_debug, logtype_default, "open(\"%s\"): %s", fullpathname(path), strerror(errno)); + EC_FAIL; + } } - return filedes; + + if ((eafd = openat(filedes, attrpath, oflag | O_XATTR, mode)) == -1) { + switch (errno) { + case ENOENT: + case EEXIST: + EC_FAIL; + default: + LOG(log_debug, logtype_default, "openat(\"%s\"): %s", fullpathname(path), strerror(errno)); + EC_FAIL; + } + } + +EC_CLEANUP: + if (filedes != -1) + close(filedes); + if (ret != 0) { + if (eafd != -1) + close(eafd); + eafd = -1; + } + return eafd; } static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode) { - int filedes = openat(fildes, path, oflag, mode); - if (filedes == -1) { - LOG(log_error, logtype_default, "openat(\"%s\"): %s", - path, strerror(errno)); + int filedes; + + if ((filedes = openat(fildes, path, oflag, mode)) == -1) { + switch (errno) { + case ENOENT: + case EEXIST: + break; + default: + LOG(log_debug, logtype_default, "openat(\"%s\"): %s", + path, strerror(errno)); + errno = ENOATTR; + break; + } } return filedes; }