X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=libatalk%2Fvfs%2Fextattr.c;h=73724d53080d66908ae3c07fa9166f58c10bd45e;hp=35587a6ede683236ba727253df8ffe0bcf033b7e;hb=c74dd3730ea1927d5083242fce4dc042f9a8646c;hpb=6ba00099278ecf64c81aaa6211059f29dbb5efdf diff --git a/libatalk/vfs/extattr.c b/libatalk/vfs/extattr.c index 35587a6e..73724d53 100644 --- a/libatalk/vfs/extattr.c +++ b/libatalk/vfs/extattr.c @@ -59,14 +59,12 @@ #include #include #include - -#ifndef ENOATTR -#define ENOATTR ENODATA -#endif +#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); @@ -91,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); @@ -149,8 +172,10 @@ ssize_t sys_getxattr (const char *path, const char *uname, void *value, size_t s #endif } -ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size) +ssize_t sys_fgetxattr (int filedes, const char *uname, void *value, size_t size) { + const char *name = prefix(uname); + #if defined(HAVE_FGETXATTR) #ifndef XATTR_ADD_OPT return fgetxattr(filedes, name, value, size); @@ -165,7 +190,7 @@ ssize_t sys_fgetxattr (int filedes, const char *name, 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) { @@ -176,7 +201,7 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size) return retval; } - DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", 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); @@ -630,8 +655,10 @@ int sys_setxattr (const char *path, const char *uname, const void *value, size_t #endif } -int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags) +int sys_fsetxattr (int filedes, const char *uname, const void *value, size_t size, int flags) { + const char *name = prefix(uname); + #if defined(HAVE_FSETXATTR) #ifndef XATTR_ADD_OPT return fsetxattr(filedes, name, value, size, flags); @@ -646,7 +673,7 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size 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); @@ -659,7 +686,6 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size /* Ignore other errors */ } else { - /* CREATE attribute, that already exists */ if (flags & XATTR_CREATE) { errno = EEXIST; return -1; @@ -740,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; @@ -823,7 +849,7 @@ static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size) } if (closedir(dirp) == -1) { - LOG(log_debug, logtype_default, "closedir dirp failed: %s\n",strerror(errno)); + LOG(log_error, logtype_default, "closedir dirp: %s",strerror(errno)); return -1; } return len; @@ -839,19 +865,59 @@ 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) { - LOG(log_maxdebug, logtype_default, "attropen FAILED: path: %s, name: %s, errno: %s\n",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_maxdebug, logtype_default, "openat FAILED: fd: %s, path: %s, errno: %s\n",filedes,path,strerror(errno)); + int filedes; + + if ((filedes = openat(fildes, path, oflag, mode)) == -1) { + switch (errno) { + case ENOENT: + case EEXIST: + case EACCES: + break; + default: + LOG(log_debug, logtype_default, "openat(\"%s\"): %s", + path, strerror(errno)); + errno = ENOATTR; + break; + } } return filedes; } @@ -861,7 +927,8 @@ 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 { - LOG(log_maxdebug, logtype_default, "solaris_write_xattr FAILED!\n"); + LOG(log_error, logtype_default, "solaris_write_xattr: %s", + strerror(errno)); return -1; } }