Hi,
i recently found two bugs ralted to list the file type in verbose (long) mode.
- in copyin(), file_hdr->c_mode was passed to mode_string, but that expects a
mode according struct stat.st_mode (only matters if the file types of system
are different from the CP_xxx constants)
- in cpio_to_stat(), the mode member is just anded with the S_IFxxx constants.
That does not work, for example S_IFDIR (04000) is also set for S_IFBLK type
(060000).
Attached is a propsed patch to fix that.
diff -rup cpio-2.12.orig/src/copyin.c cpio-2.12/src/copyin.c
--- cpio-2.12.orig/src/copyin.c 2020-09-02 02:06:33.674084995 +0200
+++ cpio-2.12/src/copyin.c 2020-09-02 02:44:38.382152878 +0200
@@ -799,8 +799,10 @@ long_format (struct cpio_file_stat *file
char mbuf[11];
char tbuf[40];
time_t when;
+ struct stat st;
- mode_string (file_hdr->c_mode, mbuf);
+ cpio_to_stat(&st, file_hdr);
+ mode_string (st.st_mode, mbuf);
mbuf[10] = '\0';
/* Get time values ready to print. */
Only in cpio-2.12/src: copyin.o
diff -rup cpio-2.12.orig/src/copyout.c cpio-2.12/src/copyout.c
--- cpio-2.12.orig/src/copyout.c 2020-09-02 02:06:33.658084994 +0200
+++ cpio-2.12/src/copyout.c 2020-09-02 03:02:56.802185514 +0200
@@ -654,7 +654,7 @@ process_copy_out ()
if (archive_format == arf_tar || archive_format == arf_ustar)
{
- if (file_hdr.c_mode & CP_IFDIR)
+ if ((file_hdr.c_mode & CP_IFMT) == CP_IFDIR)
{
int len = strlen (input_name.ds_string);
/* Make sure the name ends with a slash */
diff -rup cpio-2.12.orig/src/util.c cpio-2.12/src/util.c
--- cpio-2.12.orig/src/util.c 2020-09-02 02:06:33.678084995 +0200
+++ cpio-2.12/src/util.c 2020-09-02 03:00:05.022180410 +0200
@@ -1368,32 +1368,32 @@ cpio_to_stat (struct stat *st, struct cp
st->st_dev = makedev (hdr->c_dev_maj, hdr->c_dev_min);
st->st_ino = hdr->c_ino;
st->st_mode = hdr->c_mode & 0777;
- if (hdr->c_mode & CP_IFREG)
+ if ((hdr->c_mode & CP_IFMT) == CP_IFREG)
st->st_mode |= S_IFREG;
- else if (hdr->c_mode & CP_IFDIR)
+ else if ((hdr->c_mode & CP_IFMT) == CP_IFDIR)
st->st_mode |= S_IFDIR;
#ifdef S_IFBLK
- else if (hdr->c_mode & CP_IFBLK)
+ else if ((hdr->c_mode & CP_IFMT) == CP_IFBLK)
st->st_mode |= S_IFBLK;
#endif
#ifdef S_IFCHR
- else if (hdr->c_mode & CP_IFCHR)
+ else if ((hdr->c_mode & CP_IFMT) == CP_IFCHR)
st->st_mode |= S_IFCHR;
#endif
#ifdef S_IFFIFO
- else if (hdr->c_mode & CP_IFIFO)
+ else if ((hdr->c_mode & CP_IFMT) == CP_IFIFO)
st->st_mode |= S_IFIFO;
#endif
#ifdef S_IFLNK
- else if (hdr->c_mode & CP_IFLNK)
+ else if ((hdr->c_mode & CP_IFMT) == CP_IFLNK)
st->st_mode |= S_IFLNK;
#endif
#ifdef S_IFSOCK
- else if (hdr->c_mode & CP_IFSOCK)
+ else if ((hdr->c_mode & CP_IFMT) == CP_IFSOCK)
st->st_mode |= S_IFSOCK;
#endif
#ifdef S_IFNWK
- else if (hdr->c_mode & CP_IFNWK)
+ else if ((hdr->c_mode & CP_IFMT) == CP_IFNWK)
st->st_mode |= S_IFNWK;
#endif
st->st_nlink = hdr->c_nlink;