tar: handle --mode when extracting archives also
This commit is contained in:
1 parent
e8154e0bfc
commit
c26faff361
3 files changed
+74
-2
No files matched your search
+4
-2
@@ -422,8 +422,10 @@ 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.
|
||||
Modify the file mode bits.
|
||||
On create, this takes the on-disk mode and modifies it before storing
|
||||
in the archive.
|
||||
On extract, the mode from the archive is modified before writing to disk.
|
||||
Permissions can be absolute (an octal number) or symbolic.
|
||||
See
|
||||
.Xr chmod 1
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
|
||||
#include "bsdtar.h"
|
||||
#include "lafe_err.h"
|
||||
#include "lafe_setmode.h"
|
||||
|
||||
struct progress_data {
|
||||
struct bsdtar *bsdtar;
|
||||
@@ -278,6 +279,12 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that pattern exclusions are checked before
|
||||
* pathname rewrites are handled. This gives more
|
||||
|
||||
@@ -6,11 +6,52 @@
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
/* Compare the mode column of tar's list output with an array of expected
|
||||
* values.
|
||||
*/
|
||||
static void check_modes(const char* testname, const char *buf, const char *lines[])
|
||||
{
|
||||
int line = 1;
|
||||
while (*buf && *lines != NULL)
|
||||
{
|
||||
failure("On line %d of test %s", line, testname);
|
||||
assertEqualMem(buf, *lines, strlen(*lines));
|
||||
while (*buf && !(*buf == '\r'|| *buf == '\n'))
|
||||
buf++;
|
||||
while (*buf == '\r' || *buf == '\n')
|
||||
buf++;
|
||||
lines++;
|
||||
line++;
|
||||
}
|
||||
if (*lines && ! *buf)
|
||||
{
|
||||
failure("On line %d of test %s: unexpected end of file", line, testname);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_option_mode)
|
||||
{
|
||||
int rv;
|
||||
char *p;
|
||||
|
||||
const char *test3mtree =
|
||||
"#mtree\n"
|
||||
"in/all mode=777 type=file\n"
|
||||
"in/minimal mode=500 type=file\n";
|
||||
|
||||
const char *test3aExpected[] = {
|
||||
"-rw-r--r--",
|
||||
"-rw-r--r--",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char *test3bExpected[] = {
|
||||
"-rw-rwxr-x",
|
||||
"-rw---x---",
|
||||
NULL
|
||||
};
|
||||
|
||||
assertMakeDir("in", 0755);
|
||||
|
||||
/* Test invalid modes */
|
||||
@@ -53,4 +94,26 @@ DEFINE_TEST(test_option_mode)
|
||||
free(p);
|
||||
#endif
|
||||
|
||||
/* Create an archive file with custom modes. Using mtree here is
|
||||
* simpler than building a tar file from files, and also works on
|
||||
* Windows.
|
||||
*/
|
||||
assertMakeFile("archive3.mtree", 0644, test3mtree);
|
||||
|
||||
/* list, overriding with absolute mode */
|
||||
assertEqualInt(0,
|
||||
systemf("%s --mode 644 -tvf archive3.mtree > 3a.out",
|
||||
testprog));
|
||||
p = slurpfile(NULL, "3a.out");
|
||||
check_modes("3a", p, test3aExpected);
|
||||
free(p);
|
||||
|
||||
/* list, overriding with relative mode */
|
||||
assertEqualInt(0,
|
||||
systemf("%s --mode u+rw-x,g+X,o-w -tvf archive3.mtree > 3b.out",
|
||||
testprog));
|
||||
p = slurpfile(NULL, "3b.out");
|
||||
check_modes("3b", p, test3bExpected);
|
||||
free(p);
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user