diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-11-06 11:31:03 +0200 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-11-06 11:31:03 +0200 |
commit | a93a35eecaf580d97f6a451d7e951be0ff18372c (patch) | |
tree | cec5984f85821ad8aff5cfe317e98c0e5f4ab36e /src/archive.c | |
parent | 44ac0b06af20bd32010502a10d8bb7752215c627 (diff) | |
download | apk-tools-a93a35eecaf580d97f6a451d7e951be0ff18372c.tar.gz apk-tools-a93a35eecaf580d97f6a451d7e951be0ff18372c.tar.bz2 apk-tools-a93a35eecaf580d97f6a451d7e951be0ff18372c.tar.xz apk-tools-a93a35eecaf580d97f6a451d7e951be0ff18372c.zip |
apk: add --never-overwrite flag (ref #197)
to never ever overwrite a while in the filesystem the user knows
about. it gives the impression of extraction succeeding even though
nothing was done. this is inteded to be used only for bootstrapping
with overlay.
Diffstat (limited to 'src/archive.c')
-rw-r--r-- | src/archive.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/archive.c b/src/archive.c index 58d2573..0ba17c5 100644 --- a/src/archive.c +++ b/src/archive.c @@ -339,7 +339,17 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae, fn = alloca(PATH_MAX); snprintf(fn, PATH_MAX, "%s%s", ae->name, suffix); } - unlinkat(atfd, fn, 0); + + if ((!S_ISDIR(ae->mode) && !S_ISREG(ae->mode)) || + (ae->link_target != NULL)) { + /* non-standard entries need to be deleted first */ + if (apk_flags & APK_NEVER_OVERWRITE) { + if (faccessat(atfd, fn, F_OK, AT_SYMLINK_NOFOLLOW) == 0) + return 0; + } else { + unlinkat(atfd, fn, 0); + } + } switch (ae->mode & S_IFMT) { case S_IFDIR: @@ -349,8 +359,16 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae, break; case S_IFREG: if (ae->link_target == NULL) { - fd = openat(atfd, fn, O_RDWR | O_CREAT, ae->mode & 07777); + int flags = O_RDWR | O_CREAT | O_TRUNC; + + if (apk_flags & APK_NEVER_OVERWRITE) + flags |= O_EXCL; + + fd = openat(atfd, fn, flags, ae->mode & 07777); if (fd < 0) { + if ((apk_flags & APK_NEVER_OVERWRITE) && + (errno == EEXIST)) + return 0; r = -1; break; } |