ALT Linux repos
S: | 1.35.0.20.1cdad4cc-alt1 |
5.0: | 1.20-alt1 |
4.1: | 1.20-alt1.M41.1 |
4.0: | 1.15.1-alt8 |
3.0: | 1.15.1-alt2 |
+updates: | 1.15.1-alt4.M30.2 |
Group :: Archiving/Backup
RPM: tar
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: tar-1.20-alt1.M41.1.patch
Download
Download
doc/tar.texi | 2 +-
lib/rtapelib.c | 6 +++-
src/create.c | 21 +++++++++--------
src/extract.c | 65 +++++++++++++++++++++++++++++++++++++++---------------
src/list.c | 9 +++++++
src/system.c | 20 ++++++++++++++++-
src/tar.c | 8 +++---
tests/genfile.c | 12 ++++++---
8 files changed, 103 insertions(+), 40 deletions(-)
diff --git a/doc/tar.texi b/doc/tar.texi
index 5898792..f0edf99 100644
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -53,7 +53,7 @@ supports it in developing GNU and promoting software freedom.''
@dircategory Archiving
@direntry
-* Tar: (tar). Making tape (or disk) archives.
+* Tar: (tar). Making tape (or disk) archives.
@end direntry
@dircategory Individual utilities
diff --git a/lib/rtapelib.c b/lib/rtapelib.c
index 51faf3c..b6682b2 100644
--- a/lib/rtapelib.c
+++ b/lib/rtapelib.c
@@ -488,12 +488,14 @@ rmt_open__ (const char *file_name, int open_mode, int bias,
/* Child. */
close (STDIN_FILENO);
- dup (to_remote[remote_pipe_number][PREAD]);
+ if (dup (to_remote[remote_pipe_number][PREAD]) != STDIN_FILENO)
+ error (EXIT_ON_EXEC_ERROR, errno, _("Cannot dup"));
close (to_remote[remote_pipe_number][PREAD]);
close (to_remote[remote_pipe_number][PWRITE]);
close (STDOUT_FILENO);
- dup (from_remote[remote_pipe_number][PWRITE]);
+ if (dup (from_remote[remote_pipe_number][PWRITE]) != STDOUT_FILENO)
+ error (EXIT_ON_EXEC_ERROR, errno, _("Cannot dup"));
close (from_remote[remote_pipe_number][PREAD]);
close (from_remote[remote_pipe_number][PWRITE]);
diff --git a/src/create.c b/src/create.c
index 413115c..afdb053 100644
--- a/src/create.c
+++ b/src/create.c
@@ -1548,6 +1548,17 @@ dump_file0 (struct tar_stat_info *st, const char *p,
if (is_avoided_name (p))
return;
+ if (S_ISSOCK (st->stat.st_mode))
+ {
+ WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p)));
+ return;
+ }
+ else if (S_ISDOOR (st->stat.st_mode))
+ {
+ WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p)));
+ return;
+ }
+
is_dir = S_ISDIR (st->stat.st_mode) != 0;
if (!is_dir && dump_hard_link (st))
@@ -1734,16 +1745,6 @@ dump_file0 (struct tar_stat_info *st, const char *p,
type = BLKTYPE;
else if (S_ISFIFO (st->stat.st_mode))
type = FIFOTYPE;
- else if (S_ISSOCK (st->stat.st_mode))
- {
- WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p)));
- return;
- }
- else if (S_ISDOOR (st->stat.st_mode))
- {
- WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p)));
- return;
- }
else
{
unknown_file_error (p);
diff --git a/src/extract.c b/src/extract.c
index 0d938e6..9e0daa6 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -130,6 +130,33 @@ extr_init (void)
}
}
+static int
+fstat_or_stat (int fd, const char *name, struct stat *st)
+{
+ if (fd != -1)
+ return fstat (fd, st);
+ else
+ return stat (name, st);
+}
+
+static int
+fchown_or_chown (int fd, const char *name, uid_t uid, uid_t gid)
+{
+ if (fd != -1)
+ return fchown (fd, uid, gid);
+ else
+ return chown (name, uid, gid);
+}
+
+static int
+fchmod_or_chmod (int fd, const char *name, mode_t mode)
+{
+ if (fd != -1)
+ return fchmod (fd, mode);
+ else
+ return chmod(name, mode);
+}
+
/* If restoring permissions, restore the mode for FILE_NAME from
information given in *STAT_INFO (where *CUR_INFO gives
the current status if CUR_INFO is nonzero); otherwise invert the
@@ -137,7 +164,7 @@ extr_init (void)
PERMSTATUS specifies the status of the file's permissions.
TYPEFLAG specifies the type of the file. */
static void
-set_mode (char const *file_name,
+set_mode (int fd, char const *file_name,
struct stat const *stat_info,
struct stat const *cur_info,
mode_t invert_permissions, enum permstatus permstatus,
@@ -176,7 +203,7 @@ set_mode (char const *file_name,
struct stat st;
if (! cur_info)
{
- if (stat (file_name, &st) != 0)
+ if (fstat_or_stat (fd, file_name, &st) != 0)
{
stat_error (file_name);
return;
@@ -186,7 +213,7 @@ set_mode (char const *file_name,
mode = cur_info->st_mode ^ invert_permissions;
}
- if (chmod (file_name, mode) != 0)
+ if (fchmod_or_chmod (fd, file_name, mode) != 0)
chmod_error_details (file_name, mode);
}
@@ -233,7 +260,7 @@ check_time (char const *file_name, struct timespec t)
punt for the rest. Sigh! */
static void
-set_stat (char const *file_name,
+set_stat (int fd, char const *file_name,
struct tar_stat_info const *st,
struct stat const *cur_info,
mode_t invert_permissions, enum permstatus permstatus,
@@ -259,7 +286,7 @@ set_stat (char const *file_name,
ts[0] = start_time;
ts[1] = st->mtime;
- if (utimens (file_name, ts) != 0)
+ if (gl_futimens (fd, file_name, ts) != 0)
utime_error (file_name);
else
{
@@ -292,7 +319,8 @@ set_stat (char const *file_name,
}
else
{
- chown_result = chown (file_name, st->stat.st_uid, st->stat.st_gid);
+ chown_result = fchown_or_chown (fd, file_name, st->stat.st_uid,
+ st->stat.st_gid);
}
if (chown_result == 0)
@@ -310,7 +338,7 @@ set_stat (char const *file_name,
}
if (typeflag != SYMTYPE)
- set_mode (file_name, &st->stat, cur_info,
+ set_mode (fd, file_name, &st->stat, cur_info,
invert_permissions, permstatus, typeflag);
}
@@ -599,7 +627,7 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
sb.stat.st_gid = data->gid;
sb.atime = data->atime;
sb.mtime = data->mtime;
- set_stat (data->file_name, &sb, cur_info,
+ set_stat (-1, data->file_name, &sb, cur_info,
data->invert_permissions, data->permstatus, DIRTYPE);
}
@@ -650,7 +678,7 @@ extract_dir (char *file_name, int typeflag)
|| old_files_option == OVERWRITE_OLD_FILES))
{
struct stat st;
- if (stat (file_name, &st) == 0)
+ if (lstat (file_name, &st) == 0)
{
if (interdir_made)
{
@@ -814,6 +842,12 @@ extract_file (char *file_name, int typeflag)
mv_end ();
+ if (!to_stdout_option && !to_command_option)
+ set_stat (fd, file_name, ¤t_stat_info, NULL, invert_permissions,
+ (old_files_option == OVERWRITE_OLD_FILES ?
+ UNKNOWN_PERMSTATUS : ARCHIVED_PERMSTATUS),
+ typeflag);
+
/* If writing to stdout, don't try to do anything to the filename;
it doesn't exist, or we don't want to touch it anyway. */
@@ -826,11 +860,6 @@ extract_file (char *file_name, int typeflag)
if (to_command_option)
sys_wait_command ();
- else
- set_stat (file_name, ¤t_stat_info, NULL, invert_permissions,
- (old_files_option == OVERWRITE_OLD_FILES ?
- UNKNOWN_PERMSTATUS : ARCHIVED_PERMSTATUS),
- typeflag);
return status;
}
@@ -986,7 +1015,7 @@ extract_symlink (char *file_name, int typeflag)
break;
if (status == 0)
- set_stat (file_name, ¤t_stat_info, NULL, 0, 0, SYMTYPE);
+ set_stat (-1, file_name, ¤t_stat_info, NULL, 0, 0, SYMTYPE);
else
symlink_error (current_stat_info.link_name, file_name);
return status;
@@ -1021,7 +1050,7 @@ extract_node (char *file_name, int typeflag)
if (status != 0)
mknod_error (file_name);
else
- set_stat (file_name, ¤t_stat_info, NULL, invert_permissions,
+ set_stat (-1, file_name, ¤t_stat_info, NULL, invert_permissions,
ARCHIVED_PERMSTATUS, typeflag);
return status;
}
@@ -1042,7 +1071,7 @@ extract_fifo (char *file_name, int typeflag)
break;
if (status == 0)
- set_stat (file_name, ¤t_stat_info, NULL, invert_permissions,
+ set_stat (-1, file_name, ¤t_stat_info, NULL, invert_permissions,
ARCHIVED_PERMSTATUS, typeflag);
else
mkfifo_error (file_name);
@@ -1291,7 +1320,7 @@ apply_delayed_links (void)
struct tar_stat_info st1;
st1.stat.st_uid = ds->uid;
st1.stat.st_gid = ds->gid;
- set_stat (source, &st1, NULL, 0, 0, SYMTYPE);
+ set_stat (-1, source, &st1, NULL, 0, 0, SYMTYPE);
valid_source = source;
}
}
diff --git a/src/list.c b/src/list.c
index b17f604..c56d9b7 100644
--- a/src/list.c
+++ b/src/list.c
@@ -136,6 +136,14 @@ read_and (void (*do_something) (void))
if (!ignore_zeros_option)
{
+
+ /*
+ * According to POSIX tar specs, this is wrong, but on the web
+ * there are some tar specs that can trigger this, and some tar
+ * implementations create tars according to that spec. For now,
+ * let's not be pedantic about issuing the warning.
+ */
+#if 0
char buf[UINTMAX_STRSIZE_BOUND];
status = read_header (false);
@@ -143,6 +151,7 @@ read_and (void (*do_something) (void))
break;
WARN ((0, 0, _("A lone zero block at %s"),
STRINGIFY_BIGINT (current_block_ordinal (), buf)));
+#endif
break;
}
status = prev_status;
diff --git a/src/system.c b/src/system.c
index e57e6da..f8ee9f2 100644
--- a/src/system.c
+++ b/src/system.c
@@ -249,7 +249,25 @@ int
sys_truncate (int fd)
{
off_t pos = lseek (fd, (off_t) 0, SEEK_CUR);
- return pos < 0 ? -1 : ftruncate (fd, pos);
+
+ if (pos < 0)
+ return -1;
+
+ if (ftruncate (fd, pos) && errno == EPERM) {
+ /*
+ * ftruncate may fail to grow the size of a file with some OS and
+ * filesystem combinations. Linux and vfat/fat is one example.
+ * If this is the case do a write to grow the file to the desired length.
+ */
+ struct stat st;
+
+ if (fstat (fd, &st) ||
+ st.st_size >= pos ||
+ lseek (fd, pos - 1, SEEK_SET) == (off_t)-1 ||
+ write (fd, "\0", 1) != 1)
+ return -1;
+ }
+ return 0;
}
/* Return nonzero if NAME is the name of a regular file, or if the file
diff --git a/src/tar.c b/src/tar.c
index 4a58a74..b611a8c 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -1336,10 +1336,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'I':
- USAGE_ERROR ((0, 0,
- _("Warning: the -I option is not supported;"
- " perhaps you meant -j or -T?")));
- break;
+ case 'y':
+ WARN ((0, 0, _("Warning: option '%c' is deprecated!"
+ " Next time use -j instead."), key));
+ /* Fall through to using bzip2. */
case 'j':
set_use_compress_program_option ("bzip2");
diff --git a/tests/genfile.c b/tests/genfile.c
index 91cf5b4..991a395 100644
--- a/tests/genfile.c
+++ b/tests/genfile.c
@@ -480,7 +480,8 @@ mkhole (int fd, off_t displ)
{
if (lseek (fd, displ, SEEK_CUR) == -1)
error (EXIT_FAILURE, errno, "lseek");
- ftruncate (fd, lseek (fd, 0, SEEK_CUR));
+ if (ftruncate (fd, lseek (fd, 0, SEEK_CUR)))
+ error (EXIT_FAILURE, errno, "ftruncate");
}
static void
@@ -678,13 +679,15 @@ exec_checkpoint (struct action *p)
error (0, errno, _("cannot open `%s'"), p->name);
break;
}
- ftruncate (fd, p->size);
+ if (ftruncate (fd, p->size))
+ error (0, errno, _("cannot truncate `%s'"), p->name);
close (fd);
}
break;
case OPT_EXEC:
- system (p->name);
+ if (system (p->name) == -1)
+ error (0, errno, _("cannot execute `%s'"), p->name);
break;
default:
@@ -743,7 +746,8 @@ exec_command (void)
signal (SIGCHLD, SIG_DFL);
#endif
- pipe (fd);
+ if (pipe (fd))
+ error (EXIT_FAILURE, errno, "pipe");
pid = fork ();
if (pid == -1)