diff options
author | kientzle <kientzle@FreeBSD.org> | 2004-04-08 06:12:01 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2004-04-08 06:12:01 +0000 |
commit | 1b8aab3f614c2c9ea94f3995fcd1d713c7fa5e32 (patch) | |
tree | cd1718ff7ecd194b94603738159e2fea2fa75f0f /usr.bin/tar | |
parent | 79523261f7033c669a4667180dca6dfeef18be2c (diff) | |
download | FreeBSD-src-1b8aab3f614c2c9ea94f3995fcd1d713c7fa5e32.zip FreeBSD-src-1b8aab3f614c2c9ea94f3995fcd1d713c7fa5e32.tar.gz |
Add support for -T option on create.
(Required by pkg_create.)
Diffstat (limited to 'usr.bin/tar')
-rw-r--r-- | usr.bin/tar/bsdtar.c | 11 | ||||
-rw-r--r-- | usr.bin/tar/bsdtar.h | 2 | ||||
-rw-r--r-- | usr.bin/tar/write.c | 53 |
3 files changed, 60 insertions, 6 deletions
diff --git a/usr.bin/tar/bsdtar.c b/usr.bin/tar/bsdtar.c index 98c3c83..083779d8 100644 --- a/usr.bin/tar/bsdtar.c +++ b/usr.bin/tar/bsdtar.c @@ -57,7 +57,7 @@ static const char *progname; static char ** rewrite_argv(int *argc, char ** src_argv, const char *optstring); -const char *tar_opts = "b:C:cF:f:HhjkLlmnOoPprtUuvwXxyZz"; +const char *tar_opts = "b:C:cF:f:HhjkLlmnOoPprtT:UuvwXxyZz"; #ifdef HAVE_GETOPT_LONG /* @@ -179,8 +179,9 @@ main(int argc, char **argv) case 'c': case 'r': case 'u': case 'x': break; default: - fprintf(stderr, - "First option must be one of: -c, -r, -t, -u, -x\n"); + bsdtar_errc(1, 0, + "First option '%c' unrecognized; " + "should be -c, -r, -t, -u, -x", mode); usage(); exit(1); } @@ -279,6 +280,10 @@ main(int argc, char **argv) umask(0); bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM; break; + case 'T': /* GNU tar */ + only_mode(mode, opt, "c"); + bsdtar->names_from_file = optarg; + break; case 'U': /* GNU tar */ only_mode(mode, opt, "x"); bsdtar->extract_flags |= ARCHIVE_EXTRACT_UNLINK; diff --git a/usr.bin/tar/bsdtar.h b/usr.bin/tar/bsdtar.h index 428c1b4..dd37326 100644 --- a/usr.bin/tar/bsdtar.h +++ b/usr.bin/tar/bsdtar.h @@ -47,8 +47,8 @@ struct bsdtar { const char *filename; /* -f filename */ const char *create_format; /* -F format */ const char *start_dir; /* -C dir */ + const char *names_from_file; /* -T file */ int bytes_per_block; /* -b block_size */ - int records_per_block; int verbose; /* -v */ int extract_flags; /* Flags for extract operation */ char symlink_mode; /* H or L, per BSD conventions */ diff --git a/usr.bin/tar/write.c b/usr.bin/tar/write.c index 17f62a1..5bf9884 100644 --- a/usr.bin/tar/write.c +++ b/usr.bin/tar/write.c @@ -70,6 +70,8 @@ struct archive_dir_entry { static void add_dir_list(struct bsdtar *bsdtar, const char *path, time_t mtime_sec, int mtime_nsec); +void archive_names_from_file(struct bsdtar *bsdtar, + struct archive *a); static void create_cleanup(struct bsdtar *); static int append_archive(struct bsdtar *, struct archive *, const char *fname); @@ -96,7 +98,7 @@ tar_mode_c(struct bsdtar *bsdtar) struct archive *a; int r; - if (*bsdtar->argv == NULL) + if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) bsdtar_errc(1, 0, "no files or directories specified"); a = archive_write_new(); @@ -273,7 +275,7 @@ tar_mode_u(struct bsdtar *bsdtar) /* - * Write files/dirs given on command line to opened archive. + * Write user-specified files/dirs to opened archive. */ static void write_archive(struct archive *a, struct bsdtar *bsdtar) @@ -286,6 +288,9 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) if (bsdtar->start_dir != NULL && chdir(bsdtar->start_dir)) bsdtar_errc(1, errno, "chdir(%s) failed", bsdtar->start_dir); + if (bsdtar->names_from_file != NULL) + archive_names_from_file(bsdtar, a); + while (*bsdtar->argv) { arg = *bsdtar->argv; if (arg[0] == 'C' && arg[1] == '=') { @@ -360,6 +365,50 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) create_cleanup(bsdtar); } +/* Archive names specified in file. */ +void +archive_names_from_file(struct bsdtar *bsdtar, struct archive *a) +{ + FILE *f; + char buff[1024]; + int l; + + if (strcmp(bsdtar->names_from_file, "-") == 0) + f = stdin; + else + f = fopen(bsdtar->names_from_file, "r"); + + while (fgets(buff, sizeof(buff), f) != NULL) { + l = strlen(buff); + if (buff[l-1] == '\n') + buff[l-1] = '\0'; + + /* + * This -C processing hack is really quite ugly, but + * gtar does it this way and pkg_create depends on it, + * so I guess I'm stuck having to implement it. + * + * Someday, pkg_create will just use libarchive directly + * and this will just be a bad memory. + */ + if (strcmp(buff, "-C") == 0) { + if (fgets(buff, sizeof(buff), f) == NULL) + bsdtar_errc(1, errno, + "Unexpected end of filename list; " + "directory expected after -C"); + l = strlen(buff); + if (buff[l-1] == '\n') + buff[l-1] = '\0'; + if (chdir(buff)) + bsdtar_errc(1, errno, "chdir(%s) failed", buff); + } else { + write_heirarchy(bsdtar, a, buff); + } + } + + if (strcmp(bsdtar->names_from_file, "-") != 0) + fclose(f); +} /* Copy from specified archive to current archive. */ static int |