X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/16edf86595a5a990a942fa045dfb523dae1fe6cb..05a652d0b712af225d6cb72aa31beafaff601151:/lib/sysxattrs.c diff --git a/lib/sysxattrs.c b/lib/sysxattrs.c index 72fca41b..40619e32 100644 --- a/lib/sysxattrs.c +++ b/lib/sysxattrs.c @@ -2,11 +2,12 @@ * Extended attribute support for rsync. * * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 2003-2008 Wayne Davison * Written by Jay Fenlason. * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -15,8 +16,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + * with this program; if not, visit the http://fsf.org website. */ #include "rsync.h" @@ -126,6 +126,148 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size) return len; } +#elif HAVE_SOLARIS_XATTRS + +static ssize_t read_xattr(int attrfd, void *buf, size_t buflen) +{ + STRUCT_STAT sb; + ssize_t ret; + + if (fstat(fd, &sb) < 0) + ret = -1; + else if (sb.st_size > SSIZE_MAX) { + errno = ERANGE; + ret = -1; + } else if (size == 0) + ret = sb.st_size; + else if (sb.st_size > size) { + errno = ERANGE; + ret = -1; + } else { + size_t bufpos; + for (bufpos = 0; bufpos < buflen; ) { + ssize_t cnt = read(attrfd, buf + bufpos, buflen - bufpos); + if (cnt <= 0) { + if (cnt < 0 && errno == EINTR) + continue; + bufpos = -1; + break; + } + bufpos += cnt; + } + ret = bufpos; + } + + close(attrfd); + + return ret; +} + +ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size) +{ + int attrfd; + + if ((attrfd = attropen(path, name, O_RDONLY)) < 0) { + errno = ENOATTR; + return -1; + } + + return read_xattr(attrfd, value, size); +} + +ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size) +{ + int attrfd; + + if ((attrfd = openat(filedes, name, O_RDONLY|O_XATTR, 0)) < 0) { + errno = ENOATTR; + return -1; + } + + return read_xattr(attrfd, value, size); +} + +int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size) +{ + int attrfd; + size_t bufpos; + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + + if ((attrfd = attropen(path, name, O_CREAT|O_WRONLY|O_NOFOLLOW, mode)) < 0) + return -1; + + for (bufpos = 0; bufpos < size; ) { + ssize_t cnt = write(attrfd, value+bufpos, size); + if (cnt <= 0) { + if (cnt < 0 && errno == EINTR) + continue; + bufpos = -1; + break; + } + bufpos += cnt; + } + + close(attrfd); + + return bufpos > 0 ? 0 : -1; +} + +int sys_lremovexattr(const char *path, const char *name) +{ + int attrdirfd; + int ret; + + if ((attrdirfd = attropen(path, ".", O_RDWR)) < 0) + return -1; + + ret = unlinkat(attrdirfd, name, 0); + + close(attrdirfd); + + return ret; +} + +ssize_t sys_llistxattr(const char *path, char *list, size_t size) +{ + int attrdirfd; + DIR *dirp; + struct dirent *dp; + ssize_t ret = 0; + + if ((attrdirfd = attropen(path, ".", O_RDONLY)) < 0) { + errno = ENOTSUP; + return -1; + } + + if ((dirp = fdopendir(attrdirfd)) == NULL) { + close(attrdirfd); + return -1; + } + + while ((dp = readdir(dirp))) { + int len = strlen(dp->d_name); + + if (dp->d_name[0] == '.' && (len == 1 || (len == 2 && dp->d_name[1] == '.'))) + continue; + if (len == 11 && dp->d_name[0] == 'S' && strncmp(dp->d_name, "SUNWattr_r", 10) == 0 + && (dp->d_name[10] == 'o' || dp->d_name[10] == 'w')) + continue; + + if ((ret += len+1) > size) { + ret = -1; + errno = ERANGE; + break; + } + memcpy(list, dp->d_name, len+1); + list += len+1; + } + + closedir(dirp); + close(attrdirfd); + + return ret; +} + #else #error You need to create xattr compatibility functions.