tar/test/test_option_exclude_vcs.c \
tar/test/test_option_fflags.c \
tar/test/test_option_gid_gname.c \
+ tar/test/test_option_group.c \
tar/test/test_option_grzip.c \
tar/test/test_option_ignore_zeros.c \
tar/test/test_option_j.c \
tar/test/test_option_newer_than.c \
tar/test/test_option_nodump.c \
tar/test/test_option_older_than.c \
+ tar/test/test_option_owner.c \
tar/test/test_option_passphrase.c \
tar/test/test_option_q.c \
tar/test/test_option_r.c \
On create, this sets the group name that will be stored
in the archive;
the name will not be verified against the system group database.
+.It Fl Fl group Ar name Ns Op : Ns Ar gid
+Use the provided group, if
+.Ar gid
+is not provided,
+.Ar name
+can be either a group name or numeric id.
+See the
+.Fl Fl gname
+option for details.
.It Fl H
(c and r modes only)
Symbolic links named on the command line will be followed; the
Pipe the input (in x or t mode) or the output (in c mode) through
.Pa program
instead of using the builtin compression support.
+.It Fl Fl owner Ar name Ns Op : Ns Ar uid
+Use the provided user, if
+.Ar uid
+is not provided,
+.Ar name
+can be either an username or numeric id.
+See the
+.Fl Fl uname
+option for details.
.It Fl v , Fl Fl verbose
Produce verbose output.
In create and extract modes,
char compression, compression2;
const char *compression_name, *compression2_name;
const char *compress_program;
- char *tptr;
+ char *tptr, *uptr;
char possible_help_request;
char buff[16];
case OPTION_GNAME: /* cpio */
bsdtar->gname = bsdtar->argument;
break;
+ case OPTION_GROUP: /* GNU tar */
+ errno = 0;
+ tptr = NULL;
+
+ uptr = strchr(bsdtar->argument, ':');
+ if(uptr != NULL) {
+ if(uptr[1] == 0) {
+ lafe_errc(1, 0, "Invalid argument to --group (missing id after :)");
+ }
+ uptr[0] = 0;
+ uptr++;
+ t = (int)strtol(uptr, &tptr, 10);
+ if (errno || t < 0 || *uptr == '\0' ||
+ tptr == NULL || *tptr != '\0') {
+ lafe_errc(1, 0, "Invalid argument to --group (%s is not a number)", uptr);
+ } else {
+ bsdtar->gid = t;
+ }
+ bsdtar->gname = bsdtar->argument;
+ } else {
+ t = (int)strtol(bsdtar->argument, &tptr, 10);
+ if (errno || t < 0 || *(bsdtar->argument) == '\0' ||
+ tptr == NULL || *tptr != '\0') {
+ bsdtar->gname = bsdtar->argument;
+ } else {
+ bsdtar->gid = t;
+ bsdtar->gname = "";
+ }
+ }
+ break;
case OPTION_GRZIP:
if (compression != '\0')
lafe_errc(1, 0,
case OPTION_OPTIONS:
bsdtar->option_options = bsdtar->argument;
break;
+ case OPTION_OWNER: /* GNU tar */
+ errno = 0;
+ tptr = NULL;
+
+ uptr = strchr(bsdtar->argument, ':');
+ if(uptr != NULL) {
+ if(uptr[1] == 0) {
+ lafe_errc(1, 0, "Invalid argument to --owner (missing id after :)");
+ }
+ uptr[0] = 0;
+ uptr++;
+ t = (int)strtol(uptr, &tptr, 10);
+ if (errno || t < 0 || *uptr == '\0' ||
+ tptr == NULL || *tptr != '\0') {
+ lafe_errc(1, 0, "Invalid argument to --owner (%s is not a number)", uptr);
+ } else {
+ bsdtar->uid = t;
+ }
+ bsdtar->uname = bsdtar->argument;
+ } else {
+ t = (int)strtol(bsdtar->argument, &tptr, 10);
+ if (errno || t < 0 || *(bsdtar->argument) == '\0' ||
+ tptr == NULL || *tptr != '\0') {
+ bsdtar->uname = bsdtar->argument;
+ } else {
+ bsdtar->uid = t;
+ bsdtar->uname = "";
+ }
+ }
+ break;
#if 0
/*
* The common BSD -P option is not necessary, since
OPTION_FORMAT,
OPTION_GID,
OPTION_GNAME,
+ OPTION_GROUP,
OPTION_GRZIP,
OPTION_HELP,
OPTION_HFS_COMPRESSION,
OPTION_OLDER_MTIME_THAN,
OPTION_ONE_FILE_SYSTEM,
OPTION_OPTIONS,
+ OPTION_OWNER,
OPTION_PASSPHRASE,
OPTION_POSIX,
OPTION_READ_SPARSE,
{ "format", 1, OPTION_FORMAT },
{ "gid", 1, OPTION_GID },
{ "gname", 1, OPTION_GNAME },
+ { "group", 1, OPTION_GROUP },
{ "grzip", 0, OPTION_GRZIP },
{ "gunzip", 0, 'z' },
{ "gzip", 0, 'z' },
{ "older-than", 1, OPTION_OLDER_CTIME_THAN },
{ "one-file-system", 0, OPTION_ONE_FILE_SYSTEM },
{ "options", 1, OPTION_OPTIONS },
+ { "owner", 1, OPTION_OWNER },
{ "passphrase", 1, OPTION_PASSPHRASE },
{ "posix", 0, OPTION_POSIX },
{ "preserve-permissions", 0, 'p' },
test_option_exclude_vcs.c
test_option_fflags.c
test_option_gid_gname.c
+ test_option_group.c
test_option_grzip.c
test_option_ignore_zeros.c
test_option_j.c
test_option_newer_than.c
test_option_nodump.c
test_option_older_than.c
+ test_option_owner.c
test_option_passphrase.c
test_option_q.c
test_option_r.c
--- /dev/null
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * Copyright (c) 2024 Haelwenn (lanodan) Monnier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+DEFINE_TEST(test_option_group)
+{
+ char *reference, *data;
+ size_t s;
+
+ assertUmask(0);
+ assertMakeFile("file", 0644, "1234567890");
+
+ /* Create archive with no special options. */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive1 --format=ustar file >stdout1.txt 2>stderr1.txt",
+ testprog));
+ assertEmptyFile("stdout1.txt");
+ assertEmptyFile("stderr1.txt");
+ reference = slurpfile(&s, "archive1");
+
+ /* Create archive with --group (numeric) */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive2 --group=17 --format=ustar file >stdout2.txt 2>stderr2.txt",
+ testprog));
+ assertEmptyFile("stdout2.txt");
+ assertEmptyFile("stderr2.txt");
+ data = slurpfile(&s, "archive2");
+ assertEqualMem(data + 116, "000021 \0", 8);
+ /* Gname field in ustar header should be empty. */
+ assertEqualMem(data + 297, "\0", 1);
+ free(data);
+
+ /* Again with --group (name) */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive3 --group=foofoofoo --format=ustar file >stdout3.txt 2>stderr3.txt",
+ testprog));
+ assertEmptyFile("stdout3.txt");
+ assertEmptyFile("stderr3.txt");
+ data = slurpfile(&s, "archive3");
+ /* Gid should be unchanged from original reference. */
+ assertEqualMem(data + 116, reference + 116, 8);
+ assertEqualMem(data + 297, "foofoofoo\0", 10);
+ free(data);
+
+ /* Again with --group (name:id) */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive4 --group=foofoofoo:17 --format=ustar file >stdout4.txt 2>stderr4.txt",
+ testprog));
+ assertEmptyFile("stdout4.txt");
+ assertEmptyFile("stderr4.txt");
+ data = slurpfile(&s, "archive4");
+ assertEqualMem(data + 116, "000021 \0", 8);
+ assertEqualMem(data + 297, "foofoofoo\0", 10);
+ free(data);
+
+ free(reference);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * Copyright (c) 2024 Haelwenn (lanodan) Monnier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+DEFINE_TEST(test_option_owner)
+{
+ char *reference, *data;
+ size_t s;
+
+ assertUmask(0);
+ assertMakeFile("file", 0644, "1234567890");
+
+ /* Create archive with no special options. */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive1 --format=ustar file >stdout1.txt 2>stderr1.txt",
+ testprog));
+ assertEmptyFile("stdout1.txt");
+ assertEmptyFile("stderr1.txt");
+ reference = slurpfile(&s, "archive1");
+
+ /* Create archive with --owner (numeric) */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive2 --owner=65123 --format=ustar file >stdout2.txt 2>stderr2.txt",
+ testprog));
+ assertEmptyFile("stdout2.txt");
+ assertEmptyFile("stderr2.txt");
+ data = slurpfile(&s, "archive2");
+ assertEqualMem(data + 108, "177143 \0", 8);
+ /* Uname field in ustar header should be empty. */
+ assertEqualMem(data + 265, "\0", 1);
+ free(data);
+
+ /* Again with just --owner (name) */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive3 --owner=foofoofoo --format=ustar file >stdout3.txt 2>stderr3.txt",
+ testprog));
+ assertEmptyFile("stdout3.txt");
+ assertEmptyFile("stderr3.txt");
+ data = slurpfile(&s, "archive3");
+ /* Uid should be unchanged from original reference. */
+ assertEqualMem(data + 108, reference + 108, 8);
+ assertEqualMem(data + 265, "foofoofoo\0", 10);
+ free(data);
+
+ /* Again with just --owner (name:id) */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive4 --owner=foofoofoo:65123 --format=ustar file >stdout4.txt 2>stderr4.txt",
+ testprog));
+ assertEmptyFile("stdout4.txt");
+ assertEmptyFile("stderr4.txt");
+ data = slurpfile(&s, "archive4");
+ assertEqualMem(data + 108, "177143 \0", 8);
+ assertEqualMem(data + 265, "foofoofoo\0", 10);
+ free(data);
+
+ free(reference);
+}