diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c index dc642fdb5f25..a5bd31297952 100644 --- a/bin/pax/ar_subs.c +++ b/bin/pax/ar_subs.c @@ -1,4 +1,4 @@ -/* $NetBSD: ar_subs.c,v 1.53 2007/04/23 18:40:22 christos Exp $ */ +/* $NetBSD: ar_subs.c,v 1.54 2007/05/04 21:19:36 christos Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94"; #else -__RCSID("$NetBSD: ar_subs.c,v 1.53 2007/04/23 18:40:22 christos Exp $"); +__RCSID("$NetBSD: ar_subs.c,v 1.54 2007/05/04 21:19:36 christos Exp $"); #endif #endif /* not lint */ @@ -60,6 +60,7 @@ __RCSID("$NetBSD: ar_subs.c,v 1.53 2007/04/23 18:40:22 christos Exp $"); #include #include #include "pax.h" +#include "pat_rep.h" #include "extern.h" static int path_check(ARCHD *, int); @@ -244,7 +245,7 @@ list(void) * modify the name as requested by the user if name * survives modification, do a listing of the file */ - if ((res = mod_name(arcn)) < 0) + if ((res = mod_name(arcn, RENM)) < 0) break; if (res == 0) { if (arcn->name[0] == '/' && !check_Aflag()) { @@ -391,7 +392,7 @@ extract(void) /* * this archive member is now been selected. modify the name. */ - if ((pat_sel(arcn) < 0) || ((res = mod_name(arcn)) < 0)) + if ((pat_sel(arcn) < 0) || ((res = mod_name(arcn, RENM)) < 0)) break; if (res > 0) { /* @@ -580,7 +581,13 @@ wr_archive(ARCHD *arcn, int is_app) */ if (sel_chk(arcn) != 0) continue; - if ((res = mod_name(arcn)) < 0) + /* + * Here we handle the exclusion -X gnu style patterns which + * are implemented like a pattern list. We don't modify the + * name as this will be done below again, and we don't want + * to double modify it. + */ + if ((res = mod_name(arcn, 0)) < 0) break; if (res == 1) continue; @@ -623,7 +630,7 @@ wr_archive(ARCHD *arcn, int is_app) /* * Now modify the name as requested by the user */ - if ((res = mod_name(arcn)) < 0) { + if ((res = mod_name(arcn, RENM)) < 0) { /* * name modification says to skip this file, close the * file and purge link table entry @@ -1035,7 +1042,7 @@ copy(void) * user; set the final destination. */ ftree_sel(arcn); - if ((chk_lnk(arcn) < 0) || ((res = mod_name(arcn)) < 0)) + if ((chk_lnk(arcn) < 0) || ((res = mod_name(arcn, RENM)) < 0)) break; if ((res > 0) || (set_dest(arcn, dirbuf, dlen) < 0)) { /* diff --git a/bin/pax/extern.h b/bin/pax/extern.h index 39f5461d842e..da95feaaa629 100644 --- a/bin/pax/extern.h +++ b/bin/pax/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.52 2007/04/23 18:40:22 christos Exp $ */ +/* $NetBSD: extern.h,v 1.53 2007/05/04 21:19:36 christos Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -220,7 +220,7 @@ int pat_add(char *, char *); void pat_chk(void); int pat_sel(ARCHD *); int pat_match(ARCHD *); -int mod_name(ARCHD *); +int mod_name(ARCHD *, int); int set_dest(ARCHD *, char *, int); /* diff --git a/bin/pax/pat_rep.c b/bin/pax/pat_rep.c index dfa079391a6f..191ab3f26099 100644 --- a/bin/pax/pat_rep.c +++ b/bin/pax/pat_rep.c @@ -1,4 +1,4 @@ -/* $NetBSD: pat_rep.c,v 1.26 2007/04/29 20:23:34 msaitoh Exp $ */ +/* $NetBSD: pat_rep.c,v 1.27 2007/05/04 21:19:36 christos Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)pat_rep.c 8.2 (Berkeley) 4/18/94"; #else -__RCSID("$NetBSD: pat_rep.c,v 1.26 2007/04/29 20:23:34 msaitoh Exp $"); +__RCSID("$NetBSD: pat_rep.c,v 1.27 2007/05/04 21:19:36 christos Exp $"); #endif #endif /* not lint */ @@ -55,11 +55,6 @@ __RCSID("$NetBSD: pat_rep.c,v 1.26 2007/04/29 20:23:34 msaitoh Exp $"); #include #include #include -#ifdef NET2_REGEX -#include -#else -#include -#endif #include "pax.h" #include "pat_rep.h" #include "extern.h" @@ -220,6 +215,10 @@ rep_add(char *str) case 'P': rep->flgs |= PRNT; break; + case 's': + case 'S': + rep->flgs |= SYML; + break; default: #ifdef NET2_REGEX (void)free((char *)rep->rcmp); @@ -650,7 +649,7 @@ range_match(char *pattern, int test) */ int -mod_name(ARCHD *arcn) +mod_name(ARCHD *arcn, int flags) { int res = 0; @@ -689,18 +688,20 @@ mod_name(ARCHD *arcn) * call an oracle here. :) */ if (rephead != NULL) { + flags |= (flags & RENM) ? PRNT : 0; /* * we have replacement strings, modify the name and the link * name if any. */ if ((res = rep_name(arcn->name, sizeof(arcn->name), - &(arcn->nlen), 1)) != 0) + &(arcn->nlen), flags)) != 0) return res; if (((arcn->type == PAX_SLK) || (arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) && - ((res = rep_name(arcn->ln_name, sizeof(arcn->ln_name), - &(arcn->ln_nlen), 0)) != 0)) + ((res = rep_name(arcn->ln_name, + sizeof(arcn->ln_name), &(arcn->ln_nlen), + flags | (arcn->type == PAX_SLK ? SYML : 0))) != 0)) return res; } @@ -917,7 +918,7 @@ fix_path( char *or_name, int *or_len, char *dir_name, int dir_len) */ static int -rep_name(char *name, size_t namelen, int *nlen, int prnt) +rep_name(char *name, size_t namelen, int *nlen, int flags) { REPLACE *pt; char *inpt; @@ -951,6 +952,8 @@ rep_name(char *name, size_t namelen, int *nlen, int prnt) */ while (pt != NULL) { do { + if ((flags & SYML) && (pt->flgs & SYML)) + continue; /* * check for a successful substitution, if not go to * the next pattern, or cleanup if we were global @@ -994,7 +997,7 @@ rep_name(char *name, size_t namelen, int *nlen, int prnt) resub(&(pt->rcmp),pm,pt->nstr,inpt, outpt,endpt) #endif ) < 0) { - if (prnt) + if (flags & PRNT) tty_warn(1, "Replacement name error %s", name); return 1; @@ -1045,7 +1048,7 @@ rep_name(char *name, size_t namelen, int *nlen, int prnt) *outpt = '\0'; if ((outpt == endpt) && (*inpt != '\0')) { - if (prnt) + if (flags & PRNT) tty_warn(1,"Replacement name too long %s >> %s", name, nname); return 1; @@ -1054,7 +1057,7 @@ rep_name(char *name, size_t namelen, int *nlen, int prnt) /* * inform the user of the result if wanted */ - if (prnt && (pt->flgs & PRNT)) { + if ((flags & PRNT) && (pt->flgs & PRNT)) { if (*nname == '\0') (void)fprintf(stderr,"%s >> \n", name); @@ -1068,7 +1071,8 @@ rep_name(char *name, size_t namelen, int *nlen, int prnt) */ if (*nname == '\0') return 1; - *nlen = strlcpy(name, nname, namelen); + if (flags & RENM) + *nlen = strlcpy(name, nname, namelen); } return 0; } diff --git a/bin/pax/pat_rep.h b/bin/pax/pat_rep.h index 12722c194cb4..f7d56c6984f0 100644 --- a/bin/pax/pat_rep.h +++ b/bin/pax/pat_rep.h @@ -1,4 +1,4 @@ -/* $NetBSD: pat_rep.h,v 1.5 2003/10/13 07:41:22 agc Exp $ */ +/* $NetBSD: pat_rep.h,v 1.6 2007/05/04 21:19:36 christos Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -35,6 +35,11 @@ * @(#)pat_rep.h 8.1 (Berkeley) 5/31/93 */ +#ifdef NET2_REGEX +#include +#else +#include +#endif /* * data structure for storing user supplied replacement strings (-s) */ @@ -48,5 +53,7 @@ typedef struct replace { int flgs; /* print conversions? global in operation? */ #define PRNT 0x1 #define GLOB 0x2 +#define RENM 0x4 +#define SYML 0x8 struct replace *fow; /* pointer to next pattern */ } REPLACE; diff --git a/bin/pax/tar.1 b/bin/pax/tar.1 index 131f899df18d..7691353cda78 100644 --- a/bin/pax/tar.1 +++ b/bin/pax/tar.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: tar.1,v 1.24 2007/04/23 18:41:11 christos Exp $ +.\" $NetBSD: tar.1,v 1.25 2007/05/04 21:19:37 christos Exp $ .\" .\" Copyright (c) 1996 SigmaSoft, Th. Lockert .\" All rights reserved. @@ -25,7 +25,7 @@ .\" .\" OpenBSD: tar.1,v 1.28 2000/11/09 23:58:56 aaron Exp .\" -.Dd April 23, 2007 +.Dd May 4, 2007 .Dt TAR 1 .Os .Sh NAME @@ -161,7 +161,7 @@ using the syntax of the .Xr ed 1 utility regular expressions. The format of these regular expressions are: -.Dl /old/new/[gp] +.Dl /old/new/[gps] As in .Xr ed 1 , .Cm old @@ -196,6 +196,10 @@ in the following format: .Dl \*[Lt]original pathname\*[Gt] \*[Gt]\*[Gt] \*[Lt]new pathname\*[Gt] File or archive member names that substitute to the empty string are not selected and will be skipped. +The substitutions are applied by default to the destination hard and symbolic +links. The optional trailing +.Cm s +prevents the substitutions from being performed on symbolic link destinations. .It Fl v Verbose operation mode. .It Fl w , -interactive , -confirmation