diff options
author | kientzle <kientzle@FreeBSD.org> | 2004-06-15 05:55:41 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2004-06-15 05:55:41 +0000 |
commit | 5ace8b9fe9af8d4dd5140eb6dfac715032f55556 (patch) | |
tree | f5b7f5035df247695f901d5407f18939fb78784f /usr.bin/tar | |
parent | 292410a6b8e787b12658c7d87f2bbaeeb273723a (diff) | |
download | FreeBSD-src-5ace8b9fe9af8d4dd5140eb6dfac715032f55556.zip FreeBSD-src-5ace8b9fe9af8d4dd5140eb6dfac715032f55556.tar.gz |
Add gtar-compatible -X/--exclude-from
Diffstat (limited to 'usr.bin/tar')
-rw-r--r-- | usr.bin/tar/bsdtar.c | 4 | ||||
-rw-r--r-- | usr.bin/tar/bsdtar.h | 1 | ||||
-rw-r--r-- | usr.bin/tar/matching.c | 38 |
3 files changed, 43 insertions, 0 deletions
diff --git a/usr.bin/tar/bsdtar.c b/usr.bin/tar/bsdtar.c index f933cea..3221348 100644 --- a/usr.bin/tar/bsdtar.c +++ b/usr.bin/tar/bsdtar.c @@ -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, diff --git a/usr.bin/tar/bsdtar.h b/usr.bin/tar/bsdtar.h index 7cc7c5c..3c6746c 100644 --- a/usr.bin/tar/bsdtar.h +++ b/usr.bin/tar/bsdtar.h @@ -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, ...); diff --git a/usr.bin/tar/matching.c b/usr.bin/tar/matching.c index 2ba755f..da5417b 100644 --- a/usr.bin/tar/matching.c +++ b/usr.bin/tar/matching.c @@ -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) { |