Index: star-1.5/star/pax.c
===================================================================
--- star-1.5.orig/star/pax.c
+++ star-1.5/star/pax.c
@@ -154,7 +154,7 @@ gargs(ac, av)
 				&paxnflag,		/* -n */
 				&paxopts,		/* -o */
 				getpriv, NULL,		/* -p */
-				parsesubst, &do_subst,	/* -s */
+				paxpsubst, &do_subst,	/* -s */
 				&paxtflag,		/* -t */
 				&paxuflag,		/* -u */
 				&verbose,		/* -v */
Index: star-1.5/star/star.c
===================================================================
--- star-1.5.orig/star/star.c
+++ star-1.5/star/star.c
@@ -1142,7 +1142,7 @@ xusage(ret)
 	error("\t-dodesc\t\tdo descend directories found in a list= file\n");
 	error("\tpattern=p,pat=p\tset matching pattern\n");
 	error("\t-match-tree\tdo not scan the content of non matching dirs in create mode\n");
-	error("\ts=replstr\tApply ed like pattern substitution -s /old/new/gp on filenames\n");
+	error("\ts=replstr\tApply change(1) like pattern substitution -s /old/new/gp on filenames\n");
 	error("\tlevel=dumplevel\tset current incremental dump level\n");
 	error("\t-cumulative\tmake a cumulative incremental dump (relative to same level)\n");
 	error("\ttardumps=name\tset file name for tar dump dates, default is %s\n", dumpdates);
@@ -1466,7 +1466,9 @@ BOOL	Ointeractive	 = FALSE;
 				&errflag, &dchangeflag,
 				&prinodes,
 				&diruid, &dirgid, &u_mask,
-				parsesubst, &do_subst, &archive) < 0) {
+				parsesubst, &do_subst,
+				paxpsubst, &do_subst,
+				&archive) < 0) {
 		errmsgno(EX_BAD, "Bad Option: %s.\n", av[0]);
 		susage(EX_BAD);
 	}
Index: star-1.5/star/starsubs.h
===================================================================
--- star-1.5.orig/star/starsubs.h
+++ star-1.5/star/starsubs.h
@@ -427,6 +427,7 @@ extern	BOOL	star_darchive	__PR((char *ar
 /*
  * subst.c
  */
+extern	int	paxpsubst	__PR((char *cmd, BOOL *arg));
 extern	int	parsesubst	__PR((char *cmd, BOOL *arg));
 #ifdef _STAR_H
 extern	BOOL	subst		__PR((FINFO *info));
Index: star-1.5/star/subst.c
===================================================================
--- star-1.5.orig/star/subst.c
+++ star-1.5/star/subst.c
@@ -29,15 +29,26 @@ static	char sccsid[] =
 #include <schily/schily.h>
 
 #include <schily/patmatch.h>
+#ifdef	HAVE_REGEX_H
+#include <regex.h>
+#endif
 
 #include "star.h"
 #include "starsubs.h"
 
+EXPORT	int	paxpsubst	__PR((char *cmd, BOOL *arg));
 EXPORT	int	parsesubst	__PR((char *cmd, BOOL *arg));
+LOCAL	int	_parsesubst	__PR((char *cmd, BOOL *arg, BOOL paxmode));
 EXPORT	BOOL	subst		__PR((FINFO *info));
 LOCAL	char	*substitute	__PR((char *from, long fromlen, int idx, char *to, long tolen));
 LOCAL	BOOL	simpleto	__PR((char *s, long len));
-LOCAL	int	catsub		__PR((char *here, char *old, long oldlen, char *to, long tolen, char *limit));
+#ifdef	HAVE_REGEX_H
+LOCAL	int	catsub		__PR((char *here, char *old, long oldlen,
+					char *to, long tolen, char *limit, regmatch_t *));
+#else
+LOCAL	int	catsub		__PR((char *here, char *old, long oldlen,
+					char *to, long tolen, char *limit));
+#endif
 EXPORT	BOOL	ia_change	__PR((TCB *ptb, FINFO *info));
 LOCAL	BOOL	pax_change	__PR((TCB *ptb, FINFO *info));
 
@@ -52,6 +63,7 @@ LOCAL	int	*aux[NPAT];
 LOCAL	int	alt[NPAT];
 LOCAL	int	*state;
 LOCAL	Int32_t	substcnt[NPAT];
+LOCAL	char	isreg[NPAT];	/* Whether we use sed(1) or change(1) style */
 
 extern	FILE	*tty;
 extern	FILE	*vpr;
@@ -64,11 +76,43 @@ extern	BOOL	paxinteract;
 /*
  * This is the command line parser for tar/pax substitution commands.
  * Syntax is: -s '/old/new/v'
+ * Supporting sed(1) like substitutions.
+ */
+EXPORT int
+paxpsubst(cmd, arg)
+	char	*cmd;		/* The subst command string		*/
+	BOOL	*arg;		/* Set to TRUE if we have a valid stubst */
+{
+#ifdef	HAVE_REGEX_H
+	return (_parsesubst(cmd, arg, TRUE));
+#else
+	return (_parsesubst(cmd, arg, FALSE));
+#endif
+}
+
+/*
+ * This is the command line parser for tar/pax substitution commands.
+ * Syntax is: -s '/old/new/v'
+ * Supporting change(1) like substitutions.
  */
 EXPORT int
 parsesubst(cmd, arg)
-	char	*cmd;
-	BOOL	*arg;
+	char	*cmd;		/* The subst command string		*/
+	BOOL	*arg;		/* Set to TRUE if we have a valid stubst */
+{
+	return (_parsesubst(cmd, arg, FALSE));
+}
+
+/*
+ * This is the command line parser for tar/pax substitution commands.
+ * Syntax is: -s '/old/new/v'
+ * Supporting both variants of the substitutions.
+ */
+LOCAL int
+_parsesubst(cmd, arg, paxmode)
+	char	*cmd;		/* The subst command string		*/
+	BOOL	*arg;		/* Set to TRUE if we have a valid stubst */
+	BOOL	paxmode;	/* Whether to use sed(1) instead of change(1) */
 {
 	register char	*from;
 	register char	*to;
@@ -144,11 +188,32 @@ parsesubst(cmd, arg)
 	if (fromlen > maxplen)
 		maxplen = fromlen;
 
-	aux[npat] = __malloc(fromlen*sizeof (int), "compiled subst pattern");
-	if ((alt[npat] = patcompile(pat[npat], patlen[npat], aux[npat])) == 0) {
-		comerrno(EX_BAD, "Bad pattern: '%s'.\n", pat[npat]);
-		return (-2);
+	if (paxmode) {
+#ifdef	HAVE_REGEX_H
+		int	ret;
+
+		aux[npat] = __malloc(sizeof (regex_t),
+					"compiled subst pattern");
+		ret = regcomp((regex_t *) aux[npat], (char *)pat[npat], 0);
+		if (ret != 0) {
+			char	eb[1024];
+
+			regerror(ret, (regex_t *) aux[npat], eb, sizeof (eb));
+			comerrno(EX_BAD, "Bad pattern: '%s'. %s\n",
+				pat[npat], eb);
+			return (-2);
+		}
+#endif
+	} else {
+		aux[npat] = __malloc(fromlen*sizeof (int),
+					"compiled subst pattern");
+		if ((alt[npat] = patcompile(pat[npat], patlen[npat],
+						aux[npat])) == 0) {
+			comerrno(EX_BAD, "Bad pattern: '%s'.\n", pat[npat]);
+			return (-2);
+		}
 	}
+	isreg[npat] = paxmode;
 
 	if (printsubst)
 		count *= -1;
@@ -213,10 +278,19 @@ substitute(from, fromlen, idx, to, tolen
 	char	*string;
 	int	slen;
 	BOOL	didmatch = FALSE;
+	BOOL	paxmode;
+#ifdef	HAVE_REGEX_H
+	regmatch_t	mat[10];
+	regmatch_t	*matp;
+	regex_t		*re = (regex_t *) aux[idx];
+#endif
 	char	*limit = &new[PATH_MAX];
 
 	if (fromlen == 0)
 		return (NULL);
+
+	paxmode = isreg[idx];
+
 	tosimple = simpleto(to, tolen);
 
 	string = from;
@@ -230,6 +304,18 @@ substitute(from, fromlen, idx, to, tolen
 		 * Search the next occurence of the pattern in the 'from' string.
 		 */
 		while (*string != '\0') {
+#ifdef	HAVE_REGEX_H
+			matp = NULL;
+			if (paxmode) {
+				if (regexec(re, string, 10, mat, 0) != 0) {
+					string++;
+					slen--;
+					continue;
+				}
+				end = string + mat[0].rm_eo;
+				matp = mat;
+			} else
+#endif
 			if ((end = (char *)patmatch(pat[idx], aux[idx],
 			    (Uchar *)string, 0, slen, alt[idx],
 			    state)) == NULL) {
@@ -238,6 +324,7 @@ substitute(from, fromlen, idx, to, tolen
 				slen--;
 				continue;
 			}
+
 			if (!didmatch) {
 				didmatch = TRUE;
 				strncpy((char *)new, (char *)from, PATH_MAX);
@@ -282,7 +369,12 @@ over:
 			new[0] = '\0';
 			return (new);
 		} else {
+#ifdef	HAVE_REGEX_H
+			tolen = catsub(string, old, oldlen, to, tolen, limit,
+					matp);
+#else
 			tolen = catsub(string, old, oldlen, to, tolen, limit);
+#endif
 			if (tolen < 0) {
 				new[0] = '\0';
 				return (new);
@@ -322,13 +414,20 @@ simpleto(s, len)
  * The '&' character in the to string is substituted with the old from string.
  */
 LOCAL int
+#ifdef	HAVE_REGEX_H
+catsub(here, old, oldlen, to, tolen, limit, mat)
+#else
 catsub(here, old, oldlen, to, tolen, limit)
+#endif
 	register char	*here;
 	register char	*old;
 	register long	oldlen;
 	register char	*to;
 	register long	tolen;
 	register char	*limit;
+#ifdef	HAVE_REGEX_H
+	regmatch_t	*mat;
+#endif
 {
 	char	xold[PATH_MAX+1];
 	char	*p = here;
@@ -342,6 +441,24 @@ catsub(here, old, oldlen, to, tolen, lim
 	while (--tolen >= 0) {
 		if (here >= limit)
 			goto over;
+#ifdef	HAVE_REGEX_H
+		if (*to == '\\' && mat && to[1] >= '1' && to[1] <= '9') {
+			int	i = to[1] - '0';
+			size_t	olen;
+
+			to += 2;
+			tolen--;
+			if (mat[i].rm_so == -1)
+				continue;
+
+			olen = mat[i].rm_eo - mat[i].rm_so;
+			if ((here+olen) >= limit)
+				goto over;
+			strncpy(here, old+mat[i].rm_so, olen);
+			here += olen;
+			continue;
+		} else
+#endif
 		if (*to == '\\') {
 			if (--tolen >= 0)
 				*here++ = *++to;
@@ -360,7 +477,7 @@ catsub(here, old, oldlen, to, tolen, lim
 	strcpy(here, xold);
 	return (here - p);
 over:
-	errmsgno(EX_BAD, "& Substitution path overflow.\n");
+	errmsgno(EX_BAD, "Substitution path overflow.\n");
 	return (-1);
 }
 
Index: star-1.5/conf/configure.in
===================================================================
--- star-1.5.orig/conf/configure.in
+++ star-1.5/conf/configure.in
@@ -75,6 +75,7 @@ AC_CHECK_HEADERS(exec_attr.h secdb.h)
 AC_CHECK_HEADERS(direct.h)
 AC_CHECK_HEADERS(pthread.h thread.h)
 AC_CHECK_HEADERS(libgen.h)
+AC_CHECK_HEADERS(regex.h regexp.h regexpr.h)
 
 dnl from aclocal.m4 (uses AC_TRY_COMPILE)
 AC_HEADER_MAKEDEV
Index: star-1.5/conf/xconfig.h.in
===================================================================
--- star-1.5.orig/conf/xconfig.h.in
+++ star-1.5/conf/xconfig.h.in
@@ -143,6 +143,9 @@
 #undef HAVE_THREAD_H		/* if we may include thread.h */
 
 #undef HAVE_LIBGEN_H		/* if we may include libgen.h */
+#undef HAVE_REGEX_H		/* if we may include regex.h */
+#undef HAVE_REGEXP_H		/* if we may include regexp.h */
+#undef HAVE_REGEXPR_H		/* if we may include regexpr.h */
 
 /*
  * Convert to SCHILY name
