PR/36275: john at iastate dot edu: tar -s modifies symlink targets
- This is explained in a comment in pat_rep.c inside mod_name(). I did not want to change the default behavior, so I added another modifier "s" which when set, the pattern will not modify the symlink destination. - While here I fixed another bug that was introduced before by the fix in PR/35257 where the renaming was happening twice since we called rep_name twice. - Finally if we are renaming hard of soft-link targets print the renames for those too.
This commit is contained in:
parent
a56ad6a493
commit
206f418235
@ -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 <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#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)) {
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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 <string.h>
|
||||
#include <unistd.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"
|
||||
@ -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 >> <empty string>\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;
|
||||
}
|
||||
|
@ -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 <regexp.h>
|
||||
#else
|
||||
#include <regex.h>
|
||||
#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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user