summaryrefslogtreecommitdiff
path: root/usr/src/cmd/tar/tar.c
diff options
context:
space:
mode:
authormarks <none@none>2006-01-10 08:05:23 -0800
committermarks <none@none>2006-01-10 08:05:23 -0800
commitd2443e765650e70b88cd0346e67d2aee6dd1ea3a (patch)
tree83320edfc41dd74d9884d59a1d18fb22f6275e09 /usr/src/cmd/tar/tar.c
parent9f1fc992b281e57216b036e784b762829b875b4b (diff)
downloadillumos-joyent-d2443e765650e70b88cd0346e67d2aee6dd1ea3a.tar.gz
6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
6355681 cannot remove xattr even while write_attr is granted 6364433 `find -ls` prints extra "+" sign when running over NFSv4/UFS 6366467 Different x_attr behavior while ACL against the same user by 'user:' or 'owner@' 6368111 ZFS returns EACCES in preference to EEXIST
Diffstat (limited to 'usr/src/cmd/tar/tar.c')
-rw-r--r--usr/src/cmd/tar/tar.c104
1 files changed, 76 insertions, 28 deletions
diff --git a/usr/src/cmd/tar/tar.c b/usr/src/cmd/tar/tar.c
index d546fa2b4d..76ca6b5a5d 100644
--- a/usr/src/cmd/tar/tar.c
+++ b/usr/src/cmd/tar/tar.c
@@ -1404,7 +1404,7 @@ top:
xattrp->h_typeflag == '5') {
Hiddendir = 1;
sp->st_mode =
- (S_IFDIR | (sp->st_mode & S_IAMB));
+ (S_IFDIR | (sp->st_mode & POSIXMODES));
}
dblock.dbuf.typeflag = xattrp->h_typeflag;
}
@@ -2461,9 +2461,32 @@ doxtract(char *argv[])
}
#endif
if (dirfd == -1) {
- (void) fprintf(stderr, gettext(
- "tar: cannot open %s %s\n"), dirp,
- strerror(errno));
+#if defined(O_XATTR)
+ if (xattrp) {
+ (void) fprintf(vfile,
+ gettext("tar: cannot open "
+ "attribute %s of file %s: %s\n"),
+ xattraname, dirp, strerror(errno));
+ /*
+ * Reset typeflag back to real
+ * value so passtape will skip
+ * ahead correctly.
+ */
+ dblock.dbuf.typeflag = _XATTR_HDRTYPE;
+ free(xattrhead);
+ xattrp = NULL;
+ xattr_linkp = NULL;
+ xattrhead = NULL;
+ } else {
+ fprintf(vfile,
+ gettext("tar: cannot open %s %s\n"),
+ dirp, strerror(errno));
+ }
+#else
+ fprintf(vfile,
+ gettext("tar: cannot open %s %s\n"),
+ dirp, strerror(errno));
+#endif
passtape();
continue;
}
@@ -6534,7 +6557,6 @@ getstat(int dirfd, char *longname, char *shortname)
else
i = fstatat(dirfd, shortname, &stbuf, 0);
-
if (i < 0) {
/* Initialize flag to print error mesg. */
printerr = 1;
@@ -6881,6 +6903,7 @@ read_xattr_hdr()
} else {
xattr_linkaname = NULL;
}
+
return (0);
}
#else
@@ -6981,6 +7004,8 @@ retry_attrdir_open(char *name)
struct timeval times[2];
mode_t newmode;
struct stat parentstat;
+ acl_t *aclp = NULL;
+ int error;
/*
* We couldn't get to attrdir. See if its
@@ -6988,46 +7013,69 @@ retry_attrdir_open(char *name)
* for example: a mode such as r-xr--r--
* won't let us create an attribute dir
* if it doesn't already exist.
+ *
+ * If file has a non-trivial ACL, then save it
+ * off so that we can place it back on after doing
+ * chmod's.
*/
if (stat(name, &parentstat) == -1) {
- (void) fprintf(stderr, gettext("Cannot stat file %s %s\n"),
+ (void) fprintf(stderr, gettext("tar: cannot stat file %s %s\n"),
name, strerror(errno));
- return (1);
+ return (-1);
}
+ if ((error = acl_get(name, ACL_NO_TRIVIAL, &aclp)) != 0) {
+ (void) fprintf(stderr, gettext("tar: failed to retrieve ACL on"
+ " %s %s\n"), name, strerror(errno));
+ return (-1);
+ }
+
newmode = S_IWUSR | parentstat.st_mode;
if (chmod(name, newmode) == -1) {
(void) fprintf(stderr,
- gettext("Cannot chmod file %s to %o %s\n"),
+ gettext("tar: cannot chmod file %s to %o %s\n"),
name, newmode, strerror(errno));
- return (1);
-
+ if (aclp)
+ acl_free(aclp);
+ return (-1);
}
dirfd = attropen(name, ".", O_RDONLY);
- if (dirfd == -1) {
- (void) fprintf(stderr,
- gettext("Cannot open attribute directory of"
- " file %s %s\n"), name, strerror(errno));
- return (1);
- } else {
- /*
- * Put mode back to original
- */
- (void) chmod(name, parentstat.st_mode);
+ /*
+ * Don't print error message if attropen() failed,
+ * caller will print message.
+ */
- /*
- * Put back time stamps
- */
+ /*
+ * Put mode back to original
+ */
+ if (chmod(name, parentstat.st_mode) == -1) {
+ (void) fprintf(stderr,
+ gettext("tar: cannot chmod file %s to %o %s\n"),
+ name, newmode, strerror(errno));
+ }
- times[0].tv_sec = parentstat.st_atime;
- times[0].tv_usec = 0;
- times[1].tv_sec = parentstat.st_mtime;
- times[1].tv_usec = 0;
- (void) utimes(name, times);
+ if (aclp) {
+ error = acl_set(name, aclp);
+ if (error) {
+ (void) fprintf(stderr,
+ gettext("tar: %s: failed to set acl entries\n"),
+ name);
+ }
+ acl_free(aclp);
}
+ /*
+ * Put back time stamps
+ */
+
+ times[0].tv_sec = parentstat.st_atime;
+ times[0].tv_usec = 0;
+ times[1].tv_sec = parentstat.st_mtime;
+ times[1].tv_usec = 0;
+ (void) utimes(name, times);
+
return (dirfd);
}