On Sun, Mar 22, 2020 at 11:41:55AM +0100, Marc Espie wrote: > 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 >
Why not use errno on line 106 of file_subs.c ? That would yield "Permission denied" on obstack.h and would avoid having 2 error messages. > 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; >