Пример #1
0
ssize_t rep_flistxattr (int filedes, char *list, size_t size)
{
#if defined(HAVE_FLISTXATTR)
#ifndef XATTR_ADDITIONAL_OPTIONS
	return flistxattr(filedes, list, size);
#else
/* So that we do not recursivly call this function */
#undef flistxattr
	int options = 0;
	return flistxattr(filedes, list, size, options);
#endif
#elif defined(HAVE_FLISTEA)
	return flistea(filedes, list, size);
#elif defined(HAVE_EXTATTR_LIST_FD)
	extattr_arg arg;
	arg.filedes = filedes;
	return bsd_attr_list(2, arg, list, size);
#elif defined(HAVE_ATTR_LISTF)
	return irix_attr_list(NULL, filedes, list, size, 0);
#elif defined(HAVE_ATTROPEN)
	ssize_t ret = -1;
	int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
	if (attrdirfd >= 0) {
		ret = solaris_list_xattr(attrdirfd, list, size);
		close(attrdirfd);
	}
	return ret;
#else
	errno = ENOSYS;
	return -1;
#endif
}
Пример #2
0
// list all keys, caller responsible for freeing
void xattrkv_keys(int db, char ***keys, size_t *nkeys) {
    // flistxattr gives a buffer of null terminated strings

    // find out how much space to allocate
    size_t size = (size_t) flistxattr(db, NULL, 0, 0);
    char *buffer = malloc(size);
    flistxattr(db, buffer, size, 0);

    size_t keycount = 0;
    
    for (int i = 0; i < size; i++) {
        if (buffer[i] == '\0') {
            keycount++;
        }
    }
    *nkeys = keycount;
    *keys = malloc(sizeof(char*) * keycount);

    size_t index = 0;
    size_t bufpos = 0;
    // this is probably insane
    while (index != keycount) {
        *(*keys + index) = strdup(buffer+bufpos);
        bufpos = bufpos + strlen(*(*keys+index)) + 1;
        index = index + 1;
    }
}
Пример #3
0
static INT64_T chirp_fs_local_flistxattr(int fd, char *list, size_t size)
{
#ifdef CCTOOLS_OPSYS_DARWIN
	return flistxattr(fd, list, size, 0);
#else
	return flistxattr(fd, list, size);
#endif
}
Пример #4
0
static INT64_T chirp_fs_local_flistxattr(int fd, char *list, size_t size)
{
	PREAMBLE("flistxattr(%d, %p, %zu)", fd, list, size);
	SETUP_FILE
#ifdef CCTOOLS_OPSYS_DARWIN
	rc = flistxattr(lfd, list, size, 0);
#else
	rc = flistxattr(lfd, list, size);
#endif
	PROLOGUE
}
Пример #5
0
ssize_t
ceph_os_flistxattr(int fd, char *list, size_t size)
{
	ssize_t error = -1;

#if defined(__FreeBSD__)
	/*
	 * XXX. The format of the list FreeBSD returns differs
	 * from the Linux ones.  We have to perform the conversion. :-(
	 */
	char *newlist, *p, *p1;

	if (size != 0) {
		newlist = malloc(size);
		if (newlist != NULL) {
			error = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER,
			    newlist, size);
			if (error > 0) {
				p = newlist;
				p1 = list;
				while ((p - newlist) < error) {
					uint8_t len = *(uint8_t *)p;
					p++;
					if ((p + len - newlist) > error)
						break;
					if (len > 0) {
						bcopy(p, p1, len);
						p += len;
						p1 += len;
						*p1++ = '\0';
					}
				}
				error = p1 - list;
			}
			free(newlist);
		}
	} else {
		error = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER,
		    list, size);
	}
#elif defined(__linux__)
	//提取文件的所有属性列表
	error = flistxattr(fd, list, size);
#elif defined(__APPLE__)
	error = flistxattr(fd, list, size, 0);
#endif

	return (error);
}
Пример #6
0
ssize_t mdir_list_xattr(mdir_t *mdir, char *list, size_t size) {
    ssize_t status;

    status = flistxattr(mdir->fdp, list, size);

    return status;
}
Пример #7
0
ssize_t mslnk_list_xattr(mslnk_t *mslnk, char *list, size_t size) {
    ssize_t status;

    status = flistxattr(mslnk->fdattrs, list, size);

    return status;
}
Пример #8
0
static int check_suitable_buf(const int file, long size)
{
	int n;
	char buf[size];

	n = flistxattr(file, buf, sizeof(buf));

	return n != -1;
}
Пример #9
0
static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) {
    if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) {
        return -1;
    }
    if (options & XATTR_XATTR_NOFOLLOW) {
        return -1;
    } else {
        return flistxattr(fd, namebuf, size);
    }
}
Пример #10
0
ssize_t sys_flistxattr (int filedes, char *list, size_t size)
{
#if defined(HAVE_FLISTXATTR)
	return flistxattr(filedes, list, size);
#elif defined(HAVE_ATTR_LISTF)
	return irix_attr_list(NULL, filedes, list, size, 0);
#else
	errno = ENOSYS;
	return -1;
#endif
}
Пример #11
0
JNIEXPORT jint JNICALL
Java_sun_nio_fs_LinuxNativeDispatcher_flistxattr(JNIEnv* env, jclass clazz,
    jint fd, jlong listAddress, jint size)
{
    size_t res = -1;
    char* list = jlong_to_ptr(listAddress);

    res = flistxattr (fd, list, (size_t)size);
    if (res == (size_t)-1)
        throwUnixException(env, errno);
    return (jint)res;
}
Пример #12
0
static void verify_flistxattr(unsigned int n)
{
	TEST(flistxattr(fd[n], NULL, 0));
	if (TEST_RETURN == -1) {
		tst_res(TFAIL | TTERRNO, "flistxattr() failed");
		return;
	}

	if (check_suitable_buf(fd[n], TEST_RETURN))
		tst_res(TPASS, "flistxattr() succeed with suitable buffer");
	else
		tst_res(TFAIL, "flistxattr() failed with small buffer");
}
Пример #13
0
int verify_orig_file_xattr(enum FILE_TYPE ft, char *filename,
			   unsigned long list_size)
{
	unsigned long j;
	int ret = 0, fd;

	/*List all EA names if xattr_nums *(xattr_name_sz+1) less than 65536*/
	fd = open64(filename, open_ro_flags);

	for (j = 0; j < xattr_nums; j++)
		memset(xattr_name_list_get[j], 0, xattr_name_sz + 1);

	switch (ft) {
	case NORMAL:
		ret = flistxattr(fd, (void *)list, list_size);
		break;
	case SYMLINK:
		ret = llistxattr(filename, (void *)list, list_size);
		break;
	case DIRECTORY:
		ret = listxattr(filename, (void *)list, list_size);
		break;
	default:
		break;
	}

	list_parser(list);

	for (j = 0; j < xattr_nums; j++) {
		if (!is_namelist_member(xattr_nums, xattr_name_list_get[j],
		    xattr_name_list_set)) {
			fprintf(stderr, "Xattr list name(%s) "
				"did not match the orginal one\n",
				xattr_name_list_get[j]);
			ret = -1;
			return ret;
		}
	}

	close(fd);

	return 0;
}
Пример #14
0
static void verify_flistxattr(unsigned int n)
{
	struct test_case *t = tc + n;
	char buf[t->size];

	TEST(flistxattr(*t->fd, buf, t->size));
	if (TEST_RETURN != -1) {
		tst_res(TFAIL,
			"flistxattr() succeeded unexpectedly (returned %ld)",
			TEST_RETURN);
		return;
	}

	if (t->exp_err != TEST_ERRNO) {
		tst_res(TFAIL | TTERRNO, "flistxattr() failed "
			 "unexpectedlly, expected %s",
			 tst_strerrno(t->exp_err));
	} else {
		tst_res(TPASS | TTERRNO,
			 "flistxattr() failed as expected");
	}
}
Пример #15
0
/**
 *  return index if found,
 *  negative value on error.
 */
static int xattr_name_to_id(int fd, const char *name)
{
	unsigned int i;
	char names[MAXPATHLEN], *ptr;
	ssize_t namesize;

	/* get xattrs */

	namesize = flistxattr(fd, names, sizeof(names));

	if (namesize < 0)
		return -ERR_FSAL_NOENT;

	if (!strncmp(name, "system.posix_acl_access", MAXNAMLEN))
		return XATTR_SYSTEM;

	for (ptr = names, i = 0; ptr < names + namesize;
	     i++, ptr += strlen(ptr) + 1) {
		if (!strcmp(name, ptr))
			return i + XATTR_COUNT;
	}
	return -ERR_FSAL_NOENT;
}
Пример #16
0
static int xattr_id_to_name(int fd, unsigned int xattr_id, char *name)
{
	unsigned int index;
	unsigned int curr_idx;
	char names[MAXPATHLEN], *ptr;
	ssize_t namesize;
	size_t len = 0;

	if (xattr_id < XATTR_COUNT)
		return ERR_FSAL_INVAL;

	index = xattr_id - XATTR_COUNT;

	/* get xattrs */

	namesize = flistxattr(fd, names, sizeof(names));

	if (namesize < 0)
		return ERR_FSAL_NOENT;

	errno = 0;

	if (xattr_id == XATTR_SYSTEM) {
		strcpy(name, "system.posix_acl_access");
		return ERR_FSAL_NO_ERROR;
	}

	for (ptr = names, curr_idx = 0; ptr < names + namesize;
	     curr_idx++, ptr += len + 1) {
		len = strlen(ptr);
		if (curr_idx == index) {
			strcpy(name, ptr);
			return ERR_FSAL_NO_ERROR;
		}
	}
	return ERR_FSAL_NOENT;
}
static int
setup_xattrs(struct archive_read_disk *a,
    struct archive_entry *entry, int *fd)
{
	char *list, *p;
	const char *path;
	ssize_t list_size;

	path = archive_entry_sourcepath(entry);
	if (path == NULL)
		path = archive_entry_pathname(entry);

	if (*fd < 0 && a->tree != NULL) {
		if (a->follow_symlinks ||
		    archive_entry_filetype(entry) != AE_IFLNK)
			*fd = a->open_on_current_dir(a->tree, path,
				O_RDONLY | O_NONBLOCK);
		if (*fd < 0) {
			if (a->tree_enter_working_dir(a->tree) != 0) {
				archive_set_error(&a->archive, errno,
				    "Couldn't access %s", path);
				return (ARCHIVE_FAILED);
			}
		}
	}

#if HAVE_FLISTXATTR
	if (*fd >= 0)
		list_size = flistxattr(*fd, NULL, 0);
	else if (!a->follow_symlinks)
		list_size = llistxattr(path, NULL, 0);
	else
		list_size = listxattr(path, NULL, 0);
#elif HAVE_FLISTEA
	if (*fd >= 0)
		list_size = flistea(*fd, NULL, 0);
	else if (!a->follow_symlinks)
		list_size = llistea(path, NULL, 0);
	else
		list_size = listea(path, NULL, 0);
#endif

	if (list_size == -1) {
		if (errno == ENOTSUP || errno == ENOSYS)
			return (ARCHIVE_OK);
		archive_set_error(&a->archive, errno,
			"Couldn't list extended attributes");
		return (ARCHIVE_WARN);
	}

	if (list_size == 0)
		return (ARCHIVE_OK);

	if ((list = malloc(list_size)) == NULL) {
		archive_set_error(&a->archive, errno, "Out of memory");
		return (ARCHIVE_FATAL);
	}

#if HAVE_FLISTXATTR
	if (*fd >= 0)
		list_size = flistxattr(*fd, list, list_size);
	else if (!a->follow_symlinks)
		list_size = llistxattr(path, list, list_size);
	else
		list_size = listxattr(path, list, list_size);
#elif HAVE_FLISTEA
	if (*fd >= 0)
		list_size = flistea(*fd, list, list_size);
	else if (!a->follow_symlinks)
		list_size = llistea(path, list, list_size);
	else
		list_size = listea(path, list, list_size);
#endif

	if (list_size == -1) {
		archive_set_error(&a->archive, errno,
			"Couldn't retrieve extended attributes");
		free(list);
		return (ARCHIVE_WARN);
	}

	for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
		if (strncmp(p, "system.", 7) == 0 ||
				strncmp(p, "xfsroot.", 8) == 0)
			continue;
		setup_xattr(a, entry, p, *fd);
	}

	free(list);
	return (ARCHIVE_OK);
}
Пример #18
0
int
fd_based_fops_1 (char *filename)
{
        int         fd        = 0;
        int         ret       = -1;
        struct stat stbuf     = {0,};
        char        wstr[50]  = {0,};
        char        rstr[50]  = {0,};

        fd = open (filename, O_RDWR|O_CREAT);
        if (fd < 0) {
                fd = 0;
                fprintf (stderr, "open failed : %s\n", strerror (errno));
                goto out;
        }

        ret = unlink (filename);
        if (ret < 0) {
                fprintf (stderr, "unlink failed : %s\n", strerror (errno));
                goto out;
        }

        strcpy (wstr, "This is my string\n");
        ret = write (fd, wstr, strlen(wstr));
        if (ret <= 0) {
                ret = -1;
                fprintf (stderr, "write failed: %s\n", strerror (errno));
                goto out;
        }

        ret = lseek (fd, 0, SEEK_SET);
        if (ret < 0) {
                fprintf (stderr, "lseek failed: %s\n", strerror (errno));
                goto out;
        }

        ret = read (fd, rstr, strlen(wstr));
        if (ret <= 0) {
                ret = -1;
                fprintf (stderr, "read failed: %s\n", strerror (errno));
                goto out;
        }

        ret = memcmp (rstr, wstr, strlen (wstr));
        if (ret != 0) {
                ret = -1;
                fprintf (stderr, "read returning junk\n");
                goto out;
        }

        ret = ftruncate (fd, 0);
        if (ret < 0) {
                fprintf (stderr, "ftruncate failed : %s\n", strerror (errno));
                goto out;
        }

        ret = fstat (fd, &stbuf);
        if (ret < 0) {
                fprintf (stderr, "fstat failed : %s\n", strerror (errno));
                goto out;
        }

        ret = fchmod (fd, 0640);
        if (ret < 0) {
                fprintf (stderr, "fchmod failed : %s\n", strerror (errno));
                goto out;
        }

        ret = fchown (fd, 10001, 10001);
        if (ret < 0) {
                fprintf (stderr, "fchown failed : %s\n", strerror (errno));
                goto out;
        }

        ret = fsync (fd);
        if (ret < 0) {
                fprintf (stderr, "fsync failed : %s\n", strerror (errno));
                goto out;
        }

        ret = fsetxattr (fd, "trusted.xattr-test", "working", 8, 0);
        if (ret < 0) {
                fprintf (stderr, "fsetxattr failed : %s\n", strerror (errno));
                goto out;
        }

        ret = fdatasync (fd);
        if (ret < 0) {
                fprintf (stderr, "fdatasync failed : %s\n", strerror (errno));
                goto out;
        }

        ret = flistxattr (fd, NULL, 0);
        if (ret <= 0) {
                ret = -1;
                fprintf (stderr, "flistxattr failed : %s\n", strerror (errno));
                goto out;
        }

        ret = fgetxattr (fd, "trusted.xattr-test", NULL, 0);
        if (ret <= 0) {
                ret = -1;
                fprintf (stderr, "fgetxattr failed : %s\n", strerror (errno));
                goto out;
        }

        ret = fremovexattr (fd, "trusted.xattr-test");
        if (ret < 0) {
                fprintf (stderr, "fremovexattr failed : %s\n", strerror (errno));
                goto out;
        }

        ret = 0;
out:
        if (fd)
                close (fd);

        return ret;
}
Пример #19
0
XAErrorCode XAFileLoadAttributes(XAFileRef fileRef)
{
	XAErrorCode eCode = XAErrorImmaterial;
	
	CFIndex bSize = CFStringGetLength(fileRef->path) + 0x01;
	
	char *buffer = calloc(bSize, sizeof(*buffer));
	
	if(CFStringGetCString(fileRef->path, buffer, bSize, kCFStringEncodingUTF8))
	{
		int fd = open(buffer, O_RDONLY, 0x00);

		if(fd > 0x00)
		{
			char *keys = 0x00; size_t size = 0x00; int options = 0x00;
			
			CFArrayRemoveAllValues(fileRef->attributes);

			size = flistxattr(fd, keys, size, options);

			if(size > 0x00)
			{
				CFAllocatorRef allocator = CFGetAllocator(fileRef);
				
				char *key = 0x00;
				
				keys = calloc(size, sizeof(*keys));
				
				size = flistxattr(fd, keys, size, options);
				
				eCode = XAErrorNone;
				
				for(key = keys; key < keys + size; key += 0x01 + strlen(key))
				{
					XAAttributeRef attributeRef = 0x00;
					
					attributeRef = XAAttributeCreate(allocator);
					
					if(XAAttributeLoadFileDescriptor(attributeRef, fd, key))
					{
						CFArrayAppendValue(fileRef->attributes, attributeRef);	
						
						CFRelease(attributeRef);
					}else
					{
						CFRelease(attributeRef);

						eCode = XAErrorImmaterial;
						break;
					}
					
				}
				
			}else
			{
				eCode = XAErrorImmaterial;
				//fprintf(stderr, "listxattr error: %s\n", strerr(errno));
			}

			close(fd);

		}

	}
	fileRef->edited = 0x00;
	
	free(buffer);
	
	return(eCode);
}
Пример #20
0
fsal_status_t vfs_list_ext_attrs(struct fsal_obj_handle *obj_hdl,
				 const struct req_op_context *opctx,
				 unsigned int argcookie,
				 fsal_xattrent_t *xattrs_tab,
				 unsigned int xattrs_tabsize,
				 unsigned int *p_nb_returned, int *end_of_list)
{
	unsigned int index;
	unsigned int out_index;
	unsigned int cookie = argcookie;
	struct vfs_fsal_obj_handle *obj_handle = NULL;
	int fd = -1;
	fsal_errors_t fe;

	char names[MAXPATHLEN], *ptr;
	ssize_t namesize;
	int xattr_idx;

	obj_handle =
	    container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle);

	/* Deal with special cookie */
	if (cookie == XATTR_RW_COOKIE)
		cookie = XATTR_COUNT;

	for (index = cookie, out_index = 0;
	     index < XATTR_COUNT && out_index < xattrs_tabsize; index++) {
		if (do_match_type
		    (xattr_list[index].flags, obj_hdl->attributes.type)) {
			/* fills an xattr entry */
			xattrs_tab[out_index].xattr_id = index;
			strncpy(xattr_list[index].xattr_name,
				xattrs_tab[out_index].xattr_name, MAXNAMLEN);
			xattrs_tab[out_index].xattr_cookie = index + 1;

			/* set asked attributes (all supported) */
			xattrs_tab[out_index].attributes.mask =
			    obj_hdl->attributes.mask;

			if (file_attributes_to_xattr_attrs
			    (&obj_hdl->attributes,
			     &xattrs_tab[out_index].attributes, index)) {
				/* set error flag */
				xattrs_tab[out_index].attributes.mask =
				    ATTR_RDATTR_ERR;
			}

			/* next output slot */
			out_index++;
		}
	}

	/* save a call if output array is full */
	if (out_index == xattrs_tabsize) {
		*end_of_list = FALSE;
		*p_nb_returned = out_index;
		return fsalstat(ERR_FSAL_NO_ERROR, 0);
	}

	/* get the path of the file in Lustre */
	fd = (obj_hdl->type == DIRECTORY) ?
		vfs_fsal_open(obj_handle, O_DIRECTORY, &fe) :
		vfs_fsal_open(obj_handle, O_RDWR, &fe);
	if (fd < 0)
		return fsalstat(fe, -fd);

	/* get xattrs */

	namesize = flistxattr(fd, names, sizeof(names));

	if (namesize >= 0) {
		size_t len = 0;

		errno = 0;

		for (ptr = names, xattr_idx = 0;
		     (ptr < names + namesize) && (out_index < xattrs_tabsize);
		     xattr_idx++, ptr += len + 1) {
			len = strlen(ptr);
			index = XATTR_COUNT + xattr_idx;

			/* skip if index is before cookie */
			if (index < cookie)
				continue;

			/* fills an xattr entry */
			xattrs_tab[out_index].xattr_id = index;
			strncpy(xattrs_tab[out_index].xattr_name, ptr, len + 1);
			xattrs_tab[out_index].xattr_cookie = index + 1;

			/* set asked attributes (all supported) */
			xattrs_tab[out_index].attributes.mask =
			    obj_hdl->attributes.mask;

			if (file_attributes_to_xattr_attrs
			    (&obj_hdl->attributes,
			     &xattrs_tab[out_index].attributes, index)) {
				/* set error flag */
				xattrs_tab[out_index].attributes.mask =
				    ATTR_RDATTR_ERR;
			}

			/* next output slot */
			out_index++;
		}
		/* all xattrs are in the output array */
		if (ptr >= names + namesize)
			*end_of_list = TRUE;
		else
			*end_of_list = FALSE;
	} else			/* no xattrs */
		*end_of_list = TRUE;

	*p_nb_returned = out_index;

	close(fd);
	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
Пример #21
0
/* get all xattrs from file given by FILE_NAME or FD (when non-zero).  This
   includes all the user.*, security.*, system.*, etc. available domains */
void
xattrs_xattrs_get (int parentfd, char const *file_name,
                   struct tar_stat_info *st, int fd)
{
  if (xattrs_option > 0)
    {
#ifndef HAVE_XATTRS
      static int done = 0;
      if (!done)
        WARN ((0, 0, _("XATTR support is not available")));
      done = 1;
#else
      static size_t xsz = 1024;
      static char *xatrs = NULL;
      ssize_t xret = -1;

      if (!xatrs)
	xatrs = x2nrealloc (xatrs, &xsz, 1);

      while (((fd == 0) ?
              ((xret =
                llistxattrat (parentfd, file_name, xatrs, xsz)) == -1) :
	      ((xret = flistxattr (fd, xatrs, xsz)) == -1))
             && (errno == ERANGE))
        {
	  xatrs = x2nrealloc (xatrs, &xsz, 1);
        }

      if (xret == -1)
        call_arg_warn ((fd == 0) ? "llistxattrat" : "flistxattr", file_name);
      else
        {
          const char *attr = xatrs;
          static size_t asz = 1024;
          static char *val = NULL;

          if (!val)
            val = x2nrealloc (val, &asz, 1);

          while (xret > 0)
            {
              size_t len = strlen (attr);
              ssize_t aret = 0;

              /* Archive all xattrs during creation, decide at extraction time
               * which ones are of interest/use for the target filesystem. */
              while (((fd == 0)
                      ? ((aret = lgetxattrat (parentfd, file_name, attr,
                                              val, asz)) == -1)
                      : ((aret = fgetxattr (fd, attr, val, asz)) == -1))
                     && (errno == ERANGE))
                {
		  val = x2nrealloc (val, &asz, 1);
                }

              if (aret != -1)
                xheader_xattr_add (st, attr, val, aret);
              else if (errno != ENOATTR)
                call_arg_warn ((fd == 0) ? "lgetxattrat"
                               : "fgetxattr", file_name);

              attr += len + 1;
              xret -= len + 1;
            }
        }
#endif
    }
}
static int
setup_xattrs(struct archive_read_disk *a,
    struct archive_entry *entry, int *fd)
{
	char *list, *p;
	const char *path;
	ssize_t list_size;

	path = NULL;

	if (*fd < 0) {
		path = archive_read_disk_entry_setup_path(a, entry, fd);
		if (path == NULL)
			return (ARCHIVE_WARN);
	}

	if (*fd >= 0) {
#if ARCHIVE_XATTR_LINUX
		list_size = flistxattr(*fd, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		list_size = flistxattr(*fd, NULL, 0, 0);
#elif ARCHIVE_XATTR_AIX
		list_size = flistea(*fd, NULL, 0);
#endif
	} else if (!a->follow_symlinks) {
#if ARCHIVE_XATTR_LINUX
		list_size = llistxattr(path, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW);
#elif ARCHIVE_XATTR_AIX
		list_size = llistea(path, NULL, 0);
#endif
	} else {
#if ARCHIVE_XATTR_LINUX
		list_size = listxattr(path, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		list_size = listxattr(path, NULL, 0, 0);
#elif ARCHIVE_XATTR_AIX
		list_size = listea(path, NULL, 0);
#endif
	}

	if (list_size == -1) {
		if (errno == ENOTSUP || errno == ENOSYS)
			return (ARCHIVE_OK);
		archive_set_error(&a->archive, errno,
			"Couldn't list extended attributes");
		return (ARCHIVE_WARN);
	}

	if (list_size == 0)
		return (ARCHIVE_OK);

	if ((list = malloc(list_size)) == NULL) {
		archive_set_error(&a->archive, errno, "Out of memory");
		return (ARCHIVE_FATAL);
	}

	if (*fd >= 0) {
#if ARCHIVE_XATTR_LINUX
		list_size = flistxattr(*fd, list, list_size);
#elif ARCHIVE_XATTR_DARWIN
		list_size = flistxattr(*fd, list, list_size, 0);
#elif ARCHIVE_XATTR_AIX
		list_size = flistea(*fd, list, list_size);
#endif
	} else if (!a->follow_symlinks) {
#if ARCHIVE_XATTR_LINUX
		list_size = llistxattr(path, list, list_size);
#elif ARCHIVE_XATTR_DARWIN
		list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW);
#elif ARCHIVE_XATTR_AIX
		list_size = llistea(path, list, list_size);
#endif
	} else {
#if ARCHIVE_XATTR_LINUX
		list_size = listxattr(path, list, list_size);
#elif ARCHIVE_XATTR_DARWIN
		list_size = listxattr(path, list, list_size, 0);
#elif ARCHIVE_XATTR_AIX
		list_size = listea(path, list, list_size);
#endif
	}

	if (list_size == -1) {
		archive_set_error(&a->archive, errno,
			"Couldn't retrieve extended attributes");
		free(list);
		return (ARCHIVE_WARN);
	}

	for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
#if ARCHIVE_XATTR_LINUX
		/* Linux: skip POSIX.1e ACL extended attributes */
		if (strncmp(p, "system.", 7) == 0 &&
		   (strcmp(p + 7, "posix_acl_access") == 0 ||
		    strcmp(p + 7, "posix_acl_default") == 0))
			continue;
		if (strncmp(p, "trusted.SGI_", 12) == 0 &&
		   (strcmp(p + 12, "ACL_DEFAULT") == 0 ||
		    strcmp(p + 12, "ACL_FILE") == 0))
			continue;

		/* Linux: xfsroot namespace is obsolete and unsupported */
		if (strncmp(p, "xfsroot.", 8) == 0)
			continue;
#endif
		setup_xattr(a, entry, p, *fd, path);
	}

	free(list);
	return (ARCHIVE_OK);
}
Пример #23
0
/* Copy extended attributes from src_path to dst_path. If the file
   has an extended Access ACL (system.posix_acl_access) and that is
   copied successfully, the file mode permission bits are copied as
   a side effect. This may not always the case, so the file mode
   and/or ownership must be copied separately. */
int
attr_copy_fd(const char *src_path, int src_fd,
	     const char *dst_path, int dst_fd,
	     int (*check) (const char *, struct error_context *),
	     struct error_context *ctx)
{
#if defined(HAVE_FLISTXATTR) && defined(HAVE_FGETXATTR) && \
    defined(HAVE_FSETXATTR)
	int ret = 0;
	ssize_t size;
	char *names = NULL, *end_names, *name, *value = NULL;
	unsigned int setxattr_ENOTSUP = 0;

	/* ignore acls by default */
	if (check == NULL)
		check = attr_copy_check_permissions;

	size = flistxattr (src_fd, NULL, 0);
	if (size < 0) {
		if (errno != ENOSYS && errno != ENOTSUP) {
			const char *qpath = quote (ctx, src_path);
			error (ctx, _("listing attributes of %s"), qpath);
			quote_free (ctx, qpath);
			ret = -1;
		}
		goto getout;
	}
	names = (char *) my_alloc (size+1);
	if (names == NULL) {
		error (ctx, "");
		ret = -1;
		goto getout;
	}
	size = flistxattr (src_fd, names, size);
	if (size < 0) {
		const char *qpath = quote (ctx, src_path);
		error (ctx, _("listing attributes of %s"), qpath);
		quote_free (ctx, qpath);
		ret = -1;
		goto getout;
	} else {
		names[size] = '\0';
		end_names = names + size;
	}

	for (name = names; name != end_names; name = strchr(name, '\0') + 1) {
		void *old_value;

		/* check if this attribute shall be preserved */
		if (!*name || !check(name, ctx))
			continue;

		size = fgetxattr (src_fd, name, NULL, 0);
		if (size < 0) {
			const char *qpath = quote (ctx, src_path);
			const char *qname = quote (ctx, name);
			error (ctx, _("getting attribute %s of %s"),
			       qpath, qname);
			quote_free (ctx, qname);
			quote_free (ctx, qpath);
			ret = -1;
			continue;
		}
		value = (char *) realloc (old_value = value, size);
		if (size != 0 && value == NULL) {
			free(old_value);
			error (ctx, "");
			ret = -1;
		}
		size = fgetxattr (src_fd, name, value, size);
		if (size < 0) {
			const char *qpath = quote (ctx, src_path);
			const char *qname = quote (ctx, name);
			error (ctx, _("getting attribute %s of %s"),
			       qname, qpath);
			quote_free (ctx, qname);
			quote_free (ctx, qpath);
			ret = -1;
			continue;
		}
		if (fsetxattr (dst_fd, name, value, size, 0) != 0) {
			if (errno == ENOTSUP)
				setxattr_ENOTSUP++;
			else {
				const char *qpath = quote (ctx, dst_path);

				if (errno == ENOSYS) {
					error (ctx, _("setting attributes for "
					       "%s"), qpath);
					ret = -1;
					break;  /* no hope of getting any further */
				} else {
					const char *qname = quote (ctx, name);
					error (ctx, _("setting attribute %s for %s"),
					       qname, qpath);
					quote_free (ctx, qname);
					ret = -1;
				}
				quote_free (ctx, qpath);
			}
		}
	}
	if (setxattr_ENOTSUP) {
		const char *qpath = quote (ctx, dst_path);
		errno = ENOTSUP;
		error (ctx, _("setting attributes for %s"), qpath);
		ret = -1;
		quote_free (ctx, qpath);
	}
getout:
	free (value);
	my_free (names);
	return ret;
#else
	return 0;
#endif
}
Пример #24
0
/*
 *  stress_xattr
 *	stress the xattr operations
 */
int stress_xattr(
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name)
{
	pid_t pid = getpid();
	int ret, fd, rc = EXIT_FAILURE;
	char filename[PATH_MAX];

	ret = stress_temp_dir_mk(name, pid, instance);
	if (ret < 0)
		return exit_status(-ret);

	(void)stress_temp_filename(filename, sizeof(filename),
		name, pid, instance, mwc32());
	(void)umask(0077);
	if ((fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
		rc = exit_status(errno);
		pr_fail_err(name, "open");
		goto out;
	}
	(void)unlink(filename);

	do {
		int i, j;
		int ret;
		char attrname[32];
		char value[32];
		ssize_t sz;
		char *buffer;

		for (i = 0; i < 4096; i++) {
			snprintf(attrname, sizeof(attrname), "user.var_%d", i);
			snprintf(value, sizeof(value), "orig-value-%d", i);

			ret = fsetxattr(fd, attrname, value, strlen(value), XATTR_CREATE);
			if (ret < 0) {
				if (errno == ENOTSUP) {
					pr_inf(stderr, "%s stressor will be "
						"skipped, filesystem does not "
						"support xattr.\n", name);
				}
				if (errno == ENOSPC || errno == EDQUOT)
					break;
				pr_fail_err(name, "fsetxattr");
				goto out_close;
			}
		}
		for (j = 0; j < i; j++) {
			snprintf(attrname, sizeof(attrname), "user.var_%d", j);
			snprintf(value, sizeof(value), "value-%d", j);

			ret = fsetxattr(fd, attrname, value, strlen(value),
				XATTR_REPLACE);
			if (ret < 0) {
				if (errno == ENOSPC || errno == EDQUOT)
					break;
				pr_fail_err(name, "fsetxattr");
				goto out_close;
			}
		}
		for (j = 0; j < i; j++) {
			char tmp[sizeof(value)];

			snprintf(attrname, sizeof(attrname), "user.var_%d", j);
			snprintf(value, sizeof(value), "value-%d", j);

			ret = fgetxattr(fd, attrname, tmp, sizeof(tmp));
			if (ret < 0) {
				pr_fail_err(name, "fgetxattr");
				goto out_close;
			}
			if (strncmp(value, tmp, ret)) {
				pr_fail(stderr, "%s: fgetxattr values "
					"different %.*s vs %.*s\n",
					name, ret, value, ret, tmp);
				goto out_close;
			}
		}
		/* Determine how large a buffer we required... */
		sz = flistxattr(fd, NULL, 0);
		if (sz < 0) {
			pr_fail_err(name, "flistxattr");
			goto out_close;
		}
		buffer = malloc(sz);
		if (buffer) {
			/* ...and fetch */
			sz = flistxattr(fd, buffer, sz);
			free(buffer);

			if (sz < 0) {
				pr_fail_err(name, "flistxattr");
				goto out_close;
			}
		}
		for (j = 0; j < i; j++) {
			snprintf(attrname, sizeof(attrname), "user.var_%d", j);
			
			ret = fremovexattr(fd, attrname);
			if (ret < 0) {
				pr_fail_err(name, "fremovexattr");
				goto out_close;
			}
		}
		(*counter)++;
	} while (opt_do_run && (!max_ops || *counter < max_ops));

	rc = EXIT_SUCCESS;
out_close:
	(void)close(fd);
out:
	(void)stress_temp_dir_rm(name, pid, instance);
	return rc;
}
Пример #25
0
static void file_read_checks(const char *path)
{
	char buf1[16],buf2[8],buf3[32];
	struct iovec vec[3];
	int rc, f, cnt;
	off_t i;

	mlog("+open");
	f = open(path, O_RDONLY);
	if (f < 0)
		return;

	// first look at the file's attributes
	mlog("+fstat");
	rc = fstat(f, &sbuf);
#ifdef CHECK_XATTR
	mlog("+flistxattr");
	flistxattr(f, lbuf, MAXLISTBUF);
	mlog("+fgetxattr");
	fgetxattr(f, "selinux", lbuf, MAXLISTBUF);
#endif
//	readahead(f, NULL

	// Check reading
	mlog("+read");
	cnt = 0;
	while((read(f, buf3, sizeof(buf3)) > 0) && cnt < 1000)
		cnt++;

	// lseek around
	mlog("+lseek");
	if (rc == 0) 
		lseek(f, sbuf.st_size, SEEK_SET);
	lseek(f, 100000, SEEK_SET);
	lseek(f, 0, SEEK_SET);

	// vectored reads
	vec[0].iov_base = (void*)&buf1;
	vec[0].iov_len = sizeof(buf1);
	vec[1].iov_base = (void*)&buf2;
	vec[1].iov_len = sizeof(buf2);
	vec[2].iov_base = (void*)&buf3;
	vec[2].iov_len = sizeof(buf3);
	mlog("+readv");
	cnt = 0;
	while((readv(f, vec, 3) > 0) && cnt < 1000)
		cnt++;

	// check out pread syscall
	i = 0;
	mlog("+pread");
	cnt = 0;
	while ((pread(f, buf1, sizeof(buf1), i) > 0) && cnt < 1000) {
		i += sizeof(buf1)*2;
		cnt++;
	}

	// flock
	mlog("+flock");
	flock(f, LOCK_SH|LOCK_NB);
	flock(f, LOCK_UN);

	// fcntl ?

	// sendfile to localhost:discard
#if defined(__linux__)
	setup_socket();
	if (sfd >= 0) {
		mlog("+sendfile");
		lseek(f, 0, SEEK_SET);
		sendfile(sfd, f, NULL, rc ? 100000 : sbuf.st_size);
		close(sfd);
		sfd = -1;
	}
#endif

	// mmap each file
	if (rc == 0) {
		char *src;
		mlog("+mmap");
		src = mmap(0, sbuf.st_size, PROT_READ, MAP_FILE | MAP_SHARED,
			f, 0);
		if (src != (char *)-1) {
			// Don't touch memory...or Mr. SIGBUS will visit you
			mlog("+munmap");
			munmap(src, sbuf.st_size);
		}
	}

	close(f);
}