示例#1
0
文件: xattr.c 项目: anlaneg/ceph
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);
}
示例#2
0
static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
{
	ssize_t list_size;
	int i, len;

    switch(type) {
#if defined(HAVE_EXTATTR_LIST_FILE)
    case 0:
        list_size = extattr_list_file(arg.path, EXTATTR_NAMESPACE_USER, list, size);
        break;
#endif
#if defined(HAVE_EXTATTR_LIST_LINK)
    case 1:
        list_size = extattr_list_link(arg.path, EXTATTR_NAMESPACE_USER, list, size);
        break;
#endif
#if defined(HAVE_EXTATTR_LIST_FD)
    case 2:
        list_size = extattr_list_fd(arg.filedes, EXTATTR_NAMESPACE_USER, list, size);
        break;
#endif
    default:
        errno = ENOSYS;
        return -1;
    }

    /* Some error happend. Errno should be set by the previous call */
    if(list_size < 0)
        return -1;

    /* No attributes */
    if(list_size == 0)
        return 0;

    /* XXX: Call with an empty buffer may be used to calculate
       necessary buffer size. Unfortunately, we can't say, how
       many attributes were returned, so here is the potential
       problem with the emulation.
    */
    if(list == NULL)
        return list_size;

    /* Buffer is too small to fit the results */
    if(list_size > size) {
        errno = ERANGE;
        return -1;
    }

    /* Convert from pascal strings to C strings */
    len = list[0];
    memmove(list, list + 1, list_size);

    for(i = len; i < list_size; ) {
        len = list[i];
        list[i] = '\0';
        i += len + 1;
    }

	return list_size;
}
示例#3
0
文件: lib_build.c 项目: xattr/xattr
static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options)
{
    ssize_t rv = 0;

    if (!(options == 0 ||
          options == XATTR_XATTR_NOFOLLOW)) {
        return -1;
    }

    if (options & XATTR_XATTR_NOFOLLOW) {
        return -1;
    }
    else {
        rv = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, namebuf, size);
    }

    if (rv > 0 && namebuf) {
        convert_bsd_list(namebuf, rv);
    }

    return rv;
}
示例#4
0
文件: xattr.c 项目: rchicoli/samba
static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
{
	ssize_t list_size, total_size = 0;
	int i, t, len;
	char *buf;
	/* Iterate through extattr(2) namespaces */
	for(t = 0; t < ARRAY_SIZE(extattr); t++) {
		if (t != EXTATTR_NAMESPACE_USER && geteuid() != 0) {
			/* ignore all but user namespace when we are not root, see bug 10247 */
			continue;
		}
		switch(type) {
#if defined(HAVE_EXTATTR_LIST_FILE)
			case 0:
				list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
				break;
#endif
#if defined(HAVE_EXTATTR_LIST_LINK)
			case 1:
				list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
				break;
#endif
#if defined(HAVE_EXTATTR_LIST_FD)
			case 2:
				list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
				break;
#endif
			default:
				errno = ENOSYS;
				return -1;
		}
		/* Some error happend. Errno should be set by the previous call */
		if(list_size < 0)
			return -1;
		/* No attributes */
		if(list_size == 0)
			continue;
		/* XXX: Call with an empty buffer may be used to calculate
		   necessary buffer size. Unfortunately, we can't say, how
		   many attributes were returned, so here is the potential
		   problem with the emulation.
		*/
		if(list == NULL) {
			/* Take the worse case of one char attribute names - 
			   two bytes per name plus one more for sanity.
			*/
			total_size += list_size + (list_size/2 + 1)*extattr[t].len;
			continue;
		}
		/* Count necessary offset to fit namespace prefixes */
		len = 0;
		for(i = 0; i < list_size; i += list[i] + 1)
			len += extattr[t].len;

		total_size += list_size + len;
		/* Buffer is too small to fit the results */
		if(total_size > size) {
			errno = ERANGE;
			return -1;
		}
		/* Shift results back, so we can prepend prefixes */
		buf = (char *)memmove(list + len, list, list_size);

		for(i = 0; i < list_size; i += len + 1) {
			len = buf[i];
			strncpy(list, extattr[t].name, extattr[t].len + 1);
			list += extattr[t].len;
			strncpy(list, buf + i + 1, len);
			list[len] = '\0';
			list += len + 1;
		}
		size -= total_size;
	}
	return total_size;
}