Add gtar-compatible -X/--exclude-from
This commit is contained in:
parent
56f2fe8fd1
commit
b945d45b1e
@ -90,6 +90,7 @@ const struct option tar_longopts[] = {
|
||||
{ "dereference", no_argument, NULL, 'L' },
|
||||
{ "directory", required_argument, NULL, 'C' },
|
||||
{ "exclude", required_argument, NULL, OPTION_EXCLUDE },
|
||||
{ "exclude-from", required_argument, NULL, 'X' },
|
||||
{ "extract", no_argument, NULL, 'x' },
|
||||
{ "fast-read", no_argument, NULL, OPTION_FAST_READ },
|
||||
{ "file", required_argument, NULL, 'f' },
|
||||
@ -329,6 +330,9 @@ main(int argc, char **argv)
|
||||
case 'w': /* SUSv2 */
|
||||
bsdtar->option_interactive = 1;
|
||||
break;
|
||||
case 'X': /* GNU tar */
|
||||
exclude_from_file(bsdtar, optarg);
|
||||
break;
|
||||
case 'x': /* SUSv2 */
|
||||
if (mode != '\0')
|
||||
bsdtar_errc(bsdtar, 1, 0,
|
||||
|
@ -95,6 +95,7 @@ void bsdtar_strmode(struct archive_entry *entry, char *bp);
|
||||
void bsdtar_warnc(struct bsdtar *, int _code, const char *fmt, ...);
|
||||
void cleanup_exclusions(struct bsdtar *);
|
||||
void exclude(struct bsdtar *, const char *pattern);
|
||||
void exclude_from_file(struct bsdtar *, const char *pathname);
|
||||
int excluded(struct bsdtar *, const char *pathname);
|
||||
void include(struct bsdtar *, const char *pattern);
|
||||
void safe_fprintf(FILE *, const char *fmt, ...);
|
||||
|
@ -78,6 +78,44 @@ exclude(struct bsdtar *bsdtar, const char *pattern)
|
||||
matching->exclusions_count++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read lines from file and exclude() each one. This uses
|
||||
* a self-sizing buffer to handle arbitrarily-long lines.
|
||||
*/
|
||||
void
|
||||
exclude_from_file(struct bsdtar *bsdtar, const char *pathname)
|
||||
{
|
||||
FILE *f;
|
||||
char *buff;
|
||||
size_t buff_length, line_length;
|
||||
|
||||
f = fopen(pathname, "r");
|
||||
if (f == NULL)
|
||||
bsdtar_errc(bsdtar, 1, errno, "Couldn't open %s", pathname);
|
||||
buff_length = 256;
|
||||
buff = malloc(buff_length);
|
||||
if (buff == NULL)
|
||||
bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read %s", pathname);
|
||||
while(fgets(buff, buff_length, f) != NULL) {
|
||||
line_length = strlen(buff);
|
||||
while (buff[line_length - 1] != '\n') {
|
||||
buff = realloc(buff, buff_length *= 2);
|
||||
if (buff == NULL)
|
||||
bsdtar_errc(bsdtar, 1, ENOMEM,
|
||||
"Line too long in %s", pathname);
|
||||
if (fgets(buff + line_length,
|
||||
buff_length - line_length, f) == NULL)
|
||||
bsdtar_errc(bsdtar, 1, 0,
|
||||
"Bad input line in %s", pathname);
|
||||
line_length = strlen(buff);
|
||||
}
|
||||
buff[line_length - 1] = '\0';
|
||||
exclude(bsdtar, buff);
|
||||
}
|
||||
free(buff);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void
|
||||
include(struct bsdtar *bsdtar, const char *pattern)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user