summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2021-11-15 15:54:17 +0200
committerTimo Teräs <timo.teras@iki.fi>2021-11-15 15:55:15 +0200
commit061bd69b8040d978f22212db5f615f9ce608b678 (patch)
tree6e693b8c749d658ba7f8aaf73ccb57efff0b7427
parentde281f0f8379f1a22306ceb44c54b97a04254c1e (diff)
downloadapk-tools-061bd69b8040d978f22212db5f615f9ce608b678.tar.gz
apk-tools-061bd69b8040d978f22212db5f615f9ce608b678.tar.bz2
apk-tools-061bd69b8040d978f22212db5f615f9ce608b678.tar.xz
apk-tools-061bd69b8040d978f22212db5f615f9ce608b678.zip
fs_fsys: fix extraction of symlinks
Symlinks should use the real target filename instead of the temporary extraction name.
-rw-r--r--src/fs_fsys.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/src/fs_fsys.c b/src/fs_fsys.c
index 0993607..3518f79 100644
--- a/src/fs_fsys.c
+++ b/src/fs_fsys.c
@@ -102,11 +102,9 @@ static int fsys_file_extract(struct apk_ctx *ac, const struct apk_file_info *fi,
int atfd = apk_ctx_fd_dest(ac);
const char *fn = fi->name, *link_target = fi->link_target;
- if (pkgctx.ptr) {
- fn = format_tmpname(&ac->dctx, pkgctx, get_dirname(fn), APK_BLOB_STR(fn), tmpname_file);
- if (link_target)
- link_target = format_tmpname(&ac->dctx, pkgctx, get_dirname(link_target), APK_BLOB_STR(link_target), tmpname_linktarget);
- }
+ if (pkgctx.ptr)
+ fn = format_tmpname(&ac->dctx, pkgctx, get_dirname(fn),
+ APK_BLOB_STR(fn), tmpname_file);
if (!S_ISDIR(fi->mode) && !(extract_flags & APK_FSEXTRACTF_NO_OVERWRITE)) {
if (unlinkat(atfd, fn, 0) != 0 && errno != ENOENT) return -errno;
@@ -119,7 +117,7 @@ static int fsys_file_extract(struct apk_ctx *ac, const struct apk_file_info *fi,
ret = -errno;
break;
case S_IFREG:
- if (fi->link_target == NULL) {
+ if (!link_target) {
int flags = O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC | O_EXCL;
int fd = openat(atfd, fn, flags, fi->mode & 07777);
if (fd < 0) {
@@ -138,6 +136,10 @@ static int fsys_file_extract(struct apk_ctx *ac, const struct apk_file_info *fi,
ret = r;
}
} else {
+ // Hardlink needs to be done against the temporary name
+ if (pkgctx.ptr)
+ link_target = format_tmpname(&ac->dctx, pkgctx, get_dirname(link_target),
+ APK_BLOB_STR(link_target), tmpname_linktarget);
r = linkat(atfd, link_target, atfd, fn, 0);
if (r < 0) ret = -errno;
}