extract xattrs from packages

ref #3027
cute-signatures
Timo Teräs 2015-03-10 14:38:06 +02:00
parent 255fd81d79
commit be8e133c0b
3 changed files with 46 additions and 0 deletions

View File

@ -27,6 +27,12 @@ struct apk_id_cache {
struct apk_hash gid_cache;
};
struct apk_xattr {
const char *name;
apk_blob_t value;
};
APK_ARRAY(apk_xattr_array, struct apk_xattr);
struct apk_file_info {
char *name;
char *link_target;
@ -39,6 +45,7 @@ struct apk_file_info {
time_t mtime;
dev_t device;
struct apk_checksum csum;
struct apk_xattr_array *xattrs;
};
struct apk_istream {
@ -143,6 +150,7 @@ int apk_blob_to_file(int atfd, const char *file, apk_blob_t b, unsigned int flag
#define APK_FI_NOFOLLOW 0x80000000
int apk_file_get_info(int atfd, const char *filename, unsigned int flags,
struct apk_file_info *fi);
void apk_file_info_free(struct apk_file_info *fi);
typedef int apk_dir_file_cb(void *ctx, int dirfd, const char *entry);
int apk_dir_foreach_file(int dirfd, apk_dir_file_cb cb, void *ctx);

View File

@ -20,6 +20,7 @@
#include <sysexits.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/xattr.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
@ -148,6 +149,12 @@ static void handle_extended_header(struct apk_file_info *fi, apk_blob_t hdr)
fi->name = value.ptr;
} else if (apk_blob_compare(name, APK_BLOB_STR("linkpath")) == 0) {
fi->link_target = value.ptr;
} else if (apk_blob_pull_blob_match(&name, APK_BLOB_STR("SCHILY.xattr."))) {
name.ptr[name.len] = 0;
*apk_xattr_array_add(&fi->xattrs) = (struct apk_xattr) {
.name = name.ptr,
.value = value,
};
} else if (apk_blob_pull_blob_match(&name, APK_BLOB_STR("APK-TOOLS.checksum."))) {
int type = APK_CHECKSUM_NONE;
if (apk_blob_compare(name, APK_BLOB_STR("SHA1")) == 0)
@ -201,10 +208,12 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
.gname = buf.gname,
.device = makedev(GET_OCTAL(buf.devmajor),
GET_OCTAL(buf.devminor)),
.xattrs = entry.xattrs,
};
buf.mode[0] = 0; /* to nul terminate 100-byte buf.name */
buf.magic[0] = 0; /* to nul terminate 100-byte buf.linkname */
teis.csum = NULL;
apk_xattr_array_resize(&entry.xattrs, 0);
if (paxlen) handle_extended_header(&entry, APK_BLOB_PTR_LEN(pax.ptr, paxlen));
@ -305,6 +314,7 @@ err:
EVP_MD_CTX_cleanup(&teis.mdctx);
free(pax.ptr);
free(longname.ptr);
apk_file_info_free(&entry);
return r;
err_nomem:
@ -382,6 +392,7 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
const char *suffix, struct apk_istream *is,
apk_progress_cb cb, void *cb_ctx)
{
struct apk_xattr *xattr;
char *fn = ae->name;
int fd, r = -1, atflags = 0;
@ -454,6 +465,28 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
}
}
/* extract xattrs */
if (ae->xattrs && ae->xattrs->num) {
r = 0;
fd = openat(atfd, fn, O_RDWR);
if (fd >= 0) {
foreach_array_item(xattr, ae->xattrs) {
if (fsetxattr(fd, xattr->name, xattr->value.ptr, xattr->value.len, 0) < 0) {
r = errno;
break;
}
}
close(fd);
} else {
r = errno;
}
if (r < 0) {
apk_error("Failed to set xattrs on %s: %s",
fn, strerror(r));
return -r;
}
}
if (!S_ISLNK(ae->mode)) {
/* preserve modification time */
struct timespec times[2];

View File

@ -586,6 +586,11 @@ int apk_file_get_info(int atfd, const char *filename, unsigned int flags,
return 0;
}
void apk_file_info_free(struct apk_file_info *fi)
{
apk_xattr_array_free(&fi->xattrs);
}
int apk_dir_foreach_file(int dirfd, apk_dir_file_cb cb, void *ctx)
{
struct dirent *de;