diff options
author | Timo Teräs <timo.teras@iki.fi> | 2021-07-26 21:08:09 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2021-07-26 21:08:09 +0300 |
commit | 2d4e88aeb1690220ce57420e8d1d9de327ae901d (patch) | |
tree | e2340a8fa80745221265d820ef21379d7f972667 /src | |
parent | ca1d975e5eae662cfde085338e2e29f8e6fcf64b (diff) | |
download | apk-tools-2d4e88aeb1690220ce57420e8d1d9de327ae901d.tar.gz apk-tools-2d4e88aeb1690220ce57420e8d1d9de327ae901d.tar.bz2 apk-tools-2d4e88aeb1690220ce57420e8d1d9de327ae901d.tar.xz apk-tools-2d4e88aeb1690220ce57420e8d1d9de327ae901d.zip |
extract: fix handling of error of regular file extraction
fix the error checking, allow --force-overwrite to work and
do not delete existing file in case of error
Diffstat (limited to 'src')
-rw-r--r-- | src/app_extract.c | 3 | ||||
-rw-r--r-- | src/io_archive.c | 16 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/app_extract.c b/src/app_extract.c index 662fb81..89f3f5c 100644 --- a/src/app_extract.c +++ b/src/app_extract.c @@ -215,6 +215,7 @@ static int apk_extract_file(struct extract_ctx *ctx, off_t sz, struct apk_istrea r = apk_archive_entry_extract( ctx->root_fd, &fi, 0, 0, is, 0, 0, &dctx, ctx->extract_flags, out); + if (r < 0) return r; } apk_digest_ctx_final(&dctx, &d); apk_digest_ctx_free(&dctx); @@ -344,7 +345,7 @@ static int extract_main(void *pctx, struct apk_ctx *ac, struct apk_string_array int r = 0; ctx->ac = ac; - ctx->extract_flags |= APK_EXTRACTF_NO_OVERWRITE; + if (!(ac->force & APK_FORCE_OVERWRITE)) ctx->extract_flags |= APK_EXTRACTF_NO_OVERWRITE; if (!ctx->destination) ctx->destination = "."; ctx->root_fd = openat(AT_FDCWD, ctx->destination, O_RDONLY); if (ctx->root_fd < 0) { diff --git a/src/io_archive.c b/src/io_archive.c index bfa8efa..85f095b 100644 --- a/src/io_archive.c +++ b/src/io_archive.c @@ -355,10 +355,22 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae, case S_IFREG: if (ae->link_target == NULL) { int flags = O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC | O_EXCL; - struct apk_ostream *os = apk_ostream_to_fd(openat(atfd, fn, flags, ae->mode & 07777)); + int fd = openat(atfd, fn, flags, ae->mode & 07777); + if (fd < 0) { + ret = -errno; + break; + } + struct apk_ostream *os = apk_ostream_to_fd(fd); + if (IS_ERR(os)) { + ret = PTR_ERR(os); + break; + } apk_stream_copy(is, os, ae->size, cb, cb_ctx, dctx); r = apk_ostream_close(os); - if (r < 0) ret = r; + if (r < 0) { + unlinkat(atfd, fn, 0); + ret = r; + } } else { r = linkat(atfd, link_target ?: ae->link_target, atfd, fn, 0); if (r < 0) ret = -errno; |