parent
255fd81d79
commit
be8e133c0b
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
5
src/io.c
5
src/io.c
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue