(newdir_umask, current_umask): Now mode_t.
(extract_sparse_file): Args now use off_t. (set_mode, set_stat, make_directories, extract_sparse_file, extract_archive): Use off_t, size_t, ssize_t when appropriate. Remove now-useless casts. Use unsigned long to print *_t types, except use STRINGIFY_BIGINT for off_t.
This commit is contained in:
130
src/extract.c
130
src/extract.c
@@ -35,8 +35,8 @@ struct utimbuf
|
||||
|
||||
static time_t now; /* current time */
|
||||
static int we_are_root; /* true if our effective uid == 0 */
|
||||
static int newdir_umask; /* umask when creating new directories */
|
||||
static int current_umask; /* current umask (which is set to 0 if -p) */
|
||||
static mode_t newdir_umask; /* umask when creating new directories */
|
||||
static mode_t current_umask; /* current umask (which is set to 0 if -p) */
|
||||
|
||||
#if 0
|
||||
/* "Scratch" space to store the information about a sparse file before
|
||||
@@ -103,9 +103,10 @@ set_mode (char *file_name, struct stat *stat_info)
|
||||
|
||||
if (!keep_old_files_option
|
||||
|| (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX)))
|
||||
if (chmod (file_name, ~current_umask & (int) stat_info->st_mode) < 0)
|
||||
ERROR ((0, errno, _("%s: Cannot change mode to %0.4o"),
|
||||
file_name, ~current_umask & (int) stat_info->st_mode));
|
||||
if (chmod (file_name, ~current_umask & stat_info->st_mode) < 0)
|
||||
ERROR ((0, errno, _("%s: Cannot change mode to %0.4lo"),
|
||||
file_name,
|
||||
(unsigned long) (~current_umask & stat_info->st_mode)));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------.
|
||||
@@ -173,14 +174,18 @@ set_stat (char *file_name, struct stat *stat_info, int symlink_flag)
|
||||
if (symlink_flag)
|
||||
{
|
||||
if (lchown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
|
||||
ERROR ((0, errno, _("%s: Cannot lchown to uid %d gid %d"),
|
||||
file_name, stat_info->st_uid, stat_info->st_gid));
|
||||
ERROR ((0, errno, _("%s: Cannot lchown to uid %lu gid %lu"),
|
||||
file_name,
|
||||
(unsigned long) stat_info->st_uid,
|
||||
(unsigned long) stat_info->st_gid));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
|
||||
ERROR ((0, errno, _("%s: Cannot chown to uid %d gid %d"),
|
||||
file_name, stat_info->st_uid, stat_info->st_gid));
|
||||
ERROR ((0, errno, _("%s: Cannot chown to uid %lu gid %lu"),
|
||||
file_name,
|
||||
(unsigned long) stat_info->st_uid,
|
||||
(unsigned long) stat_info->st_gid));
|
||||
}
|
||||
|
||||
#else /* not HAVE_LCHOWN */
|
||||
@@ -188,8 +193,10 @@ set_stat (char *file_name, struct stat *stat_info, int symlink_flag)
|
||||
if (!symlink_flag)
|
||||
|
||||
if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
|
||||
ERROR ((0, errno, _("%s: Cannot chown to uid %d gid %d"),
|
||||
file_name, stat_info->st_uid, stat_info->st_gid));
|
||||
ERROR ((0, errno, _("%s: Cannot chown to uid %lu gid %lu"),
|
||||
file_name,
|
||||
(unsigned long) stat_info->st_uid,
|
||||
(unsigned long) stat_info->st_gid));
|
||||
|
||||
#endif/* not HAVE_LCHOWN */
|
||||
|
||||
@@ -242,8 +249,10 @@ make_directories (char *file_name)
|
||||
if (we_are_root)
|
||||
if (chown (file_name, current_stat.st_uid, current_stat.st_gid) < 0)
|
||||
ERROR ((0, errno,
|
||||
_("%s: Cannot change owner to uid %d, gid %d"),
|
||||
file_name, current_stat.st_uid, current_stat.st_gid));
|
||||
_("%s: Cannot change owner to uid %lu, gid %lu"),
|
||||
file_name,
|
||||
(unsigned long) current_stat.st_uid,
|
||||
(unsigned long) current_stat.st_gid));
|
||||
|
||||
print_for_mkdir (file_name, cursor - file_name,
|
||||
~newdir_umask & 0777);
|
||||
@@ -310,11 +319,12 @@ maybe_recoverable (char *file_name)
|
||||
`---*/
|
||||
|
||||
static void
|
||||
extract_sparse_file (int fd, long *sizeleft, long totalsize, char *name)
|
||||
extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
|
||||
{
|
||||
union block *data_block;
|
||||
int sparse_ind = 0;
|
||||
int written, count;
|
||||
size_t written;
|
||||
ssize_t count;
|
||||
|
||||
/* FIXME: `data_block' might be used uninitialized in this function.
|
||||
Reported by Bruno Haible. */
|
||||
@@ -342,15 +352,19 @@ extract_sparse_file (int fd, long *sizeleft, long totalsize, char *name)
|
||||
data_block = find_next_block ();
|
||||
}
|
||||
|
||||
count = write (fd, data_block->buffer, (size_t) written);
|
||||
count = write (fd, data_block->buffer, written);
|
||||
|
||||
if (count < 0)
|
||||
ERROR ((0, errno, _("%s: Could not write to file"), name));
|
||||
else if (count != written)
|
||||
{
|
||||
ERROR ((0, 0, _("%s: Could only write %d of %d bytes"),
|
||||
name, count, totalsize));
|
||||
skip_file ((long) (*sizeleft));
|
||||
char buf1[UINTMAX_STRSIZE_BOUND];
|
||||
char buf2[UINTMAX_STRSIZE_BOUND];
|
||||
ERROR ((0, 0, _("%s: Could only write %s of %s bytes"),
|
||||
name,
|
||||
STRINGIFY_BIGINT (totalsize - *sizeleft, buf1),
|
||||
STRINGIFY_BIGINT (totalsize, buf2)));
|
||||
skip_file (*sizeleft);
|
||||
}
|
||||
|
||||
written -= count;
|
||||
@@ -371,10 +385,11 @@ extract_archive (void)
|
||||
union block *data_block;
|
||||
int fd;
|
||||
int status;
|
||||
int name_length;
|
||||
int written;
|
||||
ssize_t sstatus;
|
||||
size_t name_length;
|
||||
size_t written;
|
||||
int openflag;
|
||||
long size;
|
||||
off_t size;
|
||||
int skipcrud;
|
||||
int counter;
|
||||
#if 0
|
||||
@@ -392,7 +407,7 @@ extract_archive (void)
|
||||
{
|
||||
if (current_header->oldgnu_header.isextended)
|
||||
skip_extended_headers ();
|
||||
skip_file ((long) current_stat.st_size);
|
||||
skip_file (current_stat.st_size);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -426,7 +441,7 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
CURRENT_FILE_NAME));
|
||||
if (current_header->oldgnu_header.isextended)
|
||||
skip_extended_headers ();
|
||||
skip_file ((long) current_stat.st_size);
|
||||
skip_file (current_stat.st_size);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -456,11 +471,9 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++)
|
||||
{
|
||||
sparsearray[counter].offset =
|
||||
from_oct (1 + 12,
|
||||
current_header->oldgnu_header.sp[counter].offset);
|
||||
OFF_FROM_OCT (current_header->oldgnu_header.sp[counter].offset);
|
||||
sparsearray[counter].numbytes =
|
||||
from_oct (1 + 12,
|
||||
current_header->oldgnu_header.sp[counter].numbytes);
|
||||
SIZE_FROM_OCT (current_header->oldgnu_header.sp[counter].numbytes);
|
||||
if (!sparsearray[counter].numbytes)
|
||||
break;
|
||||
}
|
||||
@@ -492,11 +505,9 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
if (exhdr->sparse_header.sp[counter].numbytes == 0)
|
||||
break;
|
||||
sparsearray[counter + ind].offset =
|
||||
from_oct (1 + 12,
|
||||
exhdr->sparse_header.sp[counter].offset);
|
||||
OFF_FROM_OCT (exhdr->sparse_header.sp[counter].offset);
|
||||
sparsearray[counter + ind].numbytes =
|
||||
from_oct (1 + 12,
|
||||
exhdr->sparse_header.sp[counter].numbytes);
|
||||
SIZE_FROM_OCT (exhdr->sparse_header.sp[counter].numbytes);
|
||||
}
|
||||
if (!exhdr->sparse_header.isextended)
|
||||
break;
|
||||
@@ -581,7 +592,7 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
CURRENT_FILE_NAME));
|
||||
if (current_header->oldgnu_header.isextended)
|
||||
skip_extended_headers ();
|
||||
skip_file ((long) current_stat.st_size);
|
||||
skip_file (current_stat.st_size);
|
||||
if (backup_option)
|
||||
undo_last_backup ();
|
||||
break;
|
||||
@@ -591,7 +602,7 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
if (current_header->header.typeflag == GNUTYPE_SPARSE)
|
||||
{
|
||||
char *name;
|
||||
int name_length_bis;
|
||||
size_t name_length_bis;
|
||||
|
||||
/* Kludge alert. NAME is assigned to header.name because
|
||||
during the extraction, the space that contains the header
|
||||
@@ -600,8 +611,8 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
REAL interesting unless we do this. */
|
||||
|
||||
name_length_bis = strlen (CURRENT_FILE_NAME) + 1;
|
||||
name = (char *) xmalloc ((sizeof (char)) * name_length_bis);
|
||||
memcpy (name, CURRENT_FILE_NAME, (size_t) name_length_bis);
|
||||
name = (char *) xmalloc (name_length_bis);
|
||||
memcpy (name, CURRENT_FILE_NAME, name_length_bis);
|
||||
size = current_stat.st_size;
|
||||
extract_sparse_file (fd, &size, current_stat.st_size, name);
|
||||
}
|
||||
@@ -610,9 +621,6 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
size > 0;
|
||||
size -= written)
|
||||
{
|
||||
#if 0
|
||||
long offset, numbytes;
|
||||
#endif
|
||||
if (multi_volume_option)
|
||||
{
|
||||
assign_string (&save_name, current_file_name);
|
||||
@@ -638,10 +646,7 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
#if 0
|
||||
if (current_header->header.typeflag == GNUTYPE_SPARSE)
|
||||
{
|
||||
off_t pos;
|
||||
|
||||
pos = lseek (fd, (off_t) sparsearray[sparse_ind].offset, 0);
|
||||
fprintf (msg_file, _("%d at %d\n"), (int) pos, sparse_ind);
|
||||
lseek (fd, sparsearray[sparse_ind].offset, 0);
|
||||
written = sparsearray[sparse_ind++].numbytes;
|
||||
}
|
||||
else
|
||||
@@ -651,23 +656,25 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
if (written > size)
|
||||
written = size;
|
||||
errno = 0; /* FIXME: errno should be read-only */
|
||||
status = write (fd, data_block->buffer, (size_t) written);
|
||||
sstatus = write (fd, data_block->buffer, written);
|
||||
|
||||
set_next_block_after ((union block *)
|
||||
(data_block->buffer + written - 1));
|
||||
if (status == written)
|
||||
if (sstatus == written)
|
||||
continue;
|
||||
|
||||
/* Error in writing to file. Print it, skip to next file in
|
||||
archive. */
|
||||
|
||||
if (status < 0)
|
||||
if (sstatus < 0)
|
||||
ERROR ((0, errno, _("%s: Could not write to file"),
|
||||
CURRENT_FILE_NAME));
|
||||
else
|
||||
ERROR ((0, 0, _("%s: Could only write %d of %d bytes"),
|
||||
CURRENT_FILE_NAME, status, written));
|
||||
skip_file ((long) (size - written));
|
||||
ERROR ((0, 0, _("%s: Could only write %lu of %lu bytes"),
|
||||
CURRENT_FILE_NAME,
|
||||
(unsigned long) sstatus,
|
||||
(unsigned long) written));
|
||||
skip_file (size - written);
|
||||
break; /* still do the close, mod time, chmod, etc */
|
||||
}
|
||||
|
||||
@@ -692,11 +699,12 @@ Removing leading `/' from absolute path names in the archive")));
|
||||
|
||||
if (!exhdr->sparse_header.sp[counter].numbytes)
|
||||
break;
|
||||
offset = from_oct (1 + 12, exhdr->sparse_header.sp[counter].offset);
|
||||
written = from_oct (1 + 12, exhdr->sparse_header.sp[counter].numbytes);
|
||||
offset = OFF_FROM_OCT (exhdr->sparse_header.sp[counter].offset);
|
||||
written
|
||||
= SIZE_FROM_OCT (exhdr->sparse_header.sp[counter].numbytes);
|
||||
lseek (fd, offset, 0);
|
||||
status = write (fd, data_block->buffer, written);
|
||||
if (status == written)
|
||||
sstatus = write (fd, data_block->buffer, written);
|
||||
if (sstatus == written)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -812,8 +820,8 @@ Attempting extraction of symbolic links as hard links")));
|
||||
if (unlink_first_option)
|
||||
remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
|
||||
|
||||
status = mknod (CURRENT_FILE_NAME, (int) current_stat.st_mode,
|
||||
(int) current_stat.st_rdev);
|
||||
status = mknod (CURRENT_FILE_NAME, current_stat.st_mode,
|
||||
current_stat.st_rdev);
|
||||
if (status != 0)
|
||||
{
|
||||
if (maybe_recoverable (CURRENT_FILE_NAME))
|
||||
@@ -836,7 +844,7 @@ Attempting extraction of symbolic links as hard links")));
|
||||
if (unlink_first_option)
|
||||
remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
|
||||
|
||||
while (status = mkfifo (CURRENT_FILE_NAME, (int) current_stat.st_mode),
|
||||
while (status = mkfifo (CURRENT_FILE_NAME, current_stat.st_mode),
|
||||
status != 0)
|
||||
if (!maybe_recoverable (CURRENT_FILE_NAME))
|
||||
break;
|
||||
@@ -869,14 +877,14 @@ Attempting extraction of symbolic links as hard links")));
|
||||
gnu_restore (skipcrud);
|
||||
}
|
||||
else if (current_header->header.typeflag == GNUTYPE_DUMPDIR)
|
||||
skip_file ((long) (current_stat.st_size));
|
||||
skip_file (current_stat.st_size);
|
||||
|
||||
if (to_stdout_option)
|
||||
break;
|
||||
|
||||
again_dir:
|
||||
status = mkdir (CURRENT_FILE_NAME,
|
||||
(we_are_root ? 0 : 0300) | (int) current_stat.st_mode);
|
||||
(we_are_root ? 0 : 0300) | current_stat.st_mode);
|
||||
if (status != 0)
|
||||
{
|
||||
/* If the directory creation fails, let's consider immediately the
|
||||
@@ -929,7 +937,7 @@ Attempting extraction of symbolic links as hard links")));
|
||||
}
|
||||
|
||||
check_perms:
|
||||
if (!we_are_root && 0300 != (0300 & (int) current_stat.st_mode))
|
||||
if (!we_are_root && 0300 != (0300 & current_stat.st_mode))
|
||||
{
|
||||
current_stat.st_mode |= 0300;
|
||||
WARN ((0, 0, _("Added write and execute permission to directory %s"),
|
||||
@@ -973,7 +981,7 @@ Attempting extraction of symbolic links as hard links")));
|
||||
ERROR ((0, 0, _("\
|
||||
Cannot extract `%s' -- file is continued from another volume"),
|
||||
current_file_name));
|
||||
skip_file ((long) current_stat.st_size);
|
||||
skip_file (current_stat.st_size);
|
||||
if (backup_option)
|
||||
undo_last_backup ();
|
||||
break;
|
||||
@@ -981,7 +989,7 @@ Cannot extract `%s' -- file is continued from another volume"),
|
||||
case GNUTYPE_LONGNAME:
|
||||
case GNUTYPE_LONGLINK:
|
||||
ERROR ((0, 0, _("Visible long name error")));
|
||||
skip_file ((long) current_stat.st_size);
|
||||
skip_file (current_stat.st_size);
|
||||
if (backup_option)
|
||||
undo_last_backup ();
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user