Esempio n. 1
0
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
{
	return lgetxattr(path, name, value, size);
}
Esempio n. 2
0
int
run_attr_tests(char *testfile)
{
    int ret = -1;
    char *res = NULL;
    struct stat buf;
    struct statfs sbuf;
    struct statvfs svbuf;

    assert(testfile);

    fprintf(stdout, "Testing chmod");
    ret = chmod(testfile, 0);
    check_err(ret, "chmod", 2);

    fprintf(stdout, "Testing chown");
    ret = chown(testfile, 0, 0);
    check_err(ret, "chown", 2);

    fprintf(stdout, "Testing link");
    ret = link(testfile, testfile);
    check_err(ret, "link", 2);

    fprintf(stdout, "Testing rename");
    ret = rename(testfile, testfile);
    check_err(ret, "rename", 2);

    fprintf(stdout, "Testing utimes");
    ret = utimes(testfile, NULL);
    check_err(ret, "utimes", 2);

    fprintf(stdout, "Testing utime");
    ret = utime(testfile, NULL);
    check_err(ret, "utime", 2);

    fprintf(stdout, "Testing unlink");
    ret = unlink(testfile);
    check_err(ret, "unlink", 2);

    fprintf(stdout, "Testing symlink");
    ret = symlink(testfile, testfile);
    check_err(ret, "symlink", 2);

    fprintf(stdout, "Testing readlink");
    ret = readlink(testfile, testfile, 0);
    check_err(ret, "readlink", 2);

    fprintf(stdout, "Testing realpath");
    ret = 0;
    res = realpath((const char *)testfile, testfile);
    if (!res)
        ret = -1;
    check_err(ret, "realpath", 2);

    fprintf(stdout, "Testing stat");
    ret = stat(testfile, &buf);
    check_err(ret, "stat", 1);

    fprintf(stdout, "Testing lstat");
    ret = lstat(testfile, &buf);
    check_err(ret, "lstat", 1);

    fprintf(stdout, "Testing statfs");
    ret = statfs(testfile, &sbuf);
    check_err(ret, "statfs", 2);

    fprintf(stdout, "Testing statvfs");
    ret = statvfs(testfile, &svbuf);
    check_err(ret, "statvfs", 1);

    fprintf(stdout, "Testing getxattr");
    ret = getxattr(testfile, NULL, NULL, 0);
    check_err(ret, "getxattr", 2);

    fprintf(stdout, "Testing lgetxattr");
    ret = lgetxattr(testfile, NULL, NULL, 0);
    check_err(ret, "lgetxattr", 1);

    fprintf(stdout, "Testing lchown");
    ret = lchown(testfile, 0, 0);
    check_err(ret, "lchown", 2);
    return 0;
}
Esempio n. 3
0
static void write_xattr_entry(struct filesystem_entry *e)
{
	struct jffs2_raw_xref ref;
	struct xattr_entry *xe;
	char xlist[XATTR_BUFFER_SIZE], xvalue[XATTR_BUFFER_SIZE];
	char *xname, *prefix_str;
	int i, xprefix, prefix_len;
	int list_sz, offset, name_len, value_len;

	if (!enable_xattr)
		return;

	list_sz = llistxattr(e->hostname, xlist, XATTR_BUFFER_SIZE);
	if (list_sz < 0) {
		if (verbose)
			printf("llistxattr('%s') = %d : %s\n",
			       e->hostname, errno, strerror(errno));
		return;
	}

	for (offset = 0; offset < list_sz; offset += name_len) {
		xname = xlist + offset;
		name_len = strlen(xname) + 1;

		for (i = 0; (xprefix = xprefix_tbl[i].xprefix); i++) {
			prefix_str = xprefix_tbl[i].string;
			prefix_len = xprefix_tbl[i].length;
			if (prefix_str[prefix_len - 1] == '.') {
				if (!strncmp(xname, prefix_str, prefix_len - 1))
					break;
			} else {
				if (!strcmp(xname, prefix_str))
					break;
			}
		}
		if (!xprefix) {
			if (verbose)
				printf("%s: xattr '%s' is not supported.\n",
				       e->hostname, xname);
			continue;
		}
		if ((enable_xattr & (1 << xprefix)) == 0)
			continue;

		value_len = lgetxattr(e->hostname, xname, xvalue, XATTR_BUFFER_SIZE);
		if (value_len < 0) {
			if (verbose)
				printf("lgetxattr('%s', '%s') = %d : %s\n",
				       e->hostname, xname, errno, strerror(errno));
			continue;
		}
		xe = find_xattr_entry(xprefix, xname + prefix_len, xvalue, value_len);
		if (!xe) {
			if (verbose)
				printf("%s : xattr '%s' was ignored.\n",
				       e->hostname, xname);
			continue;
		}

		memset(&ref, 0, sizeof(ref));
		ref.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
		ref.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
		ref.totlen = cpu_to_je32(sizeof(ref));
		ref.hdr_crc = cpu_to_je32(crc32(0, &ref, sizeof(struct jffs2_unknown_node) - 4));
		ref.ino = cpu_to_je32(e->sb.st_ino);
		ref.xid = cpu_to_je32(xe->xid);
		ref.xseqno = cpu_to_je32(highest_xseqno += 2);
		ref.node_crc = cpu_to_je32(crc32(0, &ref, sizeof(ref) - 4));

		pad_block_if_less_than(sizeof(ref));
		full_write(out_fd, &ref, sizeof(ref));
		padword();
	}
}
static int
setup_xattr(struct archive_read_disk *a,
    struct archive_entry *entry, const char *name, int fd)
{
	ssize_t size;
	void *value = NULL;
	const char *accpath;

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

#if HAVE_FGETXATTR
	if (fd >= 0)
		size = fgetxattr(fd, name, NULL, 0);
	else if (!a->follow_symlinks)
		size = lgetxattr(accpath, name, NULL, 0);
	else
		size = getxattr(accpath, name, NULL, 0);
#elif HAVE_FGETEA
	if (fd >= 0)
		size = fgetea(fd, name, NULL, 0);
	else if (!a->follow_symlinks)
		size = lgetea(accpath, name, NULL, 0);
	else
		size = getea(accpath, name, NULL, 0);
#endif

	if (size == -1) {
		archive_set_error(&a->archive, errno,
		    "Couldn't query extended attribute");
		return (ARCHIVE_WARN);
	}

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

#if HAVE_FGETXATTR
	if (fd >= 0)
		size = fgetxattr(fd, name, value, size);
	else if (!a->follow_symlinks)
		size = lgetxattr(accpath, name, value, size);
	else
		size = getxattr(accpath, name, value, size);
#elif HAVE_FGETEA
	if (fd >= 0)
		size = fgetea(fd, name, value, size);
	else if (!a->follow_symlinks)
		size = lgetea(accpath, name, value, size);
	else
		size = getea(accpath, name, value, size);
#endif

	if (size == -1) {
		archive_set_error(&a->archive, errno,
		    "Couldn't read extended attribute");
		return (ARCHIVE_WARN);
	}

	archive_entry_xattr_add_entry(entry, name, value, size);

	free(value);
	return (ARCHIVE_OK);
}
Esempio n. 5
0
static int read_xattrs_from_system(char *filename, struct xattr_list **xattrs)
{
	ssize_t size, vsize;
	char *xattr_names, *p;
	int i;
	struct xattr_list *xattr_list = NULL;

#if 0
	while(1) {
		size = llistxattr(filename, NULL, 0);
		if(size <= 0) {
			if(size < 0 && errno != ENOTSUP)
				ERROR("llistxattr for %s failed in read_attrs,"
					" because %s\n", filename,
					strerror(errno));
			return 0;
		}

		xattr_names = malloc(size);
		if(xattr_names == NULL) {
			ERROR("Out of memory in read_attrs\n");
			return 0;
		}

		size = llistxattr(filename, xattr_names, size);
		if(size < 0) {
			free(xattr_names);
			if(errno == ERANGE)
				/* xattr list grew?  Try again */
				continue;
			else {
				ERROR("llistxattr for %s failed in read_attrs,"
					" because %s\n", filename,
					strerror(errno));
				return 0;
			}
		}

		break;
	}
#else
		ERROR("llistxattr not available");
#endif

	for(i = 0, p = xattr_names; p < xattr_names + size; i++) {
		struct xattr_list *x = realloc(xattr_list, (i + 1) *
						sizeof(struct xattr_list));
		if(x == NULL) {
			ERROR("Out of memory in read_attrs\n");
			goto failed;
		} else
			xattr_list = x;

		xattr_list[i].type = get_prefix(&xattr_list[i], p);
		p += strlen(p) + 1;
		if(xattr_list[i].type == -1) {
			ERROR("Unrecognised xattr prefix %s\n",
				xattr_list[i].full_name);
			free(xattr_list[i].full_name);
			i--;
			continue;
		}

#if 0
		while(1) {
			vsize = lgetxattr(filename, xattr_list[i].full_name,
								NULL, 0);
			if(vsize < 0) {
				ERROR("lgetxattr failed for %s in read_attrs,"
					" because %s\n", filename,
					strerror(errno));
				free(xattr_list[i].full_name);
				goto failed;
			}

			xattr_list[i].value = malloc(vsize);
			if(xattr_list[i].value == NULL) {
				ERROR("Out of memory in read_attrs\n");
				free(xattr_list[i].full_name);
				goto failed;
			}

			vsize = lgetxattr(filename, xattr_list[i].full_name,
						xattr_list[i].value, vsize);
			if(vsize < 0) {
				free(xattr_list[i].value);
				if(errno == ERANGE)
					/* xattr grew?  Try again */
					continue;
				else {
					ERROR("lgetxattr failed for %s in "
						"read_attrs, because %s\n",
						filename, strerror(errno));
					free(xattr_list[i].full_name);
					goto failed;
				}
			}
			
			break;
		}
#else
		ERROR("lgetxattr not supported");
#endif
		xattr_list[i].vsize = vsize;

		TRACE("read_xattrs_from_system: filename %s, xattr name %s,"
			" vsize %d\n", filename, xattr_list[i].full_name,
			xattr_list[i].vsize);
	}
	free(xattr_names);
	*xattrs = xattr_list;
	return i;

failed:
	while(--i >= 0) {
		free(xattr_list[i].full_name);
		free(xattr_list[i].value);
	}
	free(xattr_list);
	free(xattr_names);
	return 0;
}
Esempio n. 6
0
/* copy all extended attributes from op->operand to dest_path */
void DCOPY_copy_xattrs(
    mfu_flist flist,
    uint64_t idx,
    const char* dest_path)
{
#if DCOPY_USE_XATTRS
    /* get source file name */
    const char* src_path = mfu_flist_file_get_name(flist, idx);

    /* start with a reasonable buffer, we'll allocate more as needed */
    size_t list_bufsize = 1204;
    char* list = (char*) MFU_MALLOC(list_bufsize);

    /* get list, if list_size == ERANGE, try again */
    ssize_t list_size;
    int got_list = 0;

    /* get current estimate for list size */
    while(! got_list) {
        list_size = llistxattr(src_path, list, list_bufsize);

        if(list_size < 0) {
            if(errno == ERANGE) {
                /* buffer is too small, free our current buffer
                 * and call it again with size==0 to get new size */
                mfu_free(&list);
                list_bufsize = 0;
            }
            else if(errno == ENOTSUP) {
                /* this is common enough that we silently ignore it */
                break;
            }
            else {
                /* this is a real error */
                MFU_LOG(MFU_LOG_ERR, "Failed to get list of extended attributes on %s llistxattr() errno=%d %s",
                    src_path, errno, strerror(errno)
                   );
                break;
            }
        }
        else {
            if(list_size > 0 && list_bufsize == 0) {
                /* called llistxattr with size==0 and got back positive
                 * number indicating size of buffer we need to allocate */
                list_bufsize = (size_t) list_size;
                list = (char*) MFU_MALLOC(list_bufsize);
            }
            else {
                /* got our list, it's size is in list_size, which may be 0 */
                got_list = 1;
            }
        }
    }

    /* iterate over list and copy values to new object lgetxattr/lsetxattr */
    if(got_list) {
        char* name = list;

        while(name < list + list_size) {
            /* start with a reasonable buffer,
             * allocate something bigger as needed */
            size_t val_bufsize = 1024;
            void* val = (void*) MFU_MALLOC(val_bufsize);

            /* lookup value for name */
            ssize_t val_size;
            int got_val = 0;

            while(! got_val) {
                val_size = lgetxattr(src_path, name, val, val_bufsize);

                if(val_size < 0) {
                    if(errno == ERANGE) {
                        /* buffer is too small, free our current buffer
                         * and call it again with size==0 to get new size */
                        mfu_free(&val);
                        val_bufsize = 0;
                    }
                    else if(errno == ENOATTR) {
                        /* source object no longer has this attribute,
                         * maybe deleted out from under us */
                        break;
                    }
                    else {
                        /* this is a real error */
                        MFU_LOG(MFU_LOG_ERR, "Failed to get value for name=%s on %s llistxattr() errno=%d %s",
                            name, src_path, errno, strerror(errno)
                           );
                        break;
                    }
                }
                else {
                    if(val_size > 0 && val_bufsize == 0) {
                        /* called lgetxattr with size==0 and got back positive
                         * number indicating size of buffer we need to allocate */
                        val_bufsize = (size_t) val_size;
                        val = (void*) MFU_MALLOC(val_bufsize);
                    }
                    else {
                        /* got our value, it's size is in val_size, which may be 0 */
                        got_val = 1;
                    }
                }
            }

            /* set attribute on destination object */
            if(got_val) {
                int setrc = lsetxattr(dest_path, name, val, (size_t) val_size, 0);

                if(setrc != 0) {
                    MFU_LOG(MFU_LOG_ERR, "Failed to set value for name=%s on %s llistxattr() errno=%d %s",
                        name, dest_path, errno, strerror(errno)
                       );
                }
            }

            /* free value string */
            mfu_free(&val);
            val_bufsize = 0;

            /* jump to next name */
            size_t namelen = strlen(name) + 1;
            name += namelen;
        }
    }

    /* free space allocated for list */
    mfu_free(&list);
    list_bufsize = 0;

    return;
#endif /* DCOPY_USE_XATTR */
}