Diff for /embedaddon/rsync/lib/sysxattrs.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2012/02/17 15:09:30 version 1.1.1.4, 2021/03/17 00:32:36
Line 2 Line 2
  * Extended attribute support for rsync.   * Extended attribute support for rsync.
  *   *
  * Copyright (C) 2004 Red Hat, Inc.   * Copyright (C) 2004 Red Hat, Inc.
 * Copyright (C) 2003-2008 Wayne Davison * Copyright (C) 2003-2019 Wayne Davison
  * Written by Jay Fenlason.   * Written by Jay Fenlason.
  *   *
  * This program is free software; you can redistribute it and/or modify   * This program is free software; you can redistribute it and/or modify
Line 22 Line 22
 #include "rsync.h"  #include "rsync.h"
 #include "sysxattrs.h"  #include "sysxattrs.h"
   
   extern int preserve_hfs_compression;
   
 #ifdef SUPPORT_XATTRS  #ifdef SUPPORT_XATTRS
   
   #ifdef HAVE_OSX_XATTRS
   #ifndef XATTR_SHOWCOMPRESSION
   #define XATTR_SHOWCOMPRESSION 0x0020
   #endif
   #define GETXATTR_FETCH_LIMIT (64*1024*1024)
   
   int xattr_options = XATTR_NOFOLLOW;
   #endif
   
 #if defined HAVE_LINUX_XATTRS  #if defined HAVE_LINUX_XATTRS
   
 ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)  ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
Line 55  ssize_t sys_llistxattr(const char *path, char *list, s Line 66  ssize_t sys_llistxattr(const char *path, char *list, s
   
 ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)  ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
 {  {
        return getxattr(path, name, value, size, 0, XATTR_NOFOLLOW);        ssize_t len;
 
         if (preserve_hfs_compression)
                 xattr_options |= XATTR_SHOWCOMPRESSION;
 
         len = getxattr(path, name, value, size, 0, xattr_options);
 
         /* If we're retrieving data, handle resource forks > 64MB specially */
         if (value != NULL && len == GETXATTR_FETCH_LIMIT && (size_t)len < size) {
                 /* getxattr will only return 64MB of data at a time, need to call again with a new offset */
                 u_int32_t offset = len;
                 size_t data_retrieved = len;
                 while (data_retrieved < size) {
                         len = getxattr(path, name, value + offset, size - data_retrieved, offset, xattr_options);
                         if (len <= 0)
                                 break;
                         data_retrieved += len;
                         offset += (u_int32_t)len;
                 }
                 len = data_retrieved;
         }
 
         return len;
 }  }
   
 ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)  ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
Line 70  int sys_lsetxattr(const char *path, const char *name,  Line 103  int sys_lsetxattr(const char *path, const char *name, 
   
 int sys_lremovexattr(const char *path, const char *name)  int sys_lremovexattr(const char *path, const char *name)
 {  {
        return removexattr(path, name, XATTR_NOFOLLOW);        if (preserve_hfs_compression)
                 xattr_options |= XATTR_SHOWCOMPRESSION;
         return removexattr(path, name, xattr_options);
 }  }
   
 ssize_t sys_llistxattr(const char *path, char *list, size_t size)  ssize_t sys_llistxattr(const char *path, char *list, size_t size)
 {  {
        return listxattr(path, list, size, XATTR_NOFOLLOW);        if (preserve_hfs_compression)
                 xattr_options |= XATTR_SHOWCOMPRESSION;
         return listxattr(path, list, size, xattr_options);
 }  }
   
 #elif HAVE_FREEBSD_XATTRS  #elif HAVE_FREEBSD_XATTRS
Line 124  ssize_t sys_llistxattr(const char *path, char *list, s Line 161  ssize_t sys_llistxattr(const char *path, char *list, s
         }          }
   
         return len;          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(attrfd, &sb) < 0)
                   ret = -1;
           else if (sb.st_size > SSIZE_MAX) {
                   errno = ERANGE;
                   ret = -1;
           } else if (buflen == 0)
                   ret = sb.st_size;
           else if (sb.st_size > buflen) {
                   errno = ERANGE;
                   ret = -1;
           } else {
                   size_t bufpos;
                   for (bufpos = 0; bufpos < sb.st_size; ) {
                           ssize_t cnt = read(attrfd, buf + bufpos, sb.st_size - 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_TRUNC|O_WRONLY, 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_RDONLY)) < 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) {
                           if (size == 0)
                                   continue;
                           ret = -1;
                           errno = ERANGE;
                           break;
                   }
                   memcpy(list, dp->d_name, len+1);
                   list += len+1;
           }
   
           closedir(dirp);
           close(attrdirfd);
   
           return ret;
 }  }
   
 #else  #else

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>