(extr_init): If we run out of memory, invoke apply_delayed_set_stat.

(set_mode): Use Use error message functions to report errors consistently.
(set_stat): Likewise.
(repair_delayed_set_stat): Quote file names with colons if possible.
(prepare_to_extract): Don't complain if we can't remove ".".
(extract_sparse_file): Use consistent message for unexpected EOF.
Use error message functions to report errors consistently.
(extract_archive): Use consistent message for unexpected EOF.
Use error message functions to report errors consistently.
Quote file names with colons if possible.
(apply_delayed_set_stat): New function.
(apply_nonancestor_delayed_set_stat): Renamed from apply_delayed_set_stat.
Don't remove head if it doesn't apply.
(fatal_exit): Invoke apply_delayed_set_stat with no args.
This commit is contained in:
Paul Eggert
2000-01-07 19:25:23 +00:00
parent c598438dd2
commit 53f16a5971

View File

@@ -75,6 +75,7 @@ extr_init (void)
we_are_root = geteuid () == 0;
same_permissions_option += we_are_root;
same_owner_option += we_are_root;
xalloc_fail_func = apply_delayed_set_stat;
/* Option -p clears the kernel umask, so it does not affect proper
restoration of file permissions. New intermediate directories will
@@ -137,11 +138,7 @@ set_mode (char *file_name, struct stat *stat_info,
}
if (chmod (file_name, mode) != 0)
{
int e = errno;
ERROR ((0, e, _("%s: Cannot change mode to %04lo"),
quotearg_colon (file_name), (unsigned long) mode));
}
chmod_error_details (file_name, mode);
}
/* Restore stat attributes (owner, group, mode and times) for
@@ -184,12 +181,7 @@ set_stat (char *file_name, struct stat *stat_info,
utimbuf.modtime = stat_info->st_mtime;
if (utime (file_name, &utimbuf) < 0)
{
int e = errno;
ERROR ((0, e,
_("%s: Cannot change access and modification times"),
quotearg_colon (file_name)));
}
utime_error (file_name);
}
/* Some systems allow non-root users to give files away. Once this
@@ -211,25 +203,15 @@ set_stat (char *file_name, struct stat *stat_info,
{
#if HAVE_LCHOWN
if (lchown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
{
int e = errno;
ERROR ((0, e, _("%s: Cannot lchown to uid %lu gid %lu"),
quotearg_colon (file_name),
(unsigned long) stat_info->st_uid,
(unsigned long) stat_info->st_gid));
}
chown_error_details (file_name,
stat_info->st_uid, stat_info->st_gid);
#endif
}
else
{
if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
{
int e = errno;
ERROR ((0, e, _("%s: Cannot chown to uid %lu gid %lu"),
quotearg_colon (file_name),
(unsigned long) stat_info->st_uid,
(unsigned long) stat_info->st_gid));
}
chown_error_details (file_name,
stat_info->st_uid, stat_info->st_gid);
/* On a few systems, and in particular, those allowing to give files
away, changing the owner or group destroys the suid or sgid bits.
@@ -291,8 +273,8 @@ repair_delayed_set_stat (char const *dir_name,
}
}
ERROR ((0, 0, _("Unexpected inconsistency when making directory %s"),
quote (dir_name)));
ERROR ((0, 0, _("%s: Unexpected inconsistency when making directory"),
quotearg_colon (dir_name)));
}
/*-----------------------------------------------------------------------.
@@ -379,7 +361,7 @@ prepare_to_extract (char const *file_name)
if (old_files_option == UNLINK_FIRST_OLD_FILES
&& !remove_any_file (file_name, recursive_unlink_option)
&& errno != ENOENT)
&& errno && errno != ENOENT)
{
unlink_error (file_name);
return 0;
@@ -452,16 +434,12 @@ extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
union block *data_block = find_next_block ();
if (! data_block)
{
ERROR ((0, 0, _("Unexpected EOF on archive file")));
ERROR ((0, 0, _("Unexpected EOF in archive")));
return;
}
if (lseek (fd, sparsearray[sparse_ind].offset, SEEK_SET) < 0)
{
char buf[UINTMAX_STRSIZE_BOUND];
int e = errno;
ERROR ((0, e, _("%s: lseek error at byte %s"),
quotearg_colon (name),
STRINGIFY_BIGINT (sparsearray[sparse_ind].offset, buf)));
seek_error_details (name, sparsearray[sparse_ind].offset);
return;
}
written = sparsearray[sparse_ind++].numbytes;
@@ -476,7 +454,7 @@ extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
data_block = find_next_block ();
if (! data_block)
{
ERROR ((0, 0, _("Unexpected EOF on archive file")));
ERROR ((0, 0, _("Unexpected EOF in archive")));
return;
}
}
@@ -487,12 +465,7 @@ extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
write_error (name);
else if (count != written)
{
char buf1[UINTMAX_STRSIZE_BOUND];
char buf2[UINTMAX_STRSIZE_BOUND];
ERROR ((0, 0, _("%s: Could only write %s of %s bytes"),
quotearg_colon (name),
STRINGIFY_BIGINT (totalsize - *sizeleft, buf1),
STRINGIFY_BIGINT (totalsize, buf2)));
write_error_details (name, count, written);
skip_file (*sizeleft);
}
@@ -635,7 +608,7 @@ extract_archive (void)
exhdr = find_next_block ();
if (! exhdr)
{
ERROR ((0, 0, _("Unexpected EOF on archive file")));
ERROR ((0, 0, _("Unexpected EOF in archive")));
return;
}
for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++)
@@ -782,7 +755,7 @@ extract_archive (void)
data_block = find_next_block ();
if (! data_block)
{
ERROR ((0, 0, _("Unexpected EOF on archive file")));
ERROR ((0, 0, _("Unexpected EOF in archive")));
break; /* FIXME: What happens, then? */
}
@@ -801,13 +774,7 @@ extract_archive (void)
/* Error in writing to file. Print it, skip to next file in
archive. */
if (sstatus < 0)
write_error (CURRENT_FILE_NAME);
else
ERROR ((0, 0, _("%s: Could only write %lu of %lu bytes"),
quotearg_colon (CURRENT_FILE_NAME),
(unsigned long) sstatus,
(unsigned long) written));
write_error_details (CURRENT_FILE_NAME, sstatus, written);
skip_file (size - written);
break; /* still do the close, mod time, chmod, etc */
}
@@ -1029,8 +996,7 @@ extract_archive (void)
if (errno != EEXIST || old_files_option == KEEP_OLD_FILES)
{
int e = errno;
ERROR ((0, e, "%s: mkdir", quotearg_colon (CURRENT_FILE_NAME)));
mkdir_error (CURRENT_FILE_NAME);
if (backup_option)
undo_last_backup ();
break;
@@ -1057,8 +1023,8 @@ extract_archive (void)
case GNUTYPE_MULTIVOL:
ERROR ((0, 0,
_("Cannot extract %s -- file is continued from another volume"),
quote (current_file_name)));
_("%s: Cannot extract -- file is continued from another volume"),
quotearg_colon (current_file_name)));
skip_file (current_stat.st_size);
if (backup_option)
undo_last_backup ();
@@ -1074,28 +1040,36 @@ extract_archive (void)
default:
WARN ((0, 0,
_("Unknown file type '%c' for %s, extracted as normal file"),
typeflag, quote (CURRENT_FILE_NAME)));
_("%s: Unknown file type '%c', extracted as normal file"),
quotearg_colon (CURRENT_FILE_NAME), typeflag));
goto again_file;
}
#undef CURRENT_FILE_NAME
}
/* Fix the statuses of all directories that are not ancestors of FILE_NAME. */
/* Fix the status of all directories whose statuses need fixing. */
void
apply_delayed_set_stat (char const *file_name)
apply_delayed_set_stat (void)
{
apply_nonancestor_delayed_set_stat ("");
}
/* Fix the statuses of all directories whose statuses need fixing, and
which are not ancestors of FILE_NAME. */
void
apply_nonancestor_delayed_set_stat (char const *file_name)
{
size_t file_name_len = strlen (file_name);
while (delayed_set_stat_head)
{
struct delayed_set_stat *data = delayed_set_stat_head;
delayed_set_stat_head = data->next;
if (data->file_name_len < file_name_len
&& file_name[data->file_name_len] == '/'
&& memcmp (file_name, data->file_name, data->file_name_len) == 0)
break;
delayed_set_stat_head = data->next;
set_stat (data->file_name, &data->stat_info,
data->invert_permissions, data->permstatus, DIRTYPE);
free (data);
@@ -1105,7 +1079,7 @@ apply_delayed_set_stat (char const *file_name)
void
fatal_exit (void)
{
apply_delayed_set_stat ("");
apply_delayed_set_stat ();
error (TAREXIT_FAILURE, 0, _("Error is not recoverable: exiting now"));
abort ();
}