If tar can't create intermediate directories due to permission issues, the resulting message is confusing:
./tar xf gcc.tar gcc-8.3.0/include/obstack.h tar: Unable to create gcc-8.3.0/include/obstack.h: No such file or directory (here I have gcc-8.3.0 owned by root and no permissions) The following patch changes this to: ./tar xf gcc.tar gcc-8.3.0/include/obstack.h tar: Unable to create gcc-8.3.0/include: Permission denied tar: Unable to create gcc-8.3.0/include/obstack.h: No such file or directory okay ? or a better way to do this ? Index: extern.h =================================================================== RCS file: /cvs/src/bin/pax/extern.h,v retrieving revision 1.59 diff -u -p -r1.59 extern.h --- extern.h 13 Sep 2018 12:33:43 -0000 1.59 +++ extern.h 22 Mar 2020 10:39:53 -0000 @@ -128,7 +128,7 @@ int cross_lnk(ARCHD *); int chk_same(ARCHD *); int node_creat(ARCHD *); int unlnk_exist(char *, int); -int chk_path(char *, uid_t, gid_t); +int chk_path(char *, uid_t, gid_t, int); void set_ftime(const char *, const struct timespec *, const struct timespec *, int); void fset_ftime(const char *, int, const struct timespec *, Index: file_subs.c =================================================================== RCS file: /cvs/src/bin/pax/file_subs.c,v retrieving revision 1.54 diff -u -p -r1.54 file_subs.c --- file_subs.c 28 Jun 2019 13:34:59 -0000 1.54 +++ file_subs.c 22 Mar 2020 10:39:53 -0000 @@ -102,7 +102,7 @@ file_creat(ARCHD *arcn) file_mode)) >= 0) break; oerrno = errno; - if (nodirs || chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { + if (nodirs || chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid, 0) < 0) { syswarn(1, oerrno, "Unable to create %s", arcn->name); return(-1); } @@ -316,7 +316,7 @@ mk_link(char *to, struct stat *to_sb, ch if (linkat(AT_FDCWD, to, AT_FDCWD, from, 0) == 0) break; oerrno = errno; - if (!nodirs && chk_path(from, to_sb->st_uid, to_sb->st_gid) == 0) + if (!nodirs && chk_path(from, to_sb->st_uid, to_sb->st_gid, ign) == 0) continue; if (!ign) { syswarn(1, oerrno, "Could not link to %s from %s", to, @@ -458,7 +458,7 @@ badlink: if (++pass <= 1) continue; - if (nodirs || chk_path(nm,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { + if (nodirs || chk_path(nm,arcn->sb.st_uid,arcn->sb.st_gid, 0) < 0) { syswarn(1, oerrno, "Could not create: %s", nm); return(-1); } @@ -590,7 +590,7 @@ unlnk_exist(char *name, int type) */ int -chk_path(char *name, uid_t st_uid, gid_t st_gid) +chk_path(char *name, uid_t st_uid, gid_t st_gid, int ign) { char *spt = name; char *next; @@ -643,6 +643,8 @@ chk_path(char *name, uid_t st_uid, gid_t * needed directory and continue on */ if (mkdir(name, S_IRWXU | S_IRWXG | S_IRWXO) == -1) { + if (!ign) + syswarn(1, errno, "Unable to create %s", name); *spt = '/'; retval = -1; break;