Prefer other types to int in extract.c

* src/extract.c (fd_chmod, extract_chdir, open_output_file)
(extract_file, extract_link, extract_symlink, extract_node)
(extract_fifo, tar_extractor_t, pepare_to_extract): Prefer char to
int for typeflag, since it’s a char.  All uses changed.
(fd_chmod): Use clearer code for errno.
(extract_dir, extract_file, create_placeholder_file, extract_link)
(extract_symlink, extract_node, extract_fifo, tar_extractor_t):
Return bool true for success, false for failure.  All uses changed.
(open_output_file): Prefer bool for boolean.
(prepare_to_extract): Simplify by returning the extractor a null
pointer, rather than storing through a pointer to an extractor.
This commit is contained in:
Paul Eggert
2024-11-01 14:15:09 -07:00
parent fd401e1d29
commit 112ead7931

View File

@@ -272,9 +272,9 @@ fd_i_chmod (int fd, char const *file, mode_t mode, int atflag)
notation. notation.
*/ */
static int static int
fd_chmod(int fd, char const *file_name, int mode, int atflag, int typeflag) fd_chmod (int fd, char const *file_name, int mode, int atflag, char typeflag)
{ {
int chmod_errno = fd_i_chmod (fd, file_name, mode, atflag) == 0 ? 0 : errno; int chmod_errno = fd_i_chmod (fd, file_name, mode, atflag) < 0 ? errno : 0;
/* On Solaris, chmod may fail if we don't have PRIV_ALL, because /* On Solaris, chmod may fail if we don't have PRIV_ALL, because
setuid-root files would otherwise be a backdoor. See setuid-root files would otherwise be a backdoor. See
@@ -283,7 +283,7 @@ fd_chmod(int fd, char const *file_name, int mode, int atflag, int typeflag)
if (chmod_errno == EPERM && (mode & S_ISUID) if (chmod_errno == EPERM && (mode & S_ISUID)
&& priv_set_restore_linkdir () == 0) && priv_set_restore_linkdir () == 0)
{ {
chmod_errno = fd_i_chmod (fd, file_name, mode, atflag) == 0 ? 0 : errno; chmod_errno = fd_i_chmod (fd, file_name, mode, atflag) < 0 ? errno : 0;
priv_set_remove_linkdir (); priv_set_remove_linkdir ();
} }
@@ -293,7 +293,7 @@ fd_chmod(int fd, char const *file_name, int mode, int atflag, int typeflag)
supported and if the file is not a symlink. This supported and if the file is not a symlink. This
introduces a race, alas. */ introduces a race, alas. */
if (atflag && typeflag != SYMTYPE && ! implemented (chmod_errno)) if (atflag && typeflag != SYMTYPE && ! implemented (chmod_errno))
chmod_errno = fd_i_chmod (fd, file_name, mode, 0) == 0 ? 0 : errno; chmod_errno = fd_i_chmod (fd, file_name, mode, 0) < 0 ? errno : 0;
if (chmod_errno && (typeflag != SYMTYPE || implemented (chmod_errno))) if (chmod_errno && (typeflag != SYMTYPE || implemented (chmod_errno)))
{ {
@@ -1061,8 +1061,8 @@ safe_dir_mode (struct stat const *st)
/* Extractor functions for various member types */ /* Extractor functions for various member types */
static int static bool
extract_dir (char *file_name, int typeflag) extract_dir (char *file_name, char typeflag)
{ {
int status; int status;
mode_t mode; mode_t mode;
@@ -1114,7 +1114,7 @@ extract_dir (char *file_name, int typeflag)
if (keep_directory_symlink_option if (keep_directory_symlink_option
&& is_directory_link (file_name, &st)) && is_directory_link (file_name, &st))
return 0; return true;
if ((st.st_mode != 0 && fstatat_flags == 0) if ((st.st_mode != 0 && fstatat_flags == 0)
|| deref_stat (file_name, &st) == 0) || deref_stat (file_name, &st) == 0)
@@ -1127,7 +1127,7 @@ extract_dir (char *file_name, int typeflag)
if (interdir_made) if (interdir_made)
{ {
repair_delayed_set_stat (file_name, &st); repair_delayed_set_stat (file_name, &st);
return 0; return true;
} }
else if (old_files_option == NO_OVERWRITE_DIR_OLD_FILES) else if (old_files_option == NO_OVERWRITE_DIR_OLD_FILES)
{ {
@@ -1179,7 +1179,7 @@ extract_dir (char *file_name, int typeflag)
if (errno != EEXIST) if (errno != EEXIST)
{ {
mkdir_error (file_name); mkdir_error (file_name);
return 1; return false;
} }
break; break;
} }
@@ -1192,13 +1192,13 @@ extract_dir (char *file_name, int typeflag)
delay_set_stat (file_name, &current_stat_info, delay_set_stat (file_name, &current_stat_info,
current_mode, current_mode_mask, current_mode, current_mode_mask,
current_stat_info.stat.st_mode, atflag); current_stat_info.stat.st_mode, atflag);
return status; return status == 0;
} }
static int static int
open_output_file (char const *file_name, int typeflag, mode_t mode, open_output_file (char const *file_name, char typeflag, mode_t mode,
int file_created, mode_t *current_mode, int file_created, mode_t *current_mode,
mode_t *current_mode_mask) mode_t *current_mode_mask)
{ {
@@ -1214,11 +1214,11 @@ open_output_file (char const *file_name, int typeflag, mode_t mode,
if (typeflag == CONTTYPE) if (typeflag == CONTTYPE)
{ {
static int conttype_diagnosed; static bool conttype_diagnosed;
if (!conttype_diagnosed) if (!conttype_diagnosed)
{ {
conttype_diagnosed = 1; conttype_diagnosed = true;
warnopt (WARN_CONTIGUOUS_CAST, 0, warnopt (WARN_CONTIGUOUS_CAST, 0,
_("Extracting contiguous files as regular files")); _("Extracting contiguous files as regular files"));
} }
@@ -1270,8 +1270,8 @@ open_output_file (char const *file_name, int typeflag, mode_t mode,
return fd; return fd;
} }
static int static bool
extract_file (char *file_name, int typeflag) extract_file (char *file_name, char typeflag)
{ {
int fd; int fd;
off_t size; off_t size;
@@ -1291,7 +1291,7 @@ extract_file (char *file_name, int typeflag)
if (fd < 0) if (fd < 0)
{ {
skip_member (); skip_member ();
return 0; return true;
} }
} }
else else
@@ -1315,9 +1315,9 @@ extract_file (char *file_name, int typeflag)
{ {
skip_member (); skip_member ();
if (recover == RECOVER_SKIP) if (recover == RECOVER_SKIP)
return 0; return true;
open_error (file_name); open_error (file_name);
return 1; return false;
} }
} }
} }
@@ -1368,7 +1368,7 @@ extract_file (char *file_name, int typeflag)
it doesn't exist, or we don't want to touch it anyway. */ it doesn't exist, or we don't want to touch it anyway. */
if (to_stdout_option) if (to_stdout_option)
return 0; return true;
if (! to_command_option) if (! to_command_option)
set_stat (file_name, &current_stat_info, fd, set_stat (file_name, &current_stat_info, fd,
@@ -1383,7 +1383,7 @@ extract_file (char *file_name, int typeflag)
if (to_command_option) if (to_command_option)
sys_wait_command (); sys_wait_command ();
return status; return status == 0;
} }
/* Return true if NAME is a delayed link. This can happen only if the link /* Return true if NAME is a delayed link. This can happen only if the link
@@ -1423,7 +1423,7 @@ find_delayed_link_source (char const *name)
process. process.
*/ */
static int static bool
create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made) create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
{ {
int fd; int fd;
@@ -1437,7 +1437,7 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
that the link being extracted is a duplicate of an already that the link being extracted is a duplicate of an already
processed one. Skip it. processed one. Skip it.
*/ */
return 0; return true;
} }
switch (maybe_recoverable (file_name, false, interdir_made)) switch (maybe_recoverable (file_name, false, interdir_made))
@@ -1446,11 +1446,11 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
continue; continue;
case RECOVER_SKIP: case RECOVER_SKIP:
return 0; return true;
case RECOVER_NO: case RECOVER_NO:
open_error (file_name); open_error (file_name);
return -1; return false;
} }
} }
@@ -1508,14 +1508,14 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
if ((h = find_direct_ancestor (file_name)) != NULL) if ((h = find_direct_ancestor (file_name)) != NULL)
mark_after_links (h); mark_after_links (h);
return 0; return true;
} }
return -1; return false;
} }
static int static bool
extract_link (char *file_name, MAYBE_UNUSED int typeflag) extract_link (char *file_name, MAYBE_UNUSED char typeflag)
{ {
bool interdir_made = false; bool interdir_made = false;
char const *link_name; char const *link_name;
@@ -1555,7 +1555,7 @@ extract_link (char *file_name, MAYBE_UNUSED int typeflag)
} }
} }
return 0; return true;
} }
else if ((e == EEXIST && strcmp (link_name, file_name) == 0) else if ((e == EEXIST && strcmp (link_name, file_name) == 0)
|| ((fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW) || ((fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW)
@@ -1564,7 +1564,7 @@ extract_link (char *file_name, MAYBE_UNUSED int typeflag)
== 0) == 0)
&& st1.st_dev == st2.st_dev && st1.st_dev == st2.st_dev
&& st1.st_ino == st2.st_ino)) && st1.st_ino == st2.st_ino))
return 0; return true;
errno = e; errno = e;
} }
@@ -1572,17 +1572,17 @@ extract_link (char *file_name, MAYBE_UNUSED int typeflag)
== RECOVER_OK); == RECOVER_OK);
if (rc == RECOVER_SKIP) if (rc == RECOVER_SKIP)
return 0; return true;
if (!(incremental_option && errno == EEXIST)) if (!(incremental_option && errno == EEXIST))
{ {
link_error (link_name, file_name); link_error (link_name, file_name);
return 1; return false;
} }
return 0; return true;
} }
static int static bool
extract_symlink (char *file_name, MAYBE_UNUSED int typeflag) extract_symlink (char *file_name, MAYBE_UNUSED char typeflag)
{ {
bool interdir_made = false; bool interdir_made = false;
@@ -1598,7 +1598,7 @@ extract_symlink (char *file_name, MAYBE_UNUSED int typeflag)
continue; continue;
case RECOVER_SKIP: case RECOVER_SKIP:
return 0; return true;
case RECOVER_NO: case RECOVER_NO:
if (!implemented (errno)) if (!implemented (errno))
@@ -1614,17 +1614,17 @@ extract_symlink (char *file_name, MAYBE_UNUSED int typeflag)
return extract_link (file_name, typeflag); return extract_link (file_name, typeflag);
} }
symlink_error (current_stat_info.link_name, file_name); symlink_error (current_stat_info.link_name, file_name);
return -1; return false;
} }
set_stat (file_name, &current_stat_info, -1, 0, 0, set_stat (file_name, &current_stat_info, -1, 0, 0,
SYMTYPE, false, AT_SYMLINK_NOFOLLOW); SYMTYPE, false, AT_SYMLINK_NOFOLLOW);
return 0; return true;
} }
#if S_IFCHR || S_IFBLK #if S_IFCHR || S_IFBLK
static int static bool
extract_node (char *file_name, int typeflag) extract_node (char *file_name, char typeflag)
{ {
bool interdir_made = false; bool interdir_made = false;
mode_t mode = (current_stat_info.stat.st_mode & (MODE_RWX | S_IFBLK | S_IFCHR) mode_t mode = (current_stat_info.stat.st_mode & (MODE_RWX | S_IFBLK | S_IFCHR)
@@ -1638,23 +1638,23 @@ extract_node (char *file_name, int typeflag)
continue; continue;
case RECOVER_SKIP: case RECOVER_SKIP:
return 0; return true;
case RECOVER_NO: case RECOVER_NO:
mknod_error (file_name); mknod_error (file_name);
return -1; return false;
} }
set_stat (file_name, &current_stat_info, -1, set_stat (file_name, &current_stat_info, -1,
mode & ~ current_umask, MODE_RWX, mode & ~ current_umask, MODE_RWX,
typeflag, false, AT_SYMLINK_NOFOLLOW); typeflag, false, AT_SYMLINK_NOFOLLOW);
return 0; return true;
} }
#endif #endif
#if HAVE_MKFIFO || defined mkfifo #if HAVE_MKFIFO || defined mkfifo
static int static bool
extract_fifo (char *file_name, int typeflag) extract_fifo (char *file_name, char typeflag)
{ {
bool interdir_made = false; bool interdir_made = false;
mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
@@ -1667,31 +1667,31 @@ extract_fifo (char *file_name, int typeflag)
continue; continue;
case RECOVER_SKIP: case RECOVER_SKIP:
return 0; return true;
case RECOVER_NO: case RECOVER_NO:
mkfifo_error (file_name); mkfifo_error (file_name);
return -1; return false;
} }
set_stat (file_name, &current_stat_info, -1, set_stat (file_name, &current_stat_info, -1,
mode & ~ current_umask, MODE_RWX, mode & ~ current_umask, MODE_RWX,
typeflag, false, AT_SYMLINK_NOFOLLOW); typeflag, false, AT_SYMLINK_NOFOLLOW);
return 0; return true;
} }
#endif #endif
typedef int (*tar_extractor_t) (char *file_name, int typeflag); typedef bool (*tar_extractor_t) (char *file_name, char typeflag);
/* Prepare to extract a file. Find extractor function. /* Prepare to extract a file. Find extractor function.
Return true to proceed with the extraction, false to skip the current Return an extractor to proceed with the extraction,
member. */ a null pointer to skip the current member. */
static bool static tar_extractor_t
prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun) prepare_to_extract (char const *file_name, char typeflag)
{ {
tar_extractor_t extractor = NULL; tar_extractor_t extractor;
/* Select the extractor */ /* Select the extractor */
switch (typeflag) switch (typeflag)
@@ -1705,10 +1705,8 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
case CONTTYPE: case CONTTYPE:
/* Appears to be a file. But BSD tar uses the convention that a slash /* Appears to be a file. But BSD tar uses the convention that a slash
suffix means a directory. */ suffix means a directory. */
if (current_stat_info.had_trailing_slash) extractor = (current_stat_info.had_trailing_slash
extractor = extract_dir; ? extract_dir : extract_file);
else
extractor = extract_file;
break; break;
case SYMTYPE: case SYMTYPE:
@@ -1747,17 +1745,17 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
break; break;
case GNUTYPE_VOLHDR: case GNUTYPE_VOLHDR:
return false; return NULL;
case GNUTYPE_MULTIVOL: case GNUTYPE_MULTIVOL:
paxerror (0, _("%s: Cannot extract -- file is continued from another volume"), paxerror (0, _("%s: Cannot extract -- file is continued from another volume"),
quotearg_colon (current_stat_info.file_name)); quotearg_colon (current_stat_info.file_name));
return false; return NULL;
case GNUTYPE_LONGNAME: case GNUTYPE_LONGNAME:
case GNUTYPE_LONGLINK: case GNUTYPE_LONGLINK:
paxerror (0, _("Unexpected long name header")); paxerror (0, _("Unexpected long name header"));
return false; return NULL;
default: default:
warnopt (WARN_UNKNOWN_CAST, 0, warnopt (WARN_UNKNOWN_CAST, 0,
@@ -1769,7 +1767,7 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
if (to_stdout_option || to_command_option) if (to_stdout_option || to_command_option)
{ {
if (extractor != extract_file) if (extractor != extract_file)
return false; return NULL;
} }
else else
{ {
@@ -1783,7 +1781,7 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
&& errno && errno != ENOENT) && errno && errno != ENOENT)
{ {
unlink_error (file_name); unlink_error (file_name);
return false; return NULL;
} }
break; break;
@@ -1792,7 +1790,7 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
{ {
warnopt (WARN_IGNORE_NEWER, 0, _("Current %s is newer or same age"), warnopt (WARN_IGNORE_NEWER, 0, _("Current %s is newer or same age"),
quote (file_name)); quote (file_name));
return false; return NULL;
} }
break; break;
@@ -1800,9 +1798,7 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
break; break;
} }
} }
*fun = extractor; return extractor;
return true;
} }
/* Extract a file from the archive. */ /* Extract a file from the archive. */
@@ -1810,7 +1806,6 @@ void
extract_archive (void) extract_archive (void)
{ {
char typeflag; char typeflag;
tar_extractor_t fun;
bool skip_dotdot_name; bool skip_dotdot_name;
fatal_exit_hook = extract_finish; fatal_exit_hook = extract_finish;
@@ -1859,12 +1854,14 @@ extract_archive (void)
/* Extract the archive entry according to its type. */ /* Extract the archive entry according to its type. */
/* KLUDGE */ /* KLUDGE */
typeflag = sparse_member_p (&current_stat_info) ? typeflag = (sparse_member_p (&current_stat_info)
GNUTYPE_SPARSE : current_header->header.typeflag; ? GNUTYPE_SPARSE : current_header->header.typeflag);
if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun)) tar_extractor_t fun = prepare_to_extract (current_stat_info.file_name,
typeflag);
if (fun)
{ {
if (fun (current_stat_info.file_name, typeflag) == 0) if (fun (current_stat_info.file_name, typeflag))
return; return;
} }
else else