tar: add --mode option (compatible with gnutar)
This commit is contained in:
1 parent
19ff56da4f
commit
e8154e0bfc
13 files changed
+616
-3
No files matched your search
@@ -21,6 +21,8 @@ IF(ENABLE_TAR)
|
||||
../libarchive_fe/lafe_err.c
|
||||
../libarchive_fe/lafe_err.h
|
||||
../libarchive_fe/lafe_platform.h
|
||||
../libarchive_fe/lafe_setmode.c
|
||||
../libarchive_fe/lafe_setmode.h
|
||||
../libarchive_fe/line_reader.c
|
||||
../libarchive_fe/line_reader.h
|
||||
../libarchive_fe/passphrase.c
|
||||
|
||||
@@ -421,6 +421,13 @@ is run in x mode as root.
|
||||
Currently supported only for pax formats
|
||||
.Po including "pax restricted", the default tar format for
|
||||
.Nm bsdtar Pc
|
||||
.It Fl Fl mode Ar permissions
|
||||
(c, r, u modes only)
|
||||
Modify the file mode bits stored in the archive.
|
||||
Permissions can be absolute (an octal number) or symbolic.
|
||||
See
|
||||
.Xr chmod 1
|
||||
for more information and examples of both types.
|
||||
.It Fl Fl mtime Ar date
|
||||
(c, r, u modes only)
|
||||
Set the modification times of added files to the specified date.
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
#include "bsdtar.h"
|
||||
#include "lafe_err.h"
|
||||
#include "lafe_setmode.h"
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000 && !defined(_PATH_DEFTAPE)
|
||||
// Libarchive 4.0 and later will NOT define _PATH_DEFTAPE
|
||||
@@ -512,6 +513,14 @@ main(int argc, char **argv)
|
||||
bsdtar->extract_flags |= ARCHIVE_EXTRACT_MAC_METADATA;
|
||||
bsdtar->flags |= OPTFLAG_MAC_METADATA;
|
||||
break;
|
||||
case OPTION_MODE: /* GNU tar */
|
||||
free(bsdtar->file_mode);
|
||||
bsdtar->file_mode = lafe_setmode(bsdtar->argument);
|
||||
if (bsdtar->file_mode == NULL)
|
||||
lafe_errc(1, 0,
|
||||
"Invalid file mode: %s",
|
||||
bsdtar->argument);
|
||||
break;
|
||||
case 'n': /* GNU tar */
|
||||
bsdtar->flags |= OPTFLAG_NO_SUBDIRS;
|
||||
break;
|
||||
@@ -1023,6 +1032,7 @@ main(int argc, char **argv)
|
||||
#endif
|
||||
cset_free(bsdtar->cset);
|
||||
passphrase_free(bsdtar->ppbuff);
|
||||
free(bsdtar->file_mode);
|
||||
|
||||
if (bsdtar->return_value != 0)
|
||||
lafe_warnc(0,
|
||||
|
||||
@@ -47,6 +47,7 @@ struct bsdtar {
|
||||
const char *gname; /* --gname */
|
||||
int uid; /* --uid */
|
||||
const char *uname; /* --uname */
|
||||
void *file_mode; /* --mode */
|
||||
const char *passphrase; /* --passphrase */
|
||||
int mode; /* Program mode: 'c', 't', 'r', 'u', 'x' */
|
||||
char symlink_mode; /* H or L, per BSD conventions */
|
||||
@@ -186,6 +187,7 @@ enum {
|
||||
OPTION_ZSTD,
|
||||
OPTION_MTIME,
|
||||
OPTION_CLAMP_MTIME,
|
||||
OPTION_MODE,
|
||||
};
|
||||
|
||||
int bsdtar_getopt(struct bsdtar *);
|
||||
|
||||
@@ -95,6 +95,7 @@ static const struct bsdtar_option {
|
||||
{ "lzma", 0, OPTION_LZMA },
|
||||
{ "lzop", 0, OPTION_LZOP },
|
||||
{ "mac-metadata", 0, OPTION_MAC_METADATA },
|
||||
{ "mode", 1, OPTION_MODE },
|
||||
{ "modification-time", 0, 'm' },
|
||||
{ "mtime", 1, OPTION_MTIME },
|
||||
{ "newer", 1, OPTION_NEWER_CTIME },
|
||||
|
||||
@@ -59,6 +59,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
|
||||
test_option_lz4.c
|
||||
test_option_lzma.c
|
||||
test_option_lzop.c
|
||||
test_option_mode.c
|
||||
test_option_mtime.c
|
||||
test_option_n.c
|
||||
test_option_newer_than.c
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2026 Dan Nelson
|
||||
* All rights reserved.
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
DEFINE_TEST(test_option_mode)
|
||||
{
|
||||
int rv;
|
||||
char *p;
|
||||
|
||||
assertMakeDir("in", 0755);
|
||||
|
||||
/* Test invalid modes */
|
||||
rv = systemf("%s --mode 8 -cf archive.tar in > 1.out 2> 1.err",
|
||||
testprog);
|
||||
assert(rv != 0);
|
||||
|
||||
rv = systemf("%s --mode a+a -cf archive.tar in > 2.out 2> 2.err",
|
||||
testprog);
|
||||
assert(rv != 0);
|
||||
|
||||
/* Create some files with different modes */
|
||||
assertMakeFile("in/all", 0777, "");
|
||||
assertMakeFile("in/minimal", 0500, "");
|
||||
|
||||
/* Archive and override using an absolute mode */
|
||||
assertEqualInt(0,
|
||||
systemf("%s --mode 644 -cf archive1.tar "
|
||||
"in/all in/minimal", testprog));
|
||||
|
||||
/* Verify the modes */
|
||||
p = slurpfile(NULL, "archive1.tar");
|
||||
assertEqualString(p + 100,"000644 ");
|
||||
assertEqualString(p + 612,"000644 ");
|
||||
free(p);
|
||||
|
||||
/* Skip relative symbolic mode checks on Windows; on-disk files always have
|
||||
* mode 644.
|
||||
*/
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
/* Archive and override using a symbolic mode */
|
||||
assertEqualInt(0,
|
||||
systemf("%s --mode u+rw-x,g+X,o-w -cf archive2.tar "
|
||||
"in/all in/minimal", testprog));
|
||||
|
||||
/* Verify the modes */
|
||||
p = slurpfile(NULL, "archive2.tar");
|
||||
assertEqualString(p + 100,"000675 ");
|
||||
assertEqualString(p + 612,"000610 ");
|
||||
free(p);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -59,6 +59,7 @@
|
||||
|
||||
#include "bsdtar.h"
|
||||
#include "lafe_err.h"
|
||||
#include "lafe_setmode.h"
|
||||
#include "line_reader.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
@@ -942,6 +943,12 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
|
||||
if (bsdtar->gname)
|
||||
archive_entry_set_gname(entry, bsdtar->gname);
|
||||
|
||||
if (bsdtar->file_mode) {
|
||||
mode_t m = archive_entry_mode(entry);
|
||||
m = lafe_getmode(bsdtar->file_mode, m);
|
||||
archive_entry_set_mode(entry, m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewrite the pathname to be archived. If rewrite
|
||||
* fails, skip the entry.
|
||||
|
||||
Reference in new issue
Block a user