Hi, I noticed many files in cpio are older versions of those in Gnulib. Here are a few patches to just import them.
Patch 1 fixes a function pointer that doesn't work when using 'gcc -std=c23'. There 'int func ()' == 'int func (void)' so using arguments throws an error. Patch 2 makes 'make' return success when running 'make clean' before 'make check'. Patch 3, 4, 5 removes filemode.c, idcache.c, and userspec.c instead opting for updated versions in Gnulib. I'd like to pull in Paul's recent changes to paxutils but that needs a bit more work. So work-in-progress for now. Collin
>From 3643eb52fb84c99f8d9fa7ac2a0c36aa38b1cd08 Mon Sep 17 00:00:00 2001 From: Collin Funk <[email protected]> Date: Mon, 5 Aug 2024 21:55:33 -0700 Subject: [PATCH 1/5] maint: Allow compilation with C23 compilers. * src/extern.h (xstat): Add parameters to function signature. * src/global.c (xstat): Likewise. --- src/extern.h | 2 +- src/global.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/extern.h b/src/extern.h index 9431729..fb83b1e 100644 --- a/src/extern.h +++ b/src/extern.h @@ -97,7 +97,7 @@ extern char input_is_special; extern char output_is_special; extern char input_is_seekable; extern char output_is_seekable; -extern int (*xstat) (); +extern int (*xstat) (const char *pathname, struct stat *buf); extern void (*copy_function) (); extern char *change_directory_option; diff --git a/src/global.c b/src/global.c index 085d41a..3a4a41a 100644 --- a/src/global.c +++ b/src/global.c @@ -185,7 +185,7 @@ bool to_stdout_option = false; /* A pointer to either lstat or stat, depending on whether dereferencing of symlinks is done for input files. */ -int (*xstat) (); +int (*xstat) (const char *pathname, struct stat *buf); /* Which copy operation to perform. (-i, -o, -p) */ void (*copy_function) () = 0; -- 2.45.2
>From 591ac98e606d11eb70cc8e5b83f60f50468c896d Mon Sep 17 00:00:00 2001 From: Collin Funk <[email protected]> Date: Mon, 5 Aug 2024 22:09:22 -0700 Subject: [PATCH 2/5] build: Don't fail on 'make clean' before 'make check'. * tests/Makefile.am (clean-local): Check for the $(TESTSUITE) before trying to run it. --- tests/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index a2894a7..43b5fae 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -72,7 +72,9 @@ atconfig: $(top_builddir)/config.status cd $(top_builddir) && ./config.status tests/$@ clean-local: - $(SHELL) $(TESTSUITE) --clean + if test -x $(TESTSUITE); then \ + $(SHELL) $(TESTSUITE) --clean; \ + fi check-local: atconfig atlocal $(TESTSUITE) $(SHELL) $(TESTSUITE) $(TESTSUITEFLAGS) -- 2.45.2
>From de69c5474ec016d405f3d98a71724b88f853c61c Mon Sep 17 00:00:00 2001 From: Collin Funk <[email protected]> Date: Tue, 6 Aug 2024 20:31:11 -0700 Subject: [PATCH 3/5] maint: Use filemode from Gnulib. * gnulib.modules: Add filemode. * src/Makefile.am (cpio_SOURCES): Remove filemode.c. * src/copyin.c: Include filemode.h. (long_format): Use strmode instead of mode_string. * src/extern.h (mode_string): Remove declaration. * src/filemode.c: Remove file. --- gnulib.modules | 1 + src/Makefile.am | 1 - src/copyin.c | 8 +- src/extern.h | 3 - src/filemode.c | 242 ------------------------------------------------ 5 files changed, 5 insertions(+), 250 deletions(-) delete mode 100644 src/filemode.c diff --git a/gnulib.modules b/gnulib.modules index 701abf9..40e8087 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -9,6 +9,7 @@ dirname error fdutimensat fileblocks +filemode fnmatch-gnu full-write getline diff --git a/src/Makefile.am b/src/Makefile.am index 739cb83..b469aa5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,7 +36,6 @@ cpio_SOURCES = \ main.c\ tar.c\ util.c\ - filemode.c\ idcache.c\ makepath.c\ userspec.c diff --git a/src/copyin.c b/src/copyin.c index ace0a02..467d86d 100644 --- a/src/copyin.c +++ b/src/copyin.c @@ -31,6 +31,7 @@ # include <fnmatch.h> #endif #include <hash.h> +#include <filemode.h> #ifndef HAVE_LCHOWN # define lchown(f,u,g) 0 @@ -873,7 +874,7 @@ static struct timespec current_time; void long_format (struct cpio_file_stat *file_hdr, char const *link_name) { - char mbuf[11]; + char mbuf[12]; time_t when; char *tbuf; struct timespec when_timespec; @@ -885,10 +886,9 @@ long_format (struct cpio_file_stat *file_hdr, char const *link_name) .tv_nsec = current_time.tv_nsec }; - mode_string (file_hdr->c_mode, mbuf); - mbuf[10] = '\0'; + strmode (file_hdr->c_mode, mbuf); - printf ("%s %3ju ", mbuf, (uintmax_t) file_hdr->c_nlink); + printf ("%s%3ju ", mbuf, (uintmax_t) file_hdr->c_nlink); if (numeric_uid) printf ("%-8ju %-8ju ", diff --git a/src/extern.h b/src/extern.h index fb83b1e..1cb99fc 100644 --- a/src/extern.h +++ b/src/extern.h @@ -135,9 +135,6 @@ int link_to_name (char const *link_name, char const *link_target); /* dirname.c */ char *dirname (char *path); -/* filemode.c */ -void mode_string (unsigned int mode, char *str); - /* idcache.c */ char *getgroup (gid_t gid); char *getuser (uid_t uid); diff --git a/src/filemode.c b/src/filemode.c deleted file mode 100644 index 13dfaaf..0000000 --- a/src/filemode.c +++ /dev/null @@ -1,242 +0,0 @@ -/* filemode.c -- make a string describing file modes - Copyright (C) 1985-2024 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> - -#if !S_IRUSR -# if S_IREAD -# define S_IRUSR S_IREAD -# else -# define S_IRUSR 00400 -# endif -#endif - -#if !S_IWUSR -# if S_IWRITE -# define S_IWUSR S_IWRITE -# else -# define S_IWUSR 00200 -# endif -#endif - -#if !S_IXUSR -# if S_IEXEC -# define S_IXUSR S_IEXEC -# else -# define S_IXUSR 00100 -# endif -#endif - -#ifdef STAT_MACROS_BROKEN -#undef S_ISBLK -#undef S_ISCHR -#undef S_ISDIR -#undef S_ISFIFO -#undef S_ISLNK -#undef S_ISMPB -#undef S_ISMPC -#undef S_ISNWK -#undef S_ISREG -#undef S_ISSOCK -#endif /* STAT_MACROS_BROKEN. */ - -#if !defined(S_ISBLK) && defined(S_IFBLK) -#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -#endif -#if !defined(S_ISCHR) && defined(S_IFCHR) -#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -#endif -#if !defined(S_ISDIR) && defined(S_IFDIR) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif -#if !defined(S_ISREG) && defined(S_IFREG) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif -#if !defined(S_ISFIFO) && defined(S_IFIFO) -#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -#endif -#if !defined(S_ISLNK) && defined(S_IFLNK) -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#if !defined(S_ISSOCK) && defined(S_IFSOCK) -#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -#endif -#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */ -#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) -#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) -#endif -#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */ -#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) -#endif - -/* Return a character indicating the type of file described by - file mode BITS: - 'd' for directories - 'b' for block special files - 'c' for character special files - 'm' for multiplexor files - 'l' for symbolic links - 's' for sockets - 'p' for fifos - '-' for regular files - '?' for any other file type. */ - -static char -ftypelet (long bits) -{ -#ifdef S_ISBLK - if (S_ISBLK (bits)) - return 'b'; -#endif - if (S_ISCHR (bits)) - return 'c'; - if (S_ISDIR (bits)) - return 'd'; - if (S_ISREG (bits)) - return '-'; -#ifdef S_ISFIFO - if (S_ISFIFO (bits)) - return 'p'; -#endif -#ifdef S_ISLNK - if (S_ISLNK (bits)) - return 'l'; -#endif -#ifdef S_ISSOCK - if (S_ISSOCK (bits)) - return 's'; -#endif -#ifdef S_ISMPC - if (S_ISMPC (bits)) - return 'm'; -#endif -#ifdef S_ISNWK - if (S_ISNWK (bits)) - return 'n'; -#endif - return '?'; -} - -/* Look at read, write, and execute bits in BITS and set - flags in CHARS accordingly. */ - -static void -rwx (unsigned short bits, char *chars) -{ - chars[0] = (bits & S_IRUSR) ? 'r' : '-'; - chars[1] = (bits & S_IWUSR) ? 'w' : '-'; - chars[2] = (bits & S_IXUSR) ? 'x' : '-'; -} - -/* Set the 's' and 't' flags in file attributes string CHARS, - according to the file mode BITS. */ - -static void -setst (unsigned short bits, char *chars) -{ -#ifdef S_ISUID - if (bits & S_ISUID) - { - if (chars[3] != 'x') - /* Set-uid, but not executable by owner. */ - chars[3] = 'S'; - else - chars[3] = 's'; - } -#endif -#ifdef S_ISGID - if (bits & S_ISGID) - { - if (chars[6] != 'x') - /* Set-gid, but not executable by group. */ - chars[6] = 'S'; - else - chars[6] = 's'; - } -#endif -#ifdef S_ISVTX - if (bits & S_ISVTX) - { - if (chars[9] != 'x') - /* Sticky, but not executable by others. */ - chars[9] = 'T'; - else - chars[9] = 't'; - } -#endif -} - -/* Like filemodestring (see below), but only the relevant part of the - `struct stat' is given as an argument. */ - -void -mode_string (unsigned int mode, char *str) -{ - str[0] = ftypelet ((long) mode); - rwx ((mode & 0700) << 0, &str[1]); - rwx ((mode & 0070) << 3, &str[4]); - rwx ((mode & 0007) << 6, &str[7]); - setst (mode, str); -} - -/* filemodestring - fill in string STR with an ls-style ASCII - representation of the st_mode field of file stats block STATP. - 10 characters are stored in STR; no terminating null is added. - The characters stored in STR are: - - 0 File type. 'd' for directory, 'c' for character - special, 'b' for block special, 'm' for multiplex, - 'l' for symbolic link, 's' for socket, 'p' for fifo, - '-' for regular, '?' for any other file type - - 1 'r' if the owner may read, '-' otherwise. - - 2 'w' if the owner may write, '-' otherwise. - - 3 'x' if the owner may execute, 's' if the file is - set-user-id, '-' otherwise. - 'S' if the file is set-user-id, but the execute - bit isn't set. - - 4 'r' if group members may read, '-' otherwise. - - 5 'w' if group members may write, '-' otherwise. - - 6 'x' if group members may execute, 's' if the file is - set-group-id, '-' otherwise. - 'S' if it is set-group-id but not executable. - - 7 'r' if any user may read, '-' otherwise. - - 8 'w' if any user may write, '-' otherwise. - - 9 'x' if any user may execute, 't' if the file is "sticky" - (will be retained in swap space after execution), '-' - otherwise. - 'T' if the file is sticky but not executable. */ - -void -filemodestring (struct stat *statp, char *str) -{ - mode_string (statp->st_mode, str); -} -- 2.45.2
>From de69c5474ec016d405f3d98a71724b88f853c61c Mon Sep 17 00:00:00 2001 From: Collin Funk <[email protected]> Date: Tue, 6 Aug 2024 20:31:11 -0700 Subject: [PATCH 3/5] maint: Use filemode from Gnulib. * gnulib.modules: Add filemode. * src/Makefile.am (cpio_SOURCES): Remove filemode.c. * src/copyin.c: Include filemode.h. (long_format): Use strmode instead of mode_string. * src/extern.h (mode_string): Remove declaration. * src/filemode.c: Remove file. --- gnulib.modules | 1 + src/Makefile.am | 1 - src/copyin.c | 8 +- src/extern.h | 3 - src/filemode.c | 242 ------------------------------------------------ 5 files changed, 5 insertions(+), 250 deletions(-) delete mode 100644 src/filemode.c diff --git a/gnulib.modules b/gnulib.modules index 701abf9..40e8087 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -9,6 +9,7 @@ dirname error fdutimensat fileblocks +filemode fnmatch-gnu full-write getline diff --git a/src/Makefile.am b/src/Makefile.am index 739cb83..b469aa5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,7 +36,6 @@ cpio_SOURCES = \ main.c\ tar.c\ util.c\ - filemode.c\ idcache.c\ makepath.c\ userspec.c diff --git a/src/copyin.c b/src/copyin.c index ace0a02..467d86d 100644 --- a/src/copyin.c +++ b/src/copyin.c @@ -31,6 +31,7 @@ # include <fnmatch.h> #endif #include <hash.h> +#include <filemode.h> #ifndef HAVE_LCHOWN # define lchown(f,u,g) 0 @@ -873,7 +874,7 @@ static struct timespec current_time; void long_format (struct cpio_file_stat *file_hdr, char const *link_name) { - char mbuf[11]; + char mbuf[12]; time_t when; char *tbuf; struct timespec when_timespec; @@ -885,10 +886,9 @@ long_format (struct cpio_file_stat *file_hdr, char const *link_name) .tv_nsec = current_time.tv_nsec }; - mode_string (file_hdr->c_mode, mbuf); - mbuf[10] = '\0'; + strmode (file_hdr->c_mode, mbuf); - printf ("%s %3ju ", mbuf, (uintmax_t) file_hdr->c_nlink); + printf ("%s%3ju ", mbuf, (uintmax_t) file_hdr->c_nlink); if (numeric_uid) printf ("%-8ju %-8ju ", diff --git a/src/extern.h b/src/extern.h index fb83b1e..1cb99fc 100644 --- a/src/extern.h +++ b/src/extern.h @@ -135,9 +135,6 @@ int link_to_name (char const *link_name, char const *link_target); /* dirname.c */ char *dirname (char *path); -/* filemode.c */ -void mode_string (unsigned int mode, char *str); - /* idcache.c */ char *getgroup (gid_t gid); char *getuser (uid_t uid); diff --git a/src/filemode.c b/src/filemode.c deleted file mode 100644 index 13dfaaf..0000000 --- a/src/filemode.c +++ /dev/null @@ -1,242 +0,0 @@ -/* filemode.c -- make a string describing file modes - Copyright (C) 1985-2024 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> - -#if !S_IRUSR -# if S_IREAD -# define S_IRUSR S_IREAD -# else -# define S_IRUSR 00400 -# endif -#endif - -#if !S_IWUSR -# if S_IWRITE -# define S_IWUSR S_IWRITE -# else -# define S_IWUSR 00200 -# endif -#endif - -#if !S_IXUSR -# if S_IEXEC -# define S_IXUSR S_IEXEC -# else -# define S_IXUSR 00100 -# endif -#endif - -#ifdef STAT_MACROS_BROKEN -#undef S_ISBLK -#undef S_ISCHR -#undef S_ISDIR -#undef S_ISFIFO -#undef S_ISLNK -#undef S_ISMPB -#undef S_ISMPC -#undef S_ISNWK -#undef S_ISREG -#undef S_ISSOCK -#endif /* STAT_MACROS_BROKEN. */ - -#if !defined(S_ISBLK) && defined(S_IFBLK) -#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -#endif -#if !defined(S_ISCHR) && defined(S_IFCHR) -#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -#endif -#if !defined(S_ISDIR) && defined(S_IFDIR) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif -#if !defined(S_ISREG) && defined(S_IFREG) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif -#if !defined(S_ISFIFO) && defined(S_IFIFO) -#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -#endif -#if !defined(S_ISLNK) && defined(S_IFLNK) -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#if !defined(S_ISSOCK) && defined(S_IFSOCK) -#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -#endif -#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */ -#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) -#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) -#endif -#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */ -#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) -#endif - -/* Return a character indicating the type of file described by - file mode BITS: - 'd' for directories - 'b' for block special files - 'c' for character special files - 'm' for multiplexor files - 'l' for symbolic links - 's' for sockets - 'p' for fifos - '-' for regular files - '?' for any other file type. */ - -static char -ftypelet (long bits) -{ -#ifdef S_ISBLK - if (S_ISBLK (bits)) - return 'b'; -#endif - if (S_ISCHR (bits)) - return 'c'; - if (S_ISDIR (bits)) - return 'd'; - if (S_ISREG (bits)) - return '-'; -#ifdef S_ISFIFO - if (S_ISFIFO (bits)) - return 'p'; -#endif -#ifdef S_ISLNK - if (S_ISLNK (bits)) - return 'l'; -#endif -#ifdef S_ISSOCK - if (S_ISSOCK (bits)) - return 's'; -#endif -#ifdef S_ISMPC - if (S_ISMPC (bits)) - return 'm'; -#endif -#ifdef S_ISNWK - if (S_ISNWK (bits)) - return 'n'; -#endif - return '?'; -} - -/* Look at read, write, and execute bits in BITS and set - flags in CHARS accordingly. */ - -static void -rwx (unsigned short bits, char *chars) -{ - chars[0] = (bits & S_IRUSR) ? 'r' : '-'; - chars[1] = (bits & S_IWUSR) ? 'w' : '-'; - chars[2] = (bits & S_IXUSR) ? 'x' : '-'; -} - -/* Set the 's' and 't' flags in file attributes string CHARS, - according to the file mode BITS. */ - -static void -setst (unsigned short bits, char *chars) -{ -#ifdef S_ISUID - if (bits & S_ISUID) - { - if (chars[3] != 'x') - /* Set-uid, but not executable by owner. */ - chars[3] = 'S'; - else - chars[3] = 's'; - } -#endif -#ifdef S_ISGID - if (bits & S_ISGID) - { - if (chars[6] != 'x') - /* Set-gid, but not executable by group. */ - chars[6] = 'S'; - else - chars[6] = 's'; - } -#endif -#ifdef S_ISVTX - if (bits & S_ISVTX) - { - if (chars[9] != 'x') - /* Sticky, but not executable by others. */ - chars[9] = 'T'; - else - chars[9] = 't'; - } -#endif -} - -/* Like filemodestring (see below), but only the relevant part of the - `struct stat' is given as an argument. */ - -void -mode_string (unsigned int mode, char *str) -{ - str[0] = ftypelet ((long) mode); - rwx ((mode & 0700) << 0, &str[1]); - rwx ((mode & 0070) << 3, &str[4]); - rwx ((mode & 0007) << 6, &str[7]); - setst (mode, str); -} - -/* filemodestring - fill in string STR with an ls-style ASCII - representation of the st_mode field of file stats block STATP. - 10 characters are stored in STR; no terminating null is added. - The characters stored in STR are: - - 0 File type. 'd' for directory, 'c' for character - special, 'b' for block special, 'm' for multiplex, - 'l' for symbolic link, 's' for socket, 'p' for fifo, - '-' for regular, '?' for any other file type - - 1 'r' if the owner may read, '-' otherwise. - - 2 'w' if the owner may write, '-' otherwise. - - 3 'x' if the owner may execute, 's' if the file is - set-user-id, '-' otherwise. - 'S' if the file is set-user-id, but the execute - bit isn't set. - - 4 'r' if group members may read, '-' otherwise. - - 5 'w' if group members may write, '-' otherwise. - - 6 'x' if group members may execute, 's' if the file is - set-group-id, '-' otherwise. - 'S' if it is set-group-id but not executable. - - 7 'r' if any user may read, '-' otherwise. - - 8 'w' if any user may write, '-' otherwise. - - 9 'x' if any user may execute, 't' if the file is "sticky" - (will be retained in swap space after execution), '-' - otherwise. - 'T' if the file is sticky but not executable. */ - -void -filemodestring (struct stat *statp, char *str) -{ - mode_string (statp->st_mode, str); -} -- 2.45.2
>From 5362f8ac33f13908b6e3656f3a7e946da83481b8 Mon Sep 17 00:00:00 2001 From: Collin Funk <[email protected]> Date: Tue, 6 Aug 2024 21:16:15 -0700 Subject: [PATCH 4/5] maint: Use idcache from Gnulib. * gnulib.modules: Add idcache. * src/Makefile.am (cpio_SOURCES): Remove idcache.c * src/copyin.c: Include idcache.h (long_format): Adjust code to Gnulib's version which may return a null pointer instead of uid/gid as a numeric string. * src/tar.c (write_out_tar_header): Likewise. * src/extern.h (getgroup, getuser, getuidbyname, getgidbyname): Remove declarations. * src/idcache.c: Remove file. --- gnulib.modules | 1 + src/Makefile.am | 1 - src/copyin.c | 17 +++-- src/extern.h | 6 -- src/idcache.c | 197 ------------------------------------------------ src/tar.c | 13 +++- 6 files changed, 21 insertions(+), 214 deletions(-) delete mode 100644 src/idcache.c diff --git a/gnulib.modules b/gnulib.modules index 40e8087..ee54d2f 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -17,6 +17,7 @@ gettext-h gettime gitlog-to-changelog hash +idcache inttostr inttypes lchown diff --git a/src/Makefile.am b/src/Makefile.am index b469aa5..5ee0e79 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,7 +36,6 @@ cpio_SOURCES = \ main.c\ tar.c\ util.c\ - idcache.c\ makepath.c\ userspec.c diff --git a/src/copyin.c b/src/copyin.c index 467d86d..3725cab 100644 --- a/src/copyin.c +++ b/src/copyin.c @@ -32,6 +32,7 @@ #endif #include <hash.h> #include <filemode.h> +#include <idcache.h> #ifndef HAVE_LCHOWN # define lchown(f,u,g) 0 @@ -875,6 +876,8 @@ void long_format (struct cpio_file_stat *file_hdr, char const *link_name) { char mbuf[12]; + char *user = !numeric_uid ? getuser (file_hdr->c_uid) : NULL; + char *group = !numeric_uid ? getgroup (file_hdr->c_gid) : NULL; time_t when; char *tbuf; struct timespec when_timespec; @@ -890,13 +893,15 @@ long_format (struct cpio_file_stat *file_hdr, char const *link_name) printf ("%s%3ju ", mbuf, (uintmax_t) file_hdr->c_nlink); - if (numeric_uid) - printf ("%-8ju %-8ju ", - (uintmax_t) file_hdr->c_uid, - (uintmax_t) file_hdr->c_gid); + if (user != NULL) + printf ("%-8.8s ", user); else - printf ("%-8.8s %-8.8s ", getuser (file_hdr->c_uid), - getgroup (file_hdr->c_gid)); + printf ("%-8ju ", (uintmax_t) file_hdr->c_uid); + + if (group != NULL) + printf ("%-8.8s ", group); + else + printf ("%-8ju ", (uintmax_t) file_hdr->c_gid); if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR || (file_hdr->c_mode & CP_IFMT) == CP_IFBLK) diff --git a/src/extern.h b/src/extern.h index 1cb99fc..0b7fb83 100644 --- a/src/extern.h +++ b/src/extern.h @@ -135,12 +135,6 @@ int link_to_name (char const *link_name, char const *link_target); /* dirname.c */ char *dirname (char *path); -/* idcache.c */ -char *getgroup (gid_t gid); -char *getuser (uid_t uid); -uid_t *getuidbyname (char *user); -gid_t *getgidbyname (char *group); - /* main.c */ void process_args (int argc, char *argv[]); void initialize_buffers (void); diff --git a/src/idcache.c b/src/idcache.c deleted file mode 100644 index 7e18799..0000000 --- a/src/idcache.c +++ /dev/null @@ -1,197 +0,0 @@ -/* idcache.c -- map user and group IDs, cached for speed - Copyright (C) 1985-2024 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <sys/types.h> -#include <xalloc.h> - -#include <system.h> - -#if defined(STDC_HEADERS) || defined(HAVE_STRING_H) -#include <string.h> -#else -#include <strings.h> -#endif - -#include <unistd.h> -#include "cpiohdr.h" -#include "extern.h" - -struct userid -{ - union - { - uid_t u; - gid_t g; - } id; - char *name; - struct userid *next; -}; - -static struct userid *user_alist; - -/* The members of this list have names not in the local passwd file. */ -static struct userid *nouser_alist; - -/* Translate UID to a login name or a stringified number, - with cache. */ - -char * -getuser (uid_t uid) -{ - register struct userid *tail; - struct passwd *pwent; - - for (tail = user_alist; tail; tail = tail->next) - if (tail->id.u == uid) - return tail->name; - - pwent = getpwuid (uid); - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->id.u = uid; - if (pwent == 0) - { - char nbuf[UINTMAX_STRSIZE_BOUND]; - tail->name = xstrdup (umaxtostr (uid, nbuf)); - } - else - tail->name = xstrdup (pwent->pw_name); - - /* Add to the head of the list, so most recently used is first. */ - tail->next = user_alist; - user_alist = tail; - return tail->name; -} - -/* Translate USER to a UID, with cache. - Return NULL if there is no such user. - (We also cache which user names have no passwd entry, - so we don't keep looking them up.) */ - -uid_t * -getuidbyname (char *user) -{ - register struct userid *tail; - struct passwd *pwent; - - for (tail = user_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *user && !strcmp (tail->name, user)) - return &tail->id.u; - - for (tail = nouser_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *user && !strcmp (tail->name, user)) - return 0; - - pwent = getpwnam (user); - - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->name = xstrdup (user); - - /* Add to the head of the list, so most recently used is first. */ - if (pwent) - { - tail->id.u = pwent->pw_uid; - tail->next = user_alist; - user_alist = tail; - return &tail->id.u; - } - - tail->next = nouser_alist; - nouser_alist = tail; - return 0; -} - -/* Use the same struct as for userids. */ -static struct userid *group_alist; -static struct userid *nogroup_alist; - -/* Translate GID to a group name or a stringified number, - with cache. */ - -char * -getgroup (gid_t gid) -{ - register struct userid *tail; - struct group *grent; - - for (tail = group_alist; tail; tail = tail->next) - if (tail->id.g == gid) - return tail->name; - - grent = getgrgid (gid); - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->id.g = gid; - if (grent == 0) - { - char nbuf[UINTMAX_STRSIZE_BOUND]; - tail->name = xstrdup (umaxtostr (gid, nbuf)); - } - else - tail->name = xstrdup (grent->gr_name); - - /* Add to the head of the list, so most recently used is first. */ - tail->next = group_alist; - group_alist = tail; - return tail->name; -} - -/* Translate GROUP to a UID, with cache. - Return NULL if there is no such group. - (We also cache which group names have no group entry, - so we don't keep looking them up.) */ - -gid_t * -getgidbyname (char *group) -{ - register struct userid *tail; - struct group *grent; - - for (tail = group_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *group && !strcmp (tail->name, group)) - return &tail->id.g; - - for (tail = nogroup_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *group && !strcmp (tail->name, group)) - return 0; - - grent = getgrnam (group); - - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->name = xstrdup (group); - - /* Add to the head of the list, so most recently used is first. */ - if (grent) - { - tail->id.g = grent->gr_gid; - tail->next = group_alist; - group_alist = tail; - return &tail->id.g; - } - - tail->next = nogroup_alist; - nogroup_alist = tail; - return 0; -} diff --git a/src/tar.c b/src/tar.c index 318cbbe..dc0672d 100644 --- a/src/tar.c +++ b/src/tar.c @@ -26,6 +26,7 @@ #include "dstring.h" #include "extern.h" #include <rmt.h> +#include <idcache.h> #include "tarhdr.h" /* Stash the tar linkname in static storage. */ @@ -208,16 +209,20 @@ write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) if (archive_format == arf_ustar) { char *name; + char id_buffer[UINTMAX_STRSIZE_BOUND]; strncpy (tar_hdr->magic, TMAGIC, TMAGLEN); strncpy (tar_hdr->version, TVERSION, TVERSLEN); name = getuser (file_hdr->c_uid); - if (name) - strcpy (tar_hdr->uname, name); + if (name == NULL) + name = umaxtostr (file_hdr->c_uid, id_buffer); + strcpy (tar_hdr->uname, name); + name = getgroup (file_hdr->c_gid); - if (name) - strcpy (tar_hdr->gname, name); + if (name == NULL) + name = umaxtostr (file_hdr->c_gid, id_buffer); + strcpy (tar_hdr->gname, name); TO_OCT (file_hdr, c_rdev_maj, 8, tar_hdr, devmajor); TO_OCT (file_hdr, c_rdev_min, 8, tar_hdr, devminor); -- 2.45.2
>From 448e52ab8613a672b50e2a49578a07a44ed10986 Mon Sep 17 00:00:00 2001 From: Collin Funk <[email protected]> Date: Tue, 6 Aug 2024 21:53:25 -0700 Subject: [PATCH 5/5] maint: Use userspec from Gnulib. * gnulib.modules: Add userspec. * po/POTFILES.in: Add gnu/userspec.c. Remove src/userspec.c. * src/Makefile.am (cpio_SOURCES): Remove userspec.c. * src/extern.h (parse_user_spec): Remove declaration. * src/main.c: Include userspec.h. * src/userspec.c: Remove file. --- gnulib.modules | 1 + po/POTFILES.in | 2 +- src/Makefile.am | 3 +- src/extern.h | 4 - src/main.c | 1 + src/userspec.c | 243 ------------------------------------------------ 6 files changed, 4 insertions(+), 250 deletions(-) delete mode 100644 src/userspec.c diff --git a/gnulib.modules b/gnulib.modules index ee54d2f..6363887 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -30,6 +30,7 @@ stpcpy strerror timespec unlocked-io +userspec xalloc xalloc-die xgetcwd diff --git a/po/POTFILES.in b/po/POTFILES.in index 51d7618..0cc7a16 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -24,6 +24,7 @@ gnu/getopt.c gnu/obstack.c gnu/openat-die.c gnu/quotearg.c +gnu/userspec.c gnu/version-etc.c gnu/xalloc-die.c @@ -41,7 +42,6 @@ src/main.c src/makepath.c src/mt.c src/tar.c -src/userspec.c src/util.c tests/genfile.c diff --git a/src/Makefile.am b/src/Makefile.am index 5ee0e79..77df2e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,8 +36,7 @@ cpio_SOURCES = \ main.c\ tar.c\ util.c\ - makepath.c\ - userspec.c + makepath.c noinst_HEADERS =\ cpio.h\ diff --git a/src/extern.h b/src/extern.h index 0b7fb83..6447359 100644 --- a/src/extern.h +++ b/src/extern.h @@ -151,10 +151,6 @@ int otoa (char *s, unsigned long *n); int is_tar_header (char *buf); int is_tar_filename_too_long (char *name); -/* userspec.c */ -const char *parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid, - char **username_arg, char **groupname_arg); - /* util.c */ void tape_empty_output_buffer (int out_des); void disk_empty_output_buffer (int out_des, bool flush); diff --git a/src/main.c b/src/main.c index d2135c8..7c889db 100644 --- a/src/main.c +++ b/src/main.c @@ -36,6 +36,7 @@ #include <progname.h> #include <closeout.h> +#include <userspec.h> #include "filetypes.h" #include "cpiohdr.h" diff --git a/src/userspec.c b/src/userspec.c deleted file mode 100644 index 43d565c..0000000 --- a/src/userspec.c +++ /dev/null @@ -1,243 +0,0 @@ -/* userspec.c -- Parse a user and group string. - Copyright (C) 1989-2024 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -/* Written by David MacKenzie <[email protected]>. */ - -#include <system.h> -#include <alloca.h> -#include <stdio.h> -#include <ctype.h> -#include <sys/types.h> -#include "cpiohdr.h" -#include "extern.h" - -#ifndef HAVE_ENDPWENT -# define endpwent() -#endif -#ifndef HAVE_ENDGRENT -# define endgrent() -#endif - -/* Perform the equivalent of the statement `dest = strdup (src);', - but obtaining storage via alloca instead of from the heap. */ - -#define V_STRDUP(dest, src) \ - do \ - { \ - int _len = strlen ((src)); \ - (dest) = (char *) alloca (_len + 1); \ - strcpy (dest, src); \ - } \ - while (0) - -/* Return nonzero if STR represents an unsigned decimal integer, - otherwise return 0. */ - -static int -isnumber_p (const char *str) -{ - for (; *str; str++) - if (!isdigit (*str)) - return 0; - return 1; -} - -/* Extract from NAME, which has the form "[user][:.][group]", - a USERNAME, UID U, GROUPNAME, and GID G. - Either user or group, or both, must be present. - If the group is omitted but the ":" or "." separator is given, - use the given user's login group. - - USERNAME and GROUPNAME will be in newly malloc'd memory. - Either one might be NULL instead, indicating that it was not - given and the corresponding numeric ID was left unchanged. - - Return NULL if successful, a static error message string if not. */ - -const char * -parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid, - char **username_arg, char **groupname_arg) -{ - static const char *tired = "virtual memory exhausted"; - const char *error_msg; - char *spec; /* A copy we can write on. */ - struct passwd *pwd; - struct group *grp; - char *g, *u, *separator; - char *groupname; - - error_msg = NULL; - *username_arg = *groupname_arg = NULL; - groupname = NULL; - - V_STRDUP (spec, spec_arg); - - /* Find the separator if there is one. */ - separator = strchr (spec, ':'); - if (separator == NULL) - separator = strchr (spec, '.'); - - /* Replace separator with a NUL. */ - if (separator != NULL) - *separator = '\0'; - - /* Set U and G to non-zero length strings corresponding to user and - group specifiers or to NULL. */ - u = (*spec == '\0' ? NULL : spec); - - g = (separator == NULL || *(separator + 1) == '\0' - ? NULL - : separator + 1); - - if (u == NULL && g == NULL) - return "can not omit both user and group"; - - if (u != NULL) - { - if (*u == '+') - { - pwd = NULL; - ++u; - } - else - pwd = getpwnam (u); - - if (pwd == NULL) - { - if (!isnumber_p (u)) - error_msg = _("invalid user"); - else - { - int use_login_group; - use_login_group = (separator != NULL && g == NULL); - if (use_login_group) - error_msg = _("cannot get the login group of a numeric UID"); - else - *uid = atoi (u); - } - } - else - { - *uid = pwd->pw_uid; - if (g == NULL && separator != NULL) - { - /* A separator was given, but a group was not specified, - so get the login group. */ - *gid = pwd->pw_gid; - grp = getgrgid (pwd->pw_gid); - if (grp == NULL) - { - char nbuf[UINTMAX_STRSIZE_BOUND]; - V_STRDUP (groupname, umaxtostr (pwd->pw_gid, nbuf)); - } - else - { - V_STRDUP (groupname, grp->gr_name); - } - endgrent (); - } - } - endpwent (); - } - - if (g != NULL && error_msg == NULL) - { - /* Explicit group. */ - if (*g == '+') - { - grp = NULL; - ++g; - } - else - grp = getgrnam (g); - - if (grp == NULL) - { - if (!isnumber_p (g)) - error_msg = _("invalid group"); - else - *gid = atoi (g); - } - else - *gid = grp->gr_gid; - endgrent (); /* Save a file descriptor. */ - - if (error_msg == NULL) - V_STRDUP (groupname, g); - } - - if (error_msg == NULL) - { - if (u != NULL) - { - *username_arg = strdup (u); - if (*username_arg == NULL) - error_msg = tired; - } - - if (groupname != NULL && error_msg == NULL) - { - *groupname_arg = strdup (groupname); - if (*groupname_arg == NULL) - { - if (*username_arg != NULL) - { - free (*username_arg); - *username_arg = NULL; - } - error_msg = tired; - } - } - } - - return error_msg; -} - -#ifdef TEST - -#define NULL_CHECK(s) ((s) == NULL ? "(null)" : (s)) - -int -main (int argc, char **argv) -{ - int i; - - for (i = 1; i < argc; i++) - { - const char *e; - char *username, *groupname; - uid_t uid; - gid_t gid; - char *tmp; - - tmp = strdup (argv[i]); - e = parse_user_spec (tmp, &uid, &gid, &username, &groupname); - free (tmp); - printf ("%s: %u %u %s %s %s\n", - argv[i], - (unsigned int) uid, - (unsigned int) gid, - NULL_CHECK (username), - NULL_CHECK (groupname), - NULL_CHECK (e)); - } - - exit (0); -} - -#endif -- 2.45.2
