diff options
author | kientzle <kientzle@FreeBSD.org> | 2005-09-24 21:19:57 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2005-09-24 21:19:57 +0000 |
commit | 4168ea6d084dfb6a943ad04d8c88cce7da23d146 (patch) | |
tree | 8dd5343222c5b0661ea0548816d298391e4b38f8 /usr.bin/tar | |
parent | 163e4801c503d3e63e54f04a71cc7e7a0989ca40 (diff) | |
download | FreeBSD-src-4168ea6d084dfb6a943ad04d8c88cce7da23d146.zip FreeBSD-src-4168ea6d084dfb6a943ad04d8c88cce7da23d146.tar.gz |
Fix -u with absolute paths (e.g., "tar -uf foo.tar /bar") by handling
pathname edits before comparing pathnames on disk to those in the archive.
Thanks to: Gareth Bailey, Lowell Gilbert
Diffstat (limited to 'usr.bin/tar')
-rw-r--r-- | usr.bin/tar/write.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/usr.bin/tar/write.c b/usr.bin/tar/write.c index 3974327..6a78df5 100644 --- a/usr.bin/tar/write.c +++ b/usr.bin/tar/write.c @@ -643,15 +643,12 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) tree_descend(tree); /* - * In -u mode, we need to check whether this - * is newer than what's already in the archive. - * In all modes, we need to obey --newerXXX flags. + * Write the entry. Note that write_entry() handles + * pathname editing and newness testing. */ - if (new_enough(bsdtar, name, lst)) { - write_entry(bsdtar, a, lst, name, - tree_current_pathlen(tree), - tree_current_access_path(tree)); - } + write_entry(bsdtar, a, lst, name, + tree_current_pathlen(tree), + tree_current_access_path(tree)); } tree_close(tree); } @@ -686,6 +683,13 @@ write_entry(struct bsdtar *bsdtar, struct archive *a, const struct stat *st, if (edit_pathname(bsdtar, entry)) goto abort; + /* + * In -u mode, check that the file is newer than what's + * already in the archive; in all modes, obey --newerXXX flags. + */ + if (!new_enough(bsdtar, archive_entry_pathname(entry), st)) + goto abort; + if (!S_ISDIR(st->st_mode) && (st->st_nlink > 1)) lookup_hardlink(bsdtar, entry, st); @@ -1235,10 +1239,6 @@ new_enough(struct bsdtar *bsdtar, const char *path, const struct stat *st) */ if (bsdtar->archive_dir != NULL && bsdtar->archive_dir->head != NULL) { - /* Ignore leading './' when comparing names. */ - if (path[0] == '.' && path[1] == '/' && path[2] != '\0') - path += 2; - for (p = bsdtar->archive_dir->head; p != NULL; p = p->next) { if (strcmp(path, p->name)==0) return (p->mtime_sec < st->st_mtime || |