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;

Reply via email to