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;
>