#include <atalk/logger.h>
#include <atalk/ea.h>
#include <atalk/compat.h>
+#include <atalk/errchk.h>
/******** 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);
#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);
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) {
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;
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);
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);
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);
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);
/* Ignore other errors */
}
else {
- log_error, logtype_default /* CREATE attribute, that already exists */
if (flags & XATTR_CREATE) {
errno = EEXIST;
return -1;
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;
}
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;
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",
- 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: %d, path: %s, errno: %s",
- 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;
}
if ((ftruncate(attrfd, 0) == 0) && (write(attrfd, value, size) == size)) {
return 0;
} else {
- LOG(log_maxdebug, logtype_default, "solaris_write_xattr FAILED!");
+ LOG(log_error, logtype_default, "solaris_write_xattr: %s",
+ strerror(errno));
return -1;
}
}