git: e3a294324944 - stable/13 - pax: remove 4.4BSD compatibility

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Wed, 02 Nov 2022 12:35:51 UTC
The branch stable/13 has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=e3a2943249446df9449c3a9cbf30ce0fb68a29c9

commit e3a2943249446df9449c3a9cbf30ce0fb68a29c9
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2022-09-13 14:26:54 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2022-11-02 09:39:18 +0000

    pax: remove 4.4BSD compatibility
    
    Sponsored by:   Klara, Inc.
    
    (cherry picked from commit 30c30e220af30fbe8896a2bc4769b9ffd7fb43fb)
    
    pax: comment typo fixes from NetBSD / OpenBSD.
    
    Sponsored by:   Klara, Inc.
    
    (cherry picked from commit 0266a5d610be4fb546475934125a037ca5748184)
    
    pax: name all supported formats.
    
    Sponsored by:   Klara, Inc.
    
    (cherry picked from commit a8e8a914456878a67dfc5ef6f917a04be2e6a0c7)
    
    pax: update date parsing code (from OpenBSD)
    
    Sponsored by:   Klara, Inc.
    MFC after:      1 week
    
    (cherry picked from commit d05e43bc0d5705919d057793aaa3e6d3df65f815)
---
 bin/pax/Makefile    |  24 ----------
 bin/pax/ar_io.c     |  26 ++++-------
 bin/pax/ar_subs.c   |   5 ++-
 bin/pax/buf_subs.c  |   2 +-
 bin/pax/cache.c     |   8 ----
 bin/pax/cpio.c      |  36 +--------------
 bin/pax/extern.h    |   2 -
 bin/pax/file_subs.c |   2 +-
 bin/pax/ftree.c     |  25 -----------
 bin/pax/gen_subs.c  |  11 -----
 bin/pax/options.c   |  14 +++---
 bin/pax/pat_rep.c   |  90 -------------------------------------
 bin/pax/pat_rep.h   |   4 --
 bin/pax/pax.1       |  25 ++++++-----
 bin/pax/pax.c       |   2 +-
 bin/pax/sel_subs.c  | 126 ++++++++++++++++++++++++++--------------------------
 bin/pax/sel_subs.h  |   2 +-
 bin/pax/tables.c    |  14 +++---
 bin/pax/tar.c       |  36 +++------------
 19 files changed, 112 insertions(+), 342 deletions(-)

diff --git a/bin/pax/Makefile b/bin/pax/Makefile
index d0772ee49766..500b6f1f7fd0 100644
--- a/bin/pax/Makefile
+++ b/bin/pax/Makefile
@@ -3,30 +3,6 @@
 
 .include <src.opts.mk>
 
-# To install on versions prior to BSD 4.4 the following may have to be
-# defined with CFLAGS +=
-#
-# -DNET2_STAT	Use NET2 or older stat structure. The version of the
-# 		stat structure is easily determined by looking at the
-# 		basic type of an off_t (often defined in the file:
-# 		/usr/include/sys/types.h). If off_t is a long (and is
-# 		NOT A quad) then you must define NET2_STAT.
-# 		This define is important, as if you do have a quad_t
-# 		off_t and define NET2_STAT, pax will compile but will
-# 		NOT RUN PROPERLY.
-#
-# -DNET2_FTS	Use the older NET2 fts. To identify the version,
-# 		examine the file: /usr/include/fts.h. If FTS_COMFOLLOW
-# 		is not defined then you must define NET2_FTS.
-# 		Pax may not compile if this not (un)defined properly.
-#
-# -DNET2_REGEX	Use the older regexp.h not regex.h. The regex version
-# 		is determined by looking at the value returned by
-# 		regexec() (man 3 regexec). If regexec return a 1 for
-# 		success (and NOT a 0 for success) you have the older
-# 		regex routines and must define NET2_REGEX.
-# 		Pax may not compile if this not (un)defined properly.
-
 PACKAGE=runtime
 PROG=   pax
 SRCS=	ar_io.c ar_subs.c buf_subs.c cache.c cpio.c file_subs.c ftree.c \
diff --git a/bin/pax/ar_io.c b/bin/pax/ar_io.c
index 6271944703ff..4128a91e3dc2 100644
--- a/bin/pax/ar_io.c
+++ b/bin/pax/ar_io.c
@@ -206,7 +206,7 @@ ar_open(const char *name)
 	 * set default blksz on read. APPNDs writes rdblksz on the last volume
 	 * On all new archive volumes, we shift to wrblksz (if the user
 	 * specified one, otherwise we will continue to use rdblksz). We
-	 * must to set blocksize based on what kind of device the archive is
+	 * must set blocksize based on what kind of device the archive is
 	 * stored.
 	 */
 	switch(artyp) {
@@ -286,7 +286,7 @@ ar_open(const char *name)
 		break;
 	default:
 		/*
-		 * should never happen, worse case, slow...
+		 * should never happen, worst case, slow...
 		 */
 		blksz = rdblksz = BLKMULT;
 		break;
@@ -386,13 +386,8 @@ ar_close(void)
 	 * could have written anything yet.
 	 */
 	if (frmt == NULL) {
-#	ifdef NET2_STAT
-		(void)fprintf(listf, "%s: unknown format, %lu bytes skipped.\n",
-		    argv0, rdcnt);
-#	else
 		(void)fprintf(listf, "%s: unknown format, %ju bytes skipped.\n",
 		    argv0, (uintmax_t)rdcnt);
-#	endif
 		(void)fflush(listf);
 		flcnt = 0;
 		return;
@@ -403,14 +398,9 @@ ar_close(void)
 		    (unsigned long long)((rdcnt ? rdcnt : wrcnt) / 5120));
 	else if (strcmp(NM_TAR, argv0) != 0)
 		(void)fprintf(listf,
-#	ifdef NET2_STAT
-		    "%s: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n",
-		    argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
-#	else
 		    "%s: %s vol %d, %ju files, %ju bytes read, %ju bytes written.\n",
 		    argv0, frmt->name, arvol-1, (uintmax_t)flcnt,
 		    (uintmax_t)rdcnt, (uintmax_t)wrcnt);
-#	endif
 	(void)fflush(listf);
 	flcnt = 0;
 }
@@ -543,10 +533,10 @@ ar_read(char *buf, int cnt)
 			io_ok = 1;
 			if (res != rdblksz) {
 				/*
-				 * Record size changed. If this is happens on
+				 * Record size changed. If this happens on
 				 * any record after the first, we probably have
 				 * a tape drive which has a fixed record size
-				 * we are getting multiple records in a single
+				 * (we are getting multiple records in a single
 				 * read). Watch out for record blocking that
 				 * violates pax spec (must be a multiple of
 				 * BLKMULT).
@@ -726,7 +716,7 @@ ar_rdsync(void)
 	struct mtop mb;
 
 	/*
-	 * Fail resync attempts at user request (done) or this is going to be
+	 * Fail resync attempts at user request (done) or if this is going to be
 	 * an update/append to an existing archive. If last i/o hit media end,
 	 * we need to go to the next volume not try a resync.
 	 */
@@ -932,12 +922,12 @@ ar_rev(off_t sksz)
 		break;
 	case ISTAPE:
 		/*
-	 	 * Calculate and move the proper number of PHYSICAL tape
+		 * Calculate and move the proper number of PHYSICAL tape
 		 * blocks. If the sksz is not an even multiple of the physical
 		 * tape size, we cannot do the move (this should never happen).
-		 * (We also cannot handler trailers spread over two vols).
+		 * (We also cannot handle trailers spread over two vols).
 		 * get_phys() also makes sure we are in front of the filemark.
-	 	 */
+		 */
 		if ((phyblk = get_phys()) <= 0) {
 			lstrval = -1;
 			return(-1);
diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c
index b18dc3710942..68dbced6917d 100644
--- a/bin/pax/ar_subs.c
+++ b/bin/pax/ar_subs.c
@@ -202,7 +202,7 @@ extract(void)
 
 		/*
 		 * with -u or -D only extract when the archive member is newer
-		 * than the file with the same name in the file system (nos
+		 * than the file with the same name in the file system (no
 		 * test of being the same type is required).
 		 * NOTE: this test is done BEFORE name modifications as
 		 * specified by pax. this operation can be confusing to the
@@ -387,7 +387,8 @@ wr_archive(ARCHD *arcn, int is_app)
 		return;
 
 	/*
-	 * if this not append, and there are no files, we do no write a trailer
+	 * if this is not append, and there are no files, we do not write a
+	 * trailer
 	 */
 	wr_one = is_app;
 
diff --git a/bin/pax/buf_subs.c b/bin/pax/buf_subs.c
index 6d50a280f29c..54c65150b467 100644
--- a/bin/pax/buf_subs.c
+++ b/bin/pax/buf_subs.c
@@ -199,7 +199,7 @@ cp_start(void)
  *	A major problem is rewriting this last record. For archives stored
  *	on disk files, this is trivial. However, many devices are really picky
  *	about the conditions under which they will allow a write to occur.
- *	Often devices restrict the conditions where writes can be made writes,
+ *	Often devices restrict the conditions where writes can be made,
  *	so it may not be feasible to append archives stored on all types of
  *	devices.
  * Return:
diff --git a/bin/pax/cache.c b/bin/pax/cache.c
index 980d7bccc217..5e55e70be851 100644
--- a/bin/pax/cache.c
+++ b/bin/pax/cache.c
@@ -211,12 +211,8 @@ name_uid(uid_t uid, int frc)
 			return("");
 		ptr->uid = uid;
 		ptr->valid = INVALID;
-#		ifdef NET2_STAT
-		(void)snprintf(ptr->name, sizeof(ptr->name), "%u", uid);
-#		else
 		(void)snprintf(ptr->name, sizeof(ptr->name), "%lu",
 			       (unsigned long)uid);
-#		endif
 		if (frc == 0)
 			return("");
 	} else {
@@ -282,12 +278,8 @@ name_gid(gid_t gid, int frc)
 			return("");
 		ptr->gid = gid;
 		ptr->valid = INVALID;
-#		ifdef NET2_STAT
-		(void)snprintf(ptr->name, sizeof(ptr->name), "%u", gid);
-#		else
 		(void)snprintf(ptr->name, sizeof(ptr->name), "%lu",
 			       (unsigned long)gid);
-#		endif
 		if (frc == 0)
 			return("");
 	} else {
diff --git a/bin/pax/cpio.c b/bin/pax/cpio.c
index a47b7fd7a823..4aea03b47e34 100644
--- a/bin/pax/cpio.c
+++ b/bin/pax/cpio.c
@@ -149,7 +149,7 @@ com_rd(ARCHD *arcn)
 }
 
 /*
- * cpio_end_wr()
+ * cpio_endwr()
  *	write the special file with the name trailer in the proper format
  * Return:
  *	result of the write of the trailer from the cpio specific write func
@@ -216,13 +216,8 @@ rd_ln_nm(ARCHD *arcn)
 	 */
 	if ((arcn->sb.st_size == 0) ||
 	    ((size_t)arcn->sb.st_size >= sizeof(arcn->ln_name))) {
-#		ifdef NET2_STAT
-		paxwarn(1, "Cpio link name length is invalid: %lu",
-		    arcn->sb.st_size);
-#		else
 		paxwarn(1, "Cpio link name length is invalid: %ju",
 		    (uintmax_t)arcn->sb.st_size);
-#		endif
 		return(-1);
 	}
 
@@ -302,21 +297,11 @@ cpio_rd(ARCHD *arcn, char *buf)
 	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
 	    OCT);
 	arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT);
-#ifdef NET2_STAT
-	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime),
-	    OCT);
-#else
 	arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime, sizeof(hd->c_mtime),
 	    OCT);
-#endif
 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
-#ifdef NET2_STAT
-	arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize),
-	    OCT);
-#else
 	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize),
 	    OCT);
-#endif
 
 	/*
 	 * check name size and if valid, read in the name of this entry (name
@@ -411,13 +396,8 @@ cpio_wr(ARCHD *arcn)
 		/*
 		 * set data size for file data
 		 */
-#		ifdef NET2_STAT
-		if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
-		    sizeof(hd->c_filesize), OCT)) {
-#		else
 		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
 		    sizeof(hd->c_filesize), OCT)) {
-#		endif
 			paxwarn(1,"File is too large for cpio format %s",
 			    arcn->org_name);
 			return(1);
@@ -593,19 +573,10 @@ vcpio_rd(ARCHD *arcn, char *buf)
 	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX);
 	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX);
 	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX);
-#ifdef NET2_STAT
-	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX);
-#else
 	arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime,sizeof(hd->c_mtime),HEX);
-#endif
 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
-#ifdef NET2_STAT
-	arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,
-	    sizeof(hd->c_filesize), HEX);
-#else
 	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,
 	    sizeof(hd->c_filesize), HEX);
-#endif
 	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
 	    HEX);
 	devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX);
@@ -740,13 +711,8 @@ vcpio_wr(ARCHD *arcn)
 		 * much to pad.
 		 */
 		arcn->pad = VCPIO_PAD(arcn->sb.st_size);
-#		ifdef NET2_STAT
-		if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
-		    sizeof(hd->c_filesize), HEX)) {
-#		else
 		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
 		    sizeof(hd->c_filesize), HEX)) {
-#		endif
 			paxwarn(1,"File is too large for sv4cpio format %s",
 			    arcn->org_name);
 			return(1);
diff --git a/bin/pax/extern.h b/bin/pax/extern.h
index ec171f2d177c..12b7fe162a6e 100644
--- a/bin/pax/extern.h
+++ b/bin/pax/extern.h
@@ -169,10 +169,8 @@ void ls_tty(ARCHD *);
 int l_strncpy(char *, const char *, int);
 u_long asc_ul(char *, int, int);
 int ul_asc(u_long, char *, int, int);
-#ifndef NET2_STAT
 u_quad_t asc_uqd(char *, int, int);
 int uqd_asc(u_quad_t, char *, int, int);
-#endif
 
 /*
  * getoldopt.c
diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
index 31fb9112c586..8976d055e238 100644
--- a/bin/pax/file_subs.c
+++ b/bin/pax/file_subs.c
@@ -623,7 +623,7 @@ chk_path( char *name, uid_t st_uid, gid_t st_gid)
  *	non-zero we force these times to be set even if the user did not
  *	request access and/or modification time preservation (this is also
  *	used by -t to reset access times).
- *	When ign is zero, only those times the user has asked for are set, the
+ *	When frc is zero, only those times the user has asked for are set, the
  *	other ones are left alone. We do not assume the un-documented feature
  *	of many lutimes() implementations that consider a 0 time value as a do
  *	not set request.
diff --git a/bin/pax/ftree.c b/bin/pax/ftree.c
index 26df8164bc2d..da0d72998975 100644
--- a/bin/pax/ftree.c
+++ b/bin/pax/ftree.c
@@ -115,11 +115,7 @@ ftree_start(void)
 	else
 		ftsopts |= FTS_PHYSICAL;
 	if (Hflag)
-#	ifdef NET2_FTS
-		paxwarn(0, "The -H flag is not supported on this version");
-#	else
 		ftsopts |= FTS_COMFOLLOW;
-#	endif
 	if (Xflag)
 		ftsopts |= FTS_XDEV;
 
@@ -402,13 +398,8 @@ next_file(ARCHD *arcn)
 			 * remember to force the time (this is -t on a read
 			 * directory, not a created directory).
 			 */
-#			ifdef NET2_FTS
-			if (!tflag || (get_atdir(ftent->fts_statb.st_dev,
-			    ftent->fts_statb.st_ino, &mtime, &atime) < 0))
-#			else
 			if (!tflag || (get_atdir(ftent->fts_statp->st_dev,
 			    ftent->fts_statp->st_ino, &mtime, &atime) < 0))
-#			endif
 				continue;
 			set_ftime(ftent->fts_path, mtime, atime, 1);
 			continue;
@@ -419,28 +410,16 @@ next_file(ARCHD *arcn)
 			paxwarn(1,"File system cycle found at %s",ftent->fts_path);
 			continue;
 		case FTS_DNR:
-#			ifdef NET2_FTS
-			syswarn(1, errno,
-#			else
 			syswarn(1, ftent->fts_errno,
-#			endif
 			    "Unable to read directory %s", ftent->fts_path);
 			continue;
 		case FTS_ERR:
-#			ifdef NET2_FTS
-			syswarn(1, errno,
-#			else
 			syswarn(1, ftent->fts_errno,
-#			endif
 			    "File system traversal error");
 			continue;
 		case FTS_NS:
 		case FTS_NSOK:
-#			ifdef NET2_FTS
-			syswarn(1, errno,
-#			else
 			syswarn(1, ftent->fts_errno,
-#			endif
 			    "Unable to access %s", ftent->fts_path);
 			continue;
 		}
@@ -453,11 +432,7 @@ next_file(ARCHD *arcn)
 		arcn->pad = 0;
 		arcn->ln_nlen = 0;
 		arcn->ln_name[0] = '\0';
-#		ifdef NET2_FTS
-		arcn->sb = ftent->fts_statb;
-#		else
 		arcn->sb = *(ftent->fts_statp);
-#		endif
 
 		/*
 		 * file type based set up and copy into the arcn struct
diff --git a/bin/pax/gen_subs.c b/bin/pax/gen_subs.c
index f91aaff7b809..b8cb437405a7 100644
--- a/bin/pax/gen_subs.c
+++ b/bin/pax/gen_subs.c
@@ -119,19 +119,10 @@ ls_list(ARCHD *arcn, time_t now, FILE *fp)
 	 * print device id's for devices, or sizes for other nodes
 	 */
 	if ((arcn->type == PAX_CHR) || (arcn->type == PAX_BLK))
-#		ifdef NET2_STAT
-		(void)fprintf(fp, "%4u,%4u ", MAJOR(sbp->st_rdev),
-		    MINOR(sbp->st_rdev));
-#		else
 		(void)fprintf(fp, "%4lu,%4lu ", (unsigned long)MAJOR(sbp->st_rdev),
 		    (unsigned long)MINOR(sbp->st_rdev));
-#		endif
 	else {
-#		ifdef NET2_STAT
-		(void)fprintf(fp, "%9lu ", sbp->st_size);
-#		else
 		(void)fprintf(fp, "%9ju ", (uintmax_t)sbp->st_size);
-#		endif
 	}
 
 	/*
@@ -300,7 +291,6 @@ ul_asc(u_long val, char *str, int len, int base)
 	return(0);
 }
 
-#ifndef NET2_STAT
 /*
  * asc_uqd()
  *	convert hex/octal character string into a u_quad_t. We do not have to
@@ -396,4 +386,3 @@ uqd_asc(u_quad_t val, char *str, int len, int base)
 		return(-1);
 	return(0);
 }
-#endif
diff --git a/bin/pax/options.c b/bin/pax/options.c
index 4ec02d80d55c..1366bb75eef6 100644
--- a/bin/pax/options.c
+++ b/bin/pax/options.c
@@ -87,7 +87,7 @@ char *chdname;
 
 #define GZIP_CMD	"gzip"		/* command to run as gzip */
 #define COMPRESS_CMD	"compress"	/* command to run as compress */
-#define BZIP2_CMD	"bzip2"		/* command to run as gzip */
+#define BZIP2_CMD	"bzip2"		/* command to run as bzip2 */
 
 /*
  *	Format specific routine table - MUST BE IN SORTED ORDER BY NAME
@@ -131,17 +131,18 @@ FSUB fsub[] = {
 };
 #define F_OCPIO	0	/* format when called as cpio -6 */
 #define F_ACPIO	1	/* format when called as cpio -c */
+#define F_SCPIO	2	/* format when called with -x sv4cpio */
 #define F_CPIO	3	/* format when called as cpio */
 #define F_OTAR	4	/* format when called as tar -o */
 #define F_TAR	5	/* format when called as tar */
-#define DEFLT	5	/* default write format from list above */
+#define DEFLT	F_TAR	/* default write format from list above */
 
 /*
  * ford is the archive search order used by get_arc() to determine what kind
  * of archive we are dealing with. This helps to properly id  archive formats
  * some formats may be subsets of others....
  */
-int ford[] = {5, 4, 3, 2, 1, 0, -1 };
+int ford[] = {F_TAR, F_OTAR, F_CPIO, F_SCPIO, F_ACPIO, F_OCPIO, -1 };
 
 /*
  * options()
@@ -308,7 +309,7 @@ pax_options(int argc, char **argv)
 					break;
 				case 'p':
 					/*
-					 * preserver file mode bits
+					 * preserve file mode bits
 					 */
 					pmode = 1;
 					break;
@@ -1434,13 +1435,8 @@ str_offt(char *val)
 	char *expr;
 	off_t num, t;
 
-#	ifdef NET2_STAT
-	num = strtol(val, &expr, 0);
-	if ((num == LONG_MAX) || (num <= 0) || (expr == val))
-#	else
 	num = strtoq(val, &expr, 0);
 	if ((num == QUAD_MAX) || (num <= 0) || (expr == val))
-#	endif
 		return(0);
 
 	switch(*expr) {
diff --git a/bin/pax/pat_rep.c b/bin/pax/pat_rep.c
index 0dfa630050ea..ee683341d099 100644
--- a/bin/pax/pat_rep.c
+++ b/bin/pax/pat_rep.c
@@ -46,11 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#ifdef NET2_REGEX
-#include <regexp.h>
-#else
 #include <regex.h>
-#endif
 #include "pax.h"
 #include "pat_rep.h"
 #include "extern.h"
@@ -73,11 +69,7 @@ static int tty_rename(ARCHD *);
 static int fix_path(char *, int *, char *, int);
 static int fn_match(char *, char *, char **);
 static char * range_match(char *, int);
-#ifdef NET2_REGEX
-static int resub(regexp *, char *, char *, char *);
-#else
 static int resub(regex_t *, regmatch_t *, char *, char *, char *, char *);
-#endif
 
 /*
  * rep_add()
@@ -101,10 +93,8 @@ rep_add(char *str)
 	char *pt1;
 	char *pt2;
 	REPLACE *rep;
-#	ifndef NET2_REGEX
 	int res;
 	char rebuf[BUFSIZ];
-#	endif
 
 	/*
 	 * throw out the bad parameters
@@ -133,13 +123,9 @@ rep_add(char *str)
 	}
 
 	*pt1 = '\0';
-#	ifdef NET2_REGEX
-	if ((rep->rcmp = regcomp(str+1)) == NULL) {
-#	else
 	if ((res = regcomp(&(rep->rcmp), str+1, 0)) != 0) {
 		regerror(res, &(rep->rcmp), rebuf, sizeof(rebuf));
 		paxwarn(1, "%s while compiling regular expression %s", rebuf, str);
-#	endif
 		free(rep);
 		return(-1);
 	}
@@ -151,11 +137,7 @@ rep_add(char *str)
 	 */
 	*pt1++ = *str;
 	if ((pt2 = strchr(pt1, *str)) == NULL) {
-#		ifdef NET2_REGEX
-		free(rep->rcmp);
-#		else
 		regfree(&rep->rcmp);
-#		endif
 		free(rep);
 		paxwarn(1, "Invalid replacement string %s", str);
 		return(-1);
@@ -180,11 +162,7 @@ rep_add(char *str)
 			rep->flgs  |= PRNT;
 			break;
 		default:
-#			ifdef NET2_REGEX
-			free(rep->rcmp);
-#			else
 			regfree(&rep->rcmp);
-#			endif
 			free(rep);
 			*pt1 = *str;
 			paxwarn(1, "Invalid replacement string option %s", str);
@@ -865,9 +843,7 @@ rep_name(char *name, int *nlen, int prnt)
 	char *rpt;
 	int found = 0;
 	int res;
-#	ifndef NET2_REGEX
 	regmatch_t pm[MAXSUBEXP];
-#	endif
 	char nname[PAXPATHLEN+1];	/* final result of all replacements */
 	char buf1[PAXPATHLEN+1];	/* where we work on the name */
 
@@ -894,11 +870,7 @@ rep_name(char *name, int *nlen, int prnt)
 			 * check for a successful substitution, if not go to
 			 * the next pattern, or cleanup if we were global
 			 */
-#			ifdef NET2_REGEX
-			if (regexec(pt->rcmp, inpt) == 0)
-#			else
 			if (regexec(&(pt->rcmp), inpt, MAXSUBEXP, pm, 0) != 0)
-#			endif
 				break;
 
 			/*
@@ -909,11 +881,7 @@ rep_name(char *name, int *nlen, int prnt)
 			 * do not create a string too long).
 			 */
 			found = 1;
-#			ifdef NET2_REGEX
-			rpt = pt->rcmp->startp[0];
-#			else
 			rpt = inpt + pm[0].rm_so;
-#			endif
 
 			while ((inpt < rpt) && (outpt < endpt))
 				*outpt++ = *inpt++;
@@ -926,12 +894,8 @@ rep_name(char *name, int *nlen, int prnt)
 			 * replacement string and place it the prefix in the
 			 * final output. If we have problems, skip it.
 			 */
-#			ifdef NET2_REGEX
-			if ((res = resub(pt->rcmp,pt->nstr,outpt,endpt)) < 0) {
-#			else
 			if ((res = resub(&(pt->rcmp),pm,inpt,pt->nstr,outpt,endpt))
 			    < 0) {
-#			endif
 				if (prnt)
 					paxwarn(1, "Replacement name error %s",
 					    name);
@@ -949,11 +913,7 @@ rep_name(char *name, int *nlen, int prnt)
 			 * the final result. Make sure we do not overrun the
 			 * output buffer
 			 */
-#			ifdef NET2_REGEX
-			inpt = pt->rcmp->endp[0];
-#			else
 			inpt += pm[0].rm_eo - pm[0].rm_so;
-#			endif
 
 			if ((outpt == endpt) || (*inpt == '\0'))
 				break;
@@ -1012,55 +972,6 @@ rep_name(char *name, int *nlen, int prnt)
 	return(0);
 }
 
-#ifdef NET2_REGEX
-/*
- * resub()
- *	apply the replacement to the matched expression. expand out the old
- * 	style ed(1) subexpression expansion.
- * Return:
- *	-1 if error, or the number of characters added to the destination.
- */
-
-static int
-resub(regexp *prog, char *src, char *dest, char *destend)
-{
-	char *spt;
-	char *dpt;
-	char c;
-	int no;
-	int len;
-
-	spt = src;
-	dpt = dest;
-	while ((dpt < destend) && ((c = *spt++) != '\0')) {
-		if (c == '&')
-			no = 0;
-		else if ((c == '\\') && (*spt >= '0') && (*spt <= '9'))
-			no = *spt++ - '0';
-		else {
- 			if ((c == '\\') && ((*spt == '\\') || (*spt == '&')))
- 				c = *spt++;
- 			*dpt++ = c;
-			continue;
-		}
- 		if ((prog->startp[no] == NULL) || (prog->endp[no] == NULL) ||
-		    ((len = prog->endp[no] - prog->startp[no]) <= 0))
-			continue;
-
-		/*
-		 * copy the subexpression to the destination.
-		 * fail if we run out of space or the match string is damaged
-		 */
-		if (len > (destend - dpt))
-			len = destend - dpt;
-		if (l_strncpy(dpt, prog->startp[no], len) != len)
-			return(-1);
-		dpt += len;
-	}
-	return(dpt - dest);
-}
-
-#else
 
 /*
  * resub()
@@ -1127,4 +1038,3 @@ resub(regex_t *rp, regmatch_t *pm, char *orig, char *src, char *dest,
 	}
 	return(dpt - dest);
 }
-#endif
diff --git a/bin/pax/pat_rep.h b/bin/pax/pat_rep.h
index 7def28d36e30..e28064e6a08e 100644
--- a/bin/pax/pat_rep.h
+++ b/bin/pax/pat_rep.h
@@ -41,11 +41,7 @@
  */
 typedef struct replace {
 	char		*nstr;	/* the new string we will substitute with */
-#	ifdef NET2_REGEX
-	regexp		*rcmp;	/* compiled regular expression used to match */
-#	else
 	regex_t		rcmp;	/* compiled regular expression used to match */
-#	endif
 	int		flgs;	/* print conversions? global in operation?  */
 #define	PRNT		0x1
 #define	GLOB		0x2
diff --git a/bin/pax/pax.1 b/bin/pax/pax.1
index 2cc7a694a710..f3db4847cba7 100644
--- a/bin/pax/pax.1
+++ b/bin/pax/pax.1
@@ -33,7 +33,7 @@
 .\"	@(#)pax.1	8.4 (Berkeley) 4/18/94
 .\" $FreeBSD$
 .\"
-.Dd December 29, 2018
+.Dd October 19, 2022
 .Dt PAX 1
 .Os
 .Sh NAME
@@ -933,28 +933,31 @@ changed during a specified time range will be archived).
 A time range is made up of six different fields and each field must contain two
 digits.
 The format is:
-.Dl [yy[mm[dd[hh]]]]mm[.ss]
+.Pp
+.Dl [[[[[cc]yy]mm]dd]HH]MM[.SS]
+.Pp
 Where
-.Cm yy
+.Ar cc
+is the first two digits of the year (the century),
+.Ar yy
 is the last two digits of the year,
 the first
-.Cm mm
+.Ar mm
 is the month (from 01 to 12),
-.Cm dd
+.Ar dd
 is the day of the month (from 01 to 31),
-.Cm hh
+.Ar HH
 is the hour of the day (from 00 to 23),
-the second
-.Cm mm
+.Ar MM
 is the minute (from 00 to 59),
 and
-.Cm ss
+.Ar SS
 is the seconds (from 00 to 59).
 The minute field
-.Cm mm
+.Ar MM
 is required, while the other fields are optional and must be added in the
 following order:
-.Dl Cm hh , dd , mm , yy .
+.Ar HH , dd , mm , yy , cc .
 The
 .Cm ss
 field may be added independently of the other fields.
diff --git a/bin/pax/pax.c b/bin/pax/pax.c
index 4f7456f31a78..3c3ba345e3cb 100644
--- a/bin/pax/pax.c
+++ b/bin/pax/pax.c
@@ -392,7 +392,7 @@ gen_init(void)
 	/*
 	 * signal handling to reset stored directory times and modes. Since
 	 * we deal with broken pipes via failed writes we ignore it. We also
-	 * deal with any file size limit thorough failed writes. Cpu time
+	 * deal with any file size limit through failed writes. Cpu time
 	 * limits are caught and a cleanup is forced.
 	 */
 	if ((sigemptyset(&s_mask) < 0) || (sigaddset(&s_mask, SIGTERM) < 0) ||
diff --git a/bin/pax/sel_subs.c b/bin/pax/sel_subs.c
index 4c0d09e4eb7f..7ef5bec523a5 100644
--- a/bin/pax/sel_subs.c
+++ b/bin/pax/sel_subs.c
@@ -44,17 +44,20 @@ __FBSDID("$FreeBSD$");
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/stat.h>
-#include <pwd.h>
+
+#include <ctype.h>
 #include <grp.h>
+#include <pwd.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <strings.h>
-#include <stdlib.h>
+
 #include "pax.h"
 #include "sel_subs.h"
 #include "extern.h"
 
-static int str_sec(char *, time_t *);
+static int str_sec(const char *, time_t *);
 static int usr_match(ARCHD *);
 static int grp_match(ARCHD *);
 static int trng_match(ARCHD *);
@@ -89,7 +92,7 @@ sel_chk(ARCHD *arcn)
  * User/group selection routines
  *
  * Routines to handle user selection of files based on the file uid/gid. To
- * add an entry, the user supplies either then name or the uid/gid starting with
+ * add an entry, the user supplies either the name or the uid/gid starting with
  * a # on the command line. A \# will escape the #.
  */
 
@@ -134,11 +137,7 @@ usr_add(char *str)
 		}
 		uid = (uid_t)pw->pw_uid;
 	} else
-#		ifdef NET2_STAT
-		uid = (uid_t)atoi(str+1);
-#		else
 		uid = (uid_t)strtoul(str+1, NULL, 10);
-#		endif
 	endpwent();
 
 	/*
@@ -235,11 +234,7 @@ grp_add(char *str)
 		}
 		gid = gr->gr_gid;
 	} else
-#		ifdef NET2_STAT
-		gid = (gid_t)atoi(str+1);
-#		else
 		gid = (gid_t)strtoul(str+1, NULL, 10);
-#		endif
 	endgrent();
 
 	/*
@@ -317,7 +312,7 @@ grp_match(ARCHD *arcn)
  * trng_add()
  *	add a time range match to the time range list.
  *	This is a non-standard pax option. Lower and upper ranges are in the
- *	format: [yy[mm[dd[hh]]]]mm[.ss] and are comma separated.
+ *	format: [[[[[cc]yy]mm]dd]HH]MM[.SS] and are comma separated.
  *	Time ranges are based on current time, so 1234 would specify a time of
  *	12:34 today.
  * Return:
@@ -454,7 +449,7 @@ trng_add(char *str)
 	return(0);
 
     out:
-	paxwarn(1, "Time range format is: [yy[mm[dd[hh]]]]mm[.ss][/[c][m]]");
+	paxwarn(1, "Time range format is: [[[[[cc]yy]mm]dd]HH]MM[.SS][/[c][m]]");
 	return(-1);
 }
 
@@ -528,80 +523,87 @@ trng_match(ARCHD *arcn)
 
 /*
  * str_sec()
- *	Convert a time string in the format of [yy[mm[dd[hh]]]]mm[.ss] to gmt
- *	seconds. Tval already has current time loaded into it at entry.
+ *	Convert a time string in the format of [[[[[cc]yy]mm]dd]HH]MM[.SS] to
+ *	seconds UTC. Tval already has current time loaded into it at entry.
  * Return:
  *	0 if converted ok, -1 otherwise
  */
 
 static int
-str_sec(char *str, time_t *tval)
+str_sec(const char *p, time_t *tval)
 {
 	struct tm *lt;
-	char *dot = NULL;
+	const char *dot, *t;
+	size_t len;
+	int bigyear;
+	int yearset;
+
+	yearset = 0;
+	len = strlen(p);
+
+	for (t = p, dot = NULL; *t; ++t) {
+		if (isdigit((unsigned char)*t))
+			continue;
+		if (*t == '.' && dot == NULL) {
+			dot = t;
+			continue;
+		}
+		return(-1);
+	}
 
 	lt = localtime(tval);
-	if ((dot = strchr(str, '.')) != NULL) {
-		/*
-		 * seconds (.ss)
-		 */
-		*dot++ = '\0';
-		if (strlen(dot) != 2)
+
+	if (dot != NULL) {			/* .SS */
+		if (strlen(++dot) != 2)
 			return(-1);
-		if ((lt->tm_sec = ATOI2(dot)) > 61)
+		lt->tm_sec = ATOI2(dot);
+		if (lt->tm_sec > 61)
 			return(-1);
+		len -= 3;
 	} else
 		lt->tm_sec = 0;
 
-	switch (strlen(str)) {
-	case 10:
-		/*
-		 * year (yy)
-		 * watch out for year 2000
-		 */
-		if ((lt->tm_year = ATOI2(str)) < 69)
-			lt->tm_year += 100;
-		str += 2;
+	switch (len) {
+	case 12:				/* cc */
+		bigyear = ATOI2(p);
+		lt->tm_year = (bigyear * 100) - 1900;
+		yearset = 1;
 		/* FALLTHROUGH */
-	case 8:
-		/*
-		 * month (mm)
-		 * watch out months are from 0 - 11 internally
-		 */
-		if ((lt->tm_mon = ATOI2(str)) > 12)
+	case 10:				/* yy */
+		if (yearset) {
+			lt->tm_year += ATOI2(p);
+		} else {
+			lt->tm_year = ATOI2(p);
+			if (lt->tm_year < 69)		/* hack for 2000 ;-} */
+				lt->tm_year += (2000 - 1900);
+		}
+		/* FALLTHROUGH */
+	case 8:					/* mm */
+		lt->tm_mon = ATOI2(p);
+		if ((lt->tm_mon > 12) || !lt->tm_mon)
 			return(-1);
-		--lt->tm_mon;
-		str += 2;
*** 215 LINES SKIPPED ***