implement the gnutar -X flag in terms of pax -s. fix some bugs in pax -s handling while i am here...

This commit is contained in:
mrg 1999-01-20 14:45:09 +00:00
parent d884fbb6b7
commit ce6b187617
4 changed files with 71 additions and 25 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.13 1998/08/10 22:35:02 tv Exp $ */
/* $NetBSD: extern.h,v 1.14 1999/01/20 14:45:09 mrg Exp $ */
/*-
* Copyright (c) 1992 Keith Muller.
@ -275,6 +275,7 @@ int ustar_stwr __P((void));
int ustar_id __P((char *, int));
int ustar_rd __P((ARCHD *, char *));
int ustar_wr __P((ARCHD *));
int tar_gnutar_X_compat __P((const char *));
/*
* tty_subs.c

View File

@ -1,4 +1,4 @@
/* $NetBSD: options.c,v 1.14 1998/07/28 17:44:24 mycroft Exp $ */
/* $NetBSD: options.c,v 1.15 1999/01/20 14:45:09 mrg Exp $ */
/*-
* Copyright (c) 1992 Keith Muller.
@ -42,7 +42,7 @@
#if 0
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
#else
__RCSID("$NetBSD: options.c,v 1.14 1998/07/28 17:44:24 mycroft Exp $");
__RCSID("$NetBSD: options.c,v 1.15 1999/01/20 14:45:09 mrg Exp $");
#endif
#endif /* not lint */
@ -612,7 +612,7 @@ tar_options(argc, argv)
/*
* process option flags
*/
while ((c = getoldopt(argc, argv, "b:cef:lmoprutvwxzBC:HLPXZ014578"))
while ((c = getoldopt(argc, argv, "b:cef:lmoprutvwxzBC:HLPX:Z014578"))
!= -1) {
switch(c) {
case 'b':
@ -746,9 +746,10 @@ tar_options(argc, argv)
break;
case 'X':
/*
* do not pass over mount points in the file system
* GNU tar compat: exclude the files listed in optarg
*/
Xflag = 1;
if (tar_gnutar_X_compat(optarg) != 0)
tar_usage();
break;
case 'Z':
/*
@ -1403,7 +1404,7 @@ tar_usage()
{
(void)fputs("usage: tar -{txru}[cevfblmopwBHLPX014578] [tapefile] ",
stderr);
(void)fputs("[blocksize] file1 file2...\n", stderr);
(void)fputs("[blocksize] [exclude-file] file1 file2...\n", stderr);
exit(1);
/* NOTREACHED */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pat_rep.c,v 1.7 1997/07/20 20:32:37 christos Exp $ */
/* $NetBSD: pat_rep.c,v 1.8 1999/01/20 14:45:09 mrg 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.7 1997/07/20 20:32:37 christos Exp $");
__RCSID("$NetBSD: pat_rep.c,v 1.8 1999/01/20 14:45:09 mrg Exp $");
#endif
#endif /* not lint */
@ -131,9 +131,13 @@ rep_add(str)
/*
* first character in the string specifies what the delimiter is for
* this expression
* this expression. find the end and middle, from the end. this
* allows the string to be something like /foo\/bar//, but will still
* fail on /foo\/bar/foo\/baz/. XXX need to parse the RE to properly
* do this!
*/
if ((pt1 = strchr(str+1, *str)) == NULL) {
if ((pt2 = strrchr(str+1, *str)) == NULL || pt2 == str+1 ||
(*pt2 = '\0') || (pt1 = strrchr(str+1, *str)) == NULL) {
tty_warn(1, "Invalid replacement string %s", str);
return(-1);
}
@ -166,18 +170,6 @@ rep_add(str)
* we then point the node at the new substitution string
*/
*pt1++ = *str;
if ((pt2 = strchr(pt1, *str)) == NULL) {
# ifdef NET2_REGEX
(void)free((char *)rep->rcmp);
# else
regfree(&(rep->rcmp));
# endif
(void)free((char *)rep);
tty_warn(1, "Invalid replacement string %s", str);
return(-1);
}
*pt2 = '\0';
rep->nstr = pt1;
pt1 = pt2++;
rep->flgs = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: tar.c,v 1.12 1998/10/15 00:07:34 mycroft Exp $ */
/* $NetBSD: tar.c,v 1.13 1999/01/20 14:45:09 mrg Exp $ */
/*-
* Copyright (c) 1992 Keith Muller.
@ -42,7 +42,7 @@
#if 0
static char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94";
#else
__RCSID("$NetBSD: tar.c,v 1.12 1998/10/15 00:07:34 mycroft Exp $");
__RCSID("$NetBSD: tar.c,v 1.13 1999/01/20 14:45:09 mrg Exp $");
#endif
#endif /* not lint */
@ -52,6 +52,7 @@ __RCSID("$NetBSD: tar.c,v 1.12 1998/10/15 00:07:34 mycroft Exp $");
#include <sys/param.h>
#include <ctype.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
@ -1210,3 +1211,54 @@ name_split(name, len)
*/
return(start);
}
/*
* deal with GNU tar -X switch. basically, we go through each line of
* the file, building a string from the "glob" lines in the file into
* RE lines, of the form `/^RE$//', which we pass to rep_add(), which
* will add a empty replacement (exclusion), for the named files.
*/
int
tar_gnutar_X_compat(path)
const char *path;
{
char *line, sbuf[MAXPATHLEN * 2 + 1 + 5];
FILE *fp;
int lineno = 0, len, i, j;
fp = fopen(path, "r");
if (fp == NULL) {
tty_warn(1, "can not open %s: %s", path,
strerror(errno));
return(-1);
}
while ((line = fgetln(fp, &len))) {
lineno++;
if (len > MAXPATHLEN) {
tty_warn(0, "pathname too long, line %d of %s",
lineno, path);
}
if (line[len - 1] == '\n')
len--;
for (i = 0, j = 2; i < len; i++) {
/*
* convert glob to regexp, escaping everything
*/
if (line[i] == '*')
sbuf[j++] = '.';
else if (line[i] == '?')
line[i] = '.';
else if (!isalnum(line[i]) && !isblank(line[i]))
sbuf[j++] = '\\';
sbuf[j++] = line[i];
}
sbuf[0] = sbuf[j + 1] = sbuf[j + 2] = '/';
sbuf[1] = '^';
sbuf[j] = '$';
sbuf[j + 3] = '\0';
if (rep_add(sbuf) < 0)
return (-1);
}
return (0);
}