예제 #1
0
struct archive_entry *
archive_entry_clone(struct archive_entry *entry)
{
	struct archive_entry *entry2;
	struct ae_xattr *xp;
	struct ae_sparse *sp;
	size_t s;
	const void *p;

	/* Allocate new structure and copy over all of the fields. */
	/* TODO: Should we copy the archive over?  Or require a new archive
	 * as an argument? */
	entry2 = archive_entry_new2(entry->archive);
	if (entry2 == NULL)
		return (NULL);
	entry2->ae_stat = entry->ae_stat;
	entry2->ae_fflags_set = entry->ae_fflags_set;
	entry2->ae_fflags_clear = entry->ae_fflags_clear;

	/* TODO: XXX If clone can have a different archive, what do we do here if
	 * character sets are different? XXX */
	archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
	archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
	archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
	archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname);
	archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
	archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink);
	entry2->ae_set = entry->ae_set;
	archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);

	/* Copy encryption status */
	entry2->encryption = entry->encryption;
	
	/* Copy ACL data over. */
	archive_acl_copy(&entry2->acl, &entry->acl);

	/* Copy Mac OS metadata. */
	p = archive_entry_mac_metadata(entry, &s);
	archive_entry_copy_mac_metadata(entry2, p, s);

	/* Copy xattr data over. */
	xp = entry->xattr_head;
	while (xp != NULL) {
		archive_entry_xattr_add_entry(entry2,
		    xp->name, xp->value, xp->size);
		xp = xp->next;
	}

	/* Copy sparse data over. */
	sp = entry->sparse_head;
	while (sp != NULL) {
		archive_entry_sparse_add_entry(entry2,
		    sp->offset, sp->length);
		sp = sp->next;
	}

	return (entry2);
}
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;

	(void)fd; /* UNUSED */

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

	if (!a->follow_symlinks)
		size = lgetxattr(accpath, name, NULL, 0);
	else
		size = getxattr(accpath, name, NULL, 0);

	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 (!a->follow_symlinks)
		size = lgetxattr(accpath, name, value, size);
	else
		size = getxattr(accpath, name, value, size);

	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);
}
static int
setup_xattr(struct archive_read_disk *a,
    struct archive_entry *entry, const char *name, int fd, const char *accpath)
{
	ssize_t size;
	void *value = NULL;


	if (fd >= 0) {
#if ARCHIVE_XATTR_LINUX
		size = fgetxattr(fd, name, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		size = fgetxattr(fd, name, NULL, 0, 0, 0);
#elif ARCHIVE_XATTR_AIX
		size = fgetea(fd, name, NULL, 0);
#endif
	} else if (!a->follow_symlinks) {
#if ARCHIVE_XATTR_LINUX
		size = lgetxattr(accpath, name, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		size = getxattr(accpath, name, NULL, 0, 0, XATTR_NOFOLLOW);
#elif ARCHIVE_XATTR_AIX
		size = lgetea(accpath, name, NULL, 0);
#endif
	} else {
#if ARCHIVE_XATTR_LINUX
		size = getxattr(accpath, name, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		size = getxattr(accpath, name, NULL, 0, 0, 0);
#elif ARCHIVE_XATTR_AIX
		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 (fd >= 0) {
#if ARCHIVE_XATTR_LINUX
		size = fgetxattr(fd, name, value, size);
#elif ARCHIVE_XATTR_DARWIN
		size = fgetxattr(fd, name, value, size, 0, 0);
#elif ARCHIVE_XATTR_AIX
		size = fgetea(fd, name, value, size);
#endif
	} else if (!a->follow_symlinks) {
#if ARCHIVE_XATTR_LINUX
		size = lgetxattr(accpath, name, value, size);
#elif ARCHIVE_XATTR_DARWIN
		size = getxattr(accpath, name, value, size, 0, XATTR_NOFOLLOW);
#elif ARCHIVE_XATTR_AIX
		size = lgetea(accpath, name, value, size);
#endif
	} else {
#if ARCHIVE_XATTR_LINUX
		size = getxattr(accpath, name, value, size);
#elif ARCHIVE_XATTR_DARWIN
		size = getxattr(accpath, name, value, size, 0, 0);
#elif ARCHIVE_XATTR_AIX
		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);
}