diff --git a/src/list.c b/src/list.c index cf7b41c4..1f441364 100644 --- a/src/list.c +++ b/src/list.c @@ -1437,6 +1437,24 @@ skip_member (void) skim_member (false); } +static bool +member_is_dir (struct tar_stat_info *info, char typeflag) +{ + switch (typeflag) + { + case AREGTYPE: + case REGTYPE: + case CONTTYPE: + return info->had_trailing_slash; + + case DIRTYPE: + return true; + + default: + return false; + } +} + /* Skip the current member in the archive. If MUST_COPY, always copy instead of skipping. */ void @@ -1450,7 +1468,8 @@ skim_member (bool must_copy) if (current_stat_info.is_sparse) sparse_skim_file (¤t_stat_info, must_copy); - else + else if (!member_is_dir (¤t_stat_info, + current_header->header.typeflag)) skim_file (current_stat_info.stat.st_size, must_copy); mv_end (); diff --git a/tests/skipdir.at b/tests/skipdir.at index 79119ddf..0bc38e4f 100644 --- a/tests/skipdir.at +++ b/tests/skipdir.at @@ -42,11 +42,15 @@ base64 -d < archive.in | xz -c -d > archive.tar AT_CHECK([tar tf archive.tar], [0], [owo1/ +owo2/ ]) AT_CHECK([tar vxf archive.tar], [0], [owo1/ +owo2/ ]) AT_CHECK([tar -xvf archive.tar --exclude owo1], -[0]) +[0], +[owo2/ +]) AT_CLEANUP