mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
Update vendor/libarchive to 3.7.6
Security fixes: #2330 iso: be more cautious about parsing ISO-9660 timestamps #2343 tar: clean up linkpath between entries Important bugfixes: #2338 tar: fix memory leaks when processing symlinks or parsing pax headers Obtained from: libarchive Vendor commit: f0a0bc6b3046e34c9d6981f8c026da51fea12c89
This commit is contained in:
parent
2022efa030
commit
e6330bf497
10 changed files with 213 additions and 42 deletions
2
NEWS
2
NEWS
|
|
@ -1,3 +1,5 @@
|
|||
Sep 23, 2024: libarchive 3.7.6 released
|
||||
|
||||
Sep 13, 2024: libarchive 3.7.5 released
|
||||
|
||||
Apr 26, 2024: libarchive 3.7.4 released
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3007005
|
||||
3007006
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
|
|||
dnl In particular, this allows the version macro to be used in AC_INIT
|
||||
|
||||
dnl These first two version numbers are updated automatically on each release.
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.7.5])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3007005])
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.7.6])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3007006])
|
||||
|
||||
dnl bsdtar and bsdcpio versioning tracks libarchive
|
||||
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||
*/
|
||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3007005
|
||||
#define ARCHIVE_VERSION_NUMBER 3007006
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
|
|
@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
|
|||
/*
|
||||
* Textual name/version of the library, useful for version displays.
|
||||
*/
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.7.5"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.7.6"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3007005
|
||||
#define ARCHIVE_VERSION_NUMBER 3007006
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ struct file_info {
|
|||
char re; /* Having RRIP "RE" extension. */
|
||||
char re_descendant;
|
||||
uint64_t cl_offset; /* Having RRIP "CL" extension. */
|
||||
int birthtime_is_set;
|
||||
int time_is_set; /* Bitmask indicating which times are known */
|
||||
time_t birthtime; /* File created time. */
|
||||
time_t mtime; /* File last modified time. */
|
||||
time_t atime; /* File last accessed time. */
|
||||
|
|
@ -306,6 +306,11 @@ struct file_info {
|
|||
} rede_files;
|
||||
};
|
||||
|
||||
#define BIRTHTIME_IS_SET 1
|
||||
#define MTIME_IS_SET 2
|
||||
#define ATIME_IS_SET 4
|
||||
#define CTIME_IS_SET 8
|
||||
|
||||
struct heap_queue {
|
||||
struct file_info **files;
|
||||
int allocated;
|
||||
|
|
@ -394,7 +399,9 @@ static void dump_isodirrec(FILE *, const unsigned char *isodirrec);
|
|||
#endif
|
||||
static time_t time_from_tm(struct tm *);
|
||||
static time_t isodate17(const unsigned char *);
|
||||
static int isodate17_valid(const unsigned char *);
|
||||
static time_t isodate7(const unsigned char *);
|
||||
static int isodate7_valid(const unsigned char *);
|
||||
static int isBootRecord(struct iso9660 *, const unsigned char *);
|
||||
static int isVolumePartition(struct iso9660 *, const unsigned char *);
|
||||
static int isVDSetTerminator(struct iso9660 *, const unsigned char *);
|
||||
|
|
@ -1351,13 +1358,22 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
|
|||
archive_entry_set_uid(entry, file->uid);
|
||||
archive_entry_set_gid(entry, file->gid);
|
||||
archive_entry_set_nlink(entry, file->nlinks);
|
||||
if (file->birthtime_is_set)
|
||||
if ((file->time_is_set & BIRTHTIME_IS_SET))
|
||||
archive_entry_set_birthtime(entry, file->birthtime, 0);
|
||||
else
|
||||
archive_entry_unset_birthtime(entry);
|
||||
archive_entry_set_mtime(entry, file->mtime, 0);
|
||||
archive_entry_set_ctime(entry, file->ctime, 0);
|
||||
archive_entry_set_atime(entry, file->atime, 0);
|
||||
if ((file->time_is_set & MTIME_IS_SET))
|
||||
archive_entry_set_mtime(entry, file->mtime, 0);
|
||||
else
|
||||
archive_entry_unset_mtime(entry);
|
||||
if ((file->time_is_set & CTIME_IS_SET))
|
||||
archive_entry_set_ctime(entry, file->ctime, 0);
|
||||
else
|
||||
archive_entry_unset_ctime(entry);
|
||||
if ((file->time_is_set & ATIME_IS_SET))
|
||||
archive_entry_set_atime(entry, file->atime, 0);
|
||||
else
|
||||
archive_entry_unset_atime(entry);
|
||||
/* N.B.: Rock Ridge supports 64-bit device numbers. */
|
||||
archive_entry_set_rdev(entry, (dev_t)file->rdev);
|
||||
archive_entry_set_size(entry, iso9660->entry_bytes_remaining);
|
||||
|
|
@ -1898,8 +1914,11 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
|||
file->parent = parent;
|
||||
file->offset = offset;
|
||||
file->size = fsize;
|
||||
file->mtime = isodate7(isodirrec + DR_date_offset);
|
||||
file->ctime = file->atime = file->mtime;
|
||||
if (isodate7_valid(isodirrec + DR_date_offset)) {
|
||||
file->time_is_set |= MTIME_IS_SET | ATIME_IS_SET | CTIME_IS_SET;
|
||||
file->mtime = isodate7(isodirrec + DR_date_offset);
|
||||
file->ctime = file->atime = file->mtime;
|
||||
}
|
||||
file->rede_files.first = NULL;
|
||||
file->rede_files.last = &(file->rede_files.first);
|
||||
|
||||
|
|
@ -2573,51 +2592,73 @@ parse_rockridge_TF1(struct file_info *file, const unsigned char *data,
|
|||
/* Use 17-byte time format. */
|
||||
if ((flag & 1) && data_length >= 17) {
|
||||
/* Create time. */
|
||||
file->birthtime_is_set = 1;
|
||||
file->birthtime = isodate17(data);
|
||||
if (isodate17_valid(data)) {
|
||||
file->time_is_set |= BIRTHTIME_IS_SET;
|
||||
file->birthtime = isodate17(data);
|
||||
}
|
||||
data += 17;
|
||||
data_length -= 17;
|
||||
}
|
||||
if ((flag & 2) && data_length >= 17) {
|
||||
/* Modify time. */
|
||||
file->mtime = isodate17(data);
|
||||
if (isodate17_valid(data)) {
|
||||
file->time_is_set |= MTIME_IS_SET;
|
||||
file->mtime = isodate17(data);
|
||||
}
|
||||
data += 17;
|
||||
data_length -= 17;
|
||||
}
|
||||
if ((flag & 4) && data_length >= 17) {
|
||||
/* Access time. */
|
||||
file->atime = isodate17(data);
|
||||
if (isodate17_valid(data)) {
|
||||
file->time_is_set |= ATIME_IS_SET;
|
||||
file->atime = isodate17(data);
|
||||
}
|
||||
data += 17;
|
||||
data_length -= 17;
|
||||
}
|
||||
if ((flag & 8) && data_length >= 17) {
|
||||
/* Attribute change time. */
|
||||
file->ctime = isodate17(data);
|
||||
if (isodate17_valid(data)) {
|
||||
file->time_is_set |= CTIME_IS_SET;
|
||||
file->ctime = isodate17(data);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Use 7-byte time format. */
|
||||
if ((flag & 1) && data_length >= 7) {
|
||||
/* Create time. */
|
||||
file->birthtime_is_set = 1;
|
||||
file->birthtime = isodate7(data);
|
||||
if (isodate7_valid(data)) {
|
||||
file->time_is_set |= BIRTHTIME_IS_SET;
|
||||
file->birthtime = isodate7(data);
|
||||
}
|
||||
data += 7;
|
||||
data_length -= 7;
|
||||
}
|
||||
if ((flag & 2) && data_length >= 7) {
|
||||
/* Modify time. */
|
||||
file->mtime = isodate7(data);
|
||||
if (isodate7_valid(data)) {
|
||||
file->time_is_set |= MTIME_IS_SET;
|
||||
file->mtime = isodate7(data);
|
||||
}
|
||||
data += 7;
|
||||
data_length -= 7;
|
||||
}
|
||||
if ((flag & 4) && data_length >= 7) {
|
||||
/* Access time. */
|
||||
file->atime = isodate7(data);
|
||||
if (isodate7_valid(data)) {
|
||||
file->time_is_set |= ATIME_IS_SET;
|
||||
file->atime = isodate7(data);
|
||||
}
|
||||
data += 7;
|
||||
data_length -= 7;
|
||||
}
|
||||
if ((flag & 8) && data_length >= 7) {
|
||||
/* Attribute change time. */
|
||||
file->ctime = isodate7(data);
|
||||
if (isodate7_valid(data)) {
|
||||
file->time_is_set |= CTIME_IS_SET;
|
||||
file->ctime = isodate7(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3226,6 +3267,56 @@ isValid733Integer(const unsigned char *p)
|
|||
&& p[3] == p[4]);
|
||||
}
|
||||
|
||||
static int
|
||||
isodate7_valid(const unsigned char *v)
|
||||
{
|
||||
int year = v[0];
|
||||
int month = v[1];
|
||||
int day = v[2];
|
||||
int hour = v[3];
|
||||
int minute = v[4];
|
||||
int second = v[5];
|
||||
int gmt_off = (signed char)v[6];
|
||||
|
||||
/* ECMA-119 9.1.5 "If all seven values are zero, it shall mean
|
||||
* that the date is unspecified" */
|
||||
if (year == 0
|
||||
&& month == 0
|
||||
&& day == 0
|
||||
&& hour == 0
|
||||
&& minute == 0
|
||||
&& second == 0
|
||||
&& gmt_off == 0)
|
||||
return 0;
|
||||
/*
|
||||
* Sanity-test each individual field
|
||||
*/
|
||||
/* Year can have any value */
|
||||
/* Month must be 1-12 */
|
||||
if (month < 1 || month > 12)
|
||||
return 0;
|
||||
/* Day must be 1-31 */
|
||||
if (day < 1 || day > 31)
|
||||
return 0;
|
||||
/* Hour must be 0-23 */
|
||||
if (hour > 23)
|
||||
return 0;
|
||||
/* Minute must be 0-59 */
|
||||
if (minute > 59)
|
||||
return 0;
|
||||
/* second must be 0-59 according to ECMA-119 9.1.5 */
|
||||
/* BUT: we should probably allow for the time being in UTC, which
|
||||
allows up to 61 seconds in a minute in certain cases */
|
||||
if (second > 61)
|
||||
return 0;
|
||||
/* Offset from GMT must be -48 to +52 */
|
||||
if (gmt_off < -48 || gmt_off > +52)
|
||||
return 0;
|
||||
|
||||
/* All tests pass, this is OK */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static time_t
|
||||
isodate7(const unsigned char *v)
|
||||
{
|
||||
|
|
@ -3252,6 +3343,67 @@ isodate7(const unsigned char *v)
|
|||
return (t);
|
||||
}
|
||||
|
||||
static int
|
||||
isodate17_valid(const unsigned char *v)
|
||||
{
|
||||
/* First 16 bytes are all ASCII digits */
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (v[i] < '0' || v[i] > '9')
|
||||
return 0;
|
||||
}
|
||||
|
||||
int year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
|
||||
+ (v[2] - '0') * 10 + (v[3] - '0');
|
||||
int month = (v[4] - '0') * 10 + (v[5] - '0');
|
||||
int day = (v[6] - '0') * 10 + (v[7] - '0');
|
||||
int hour = (v[8] - '0') * 10 + (v[9] - '0');
|
||||
int minute = (v[10] - '0') * 10 + (v[11] - '0');
|
||||
int second = (v[12] - '0') * 10 + (v[13] - '0');
|
||||
int hundredths = (v[14] - '0') * 10 + (v[15] - '0');
|
||||
int gmt_off = (signed char)v[16];
|
||||
|
||||
if (year == 0 && month == 0 && day == 0
|
||||
&& hour == 0 && minute == 0 && second == 0
|
||||
&& hundredths == 0 && gmt_off == 0)
|
||||
return 0;
|
||||
/*
|
||||
* Sanity-test each individual field
|
||||
*/
|
||||
|
||||
/* Year must be 1900-2300 */
|
||||
/* (Not specified in ECMA-119, but these seem
|
||||
like reasonable limits. */
|
||||
if (year < 1900 || year > 2300)
|
||||
return 0;
|
||||
/* Month must be 1-12 */
|
||||
if (month < 1 || month > 12)
|
||||
return 0;
|
||||
/* Day must be 1-31 */
|
||||
if (day < 1 || day > 31)
|
||||
return 0;
|
||||
/* Hour must be 0-23 */
|
||||
if (hour > 23)
|
||||
return 0;
|
||||
/* Minute must be 0-59 */
|
||||
if (minute > 59)
|
||||
return 0;
|
||||
/* second must be 0-59 according to ECMA-119 9.1.5 */
|
||||
/* BUT: we should probably allow for the time being in UTC, which
|
||||
allows up to 61 seconds in a minute in certain cases */
|
||||
if (second > 61)
|
||||
return 0;
|
||||
/* Hundredths must be 0-99 */
|
||||
if (hundredths > 99)
|
||||
return 0;
|
||||
/* Offset from GMT must be -48 to +52 */
|
||||
if (gmt_off < -48 || gmt_off > +52)
|
||||
return 0;
|
||||
|
||||
/* All tests pass, this is OK */
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static time_t
|
||||
isodate17(const unsigned char *v)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -296,6 +296,7 @@ archive_read_format_tar_cleanup(struct archive_read *a)
|
|||
archive_string_free(&tar->entry_pathname_override);
|
||||
archive_string_free(&tar->entry_uname);
|
||||
archive_string_free(&tar->entry_gname);
|
||||
archive_string_free(&tar->entry_linkpath);
|
||||
archive_string_free(&tar->line);
|
||||
archive_string_free(&tar->pax_global);
|
||||
archive_string_free(&tar->longname);
|
||||
|
|
@ -726,6 +727,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
|||
archive_string_empty(&(tar->entry_pathname));
|
||||
archive_string_empty(&(tar->entry_pathname_override));
|
||||
archive_string_empty(&(tar->entry_uname));
|
||||
archive_string_empty(&tar->entry_linkpath);
|
||||
|
||||
/* Ensure format is set. */
|
||||
if (a->archive.archive_format_name == NULL) {
|
||||
|
|
@ -1935,6 +1937,7 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
|
|||
*unconsumed += 1;
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
}
|
||||
archive_string_free(&attr_name);
|
||||
*unconsumed += ext_size + ext_padding;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -93,16 +93,20 @@ test_small(const char *name)
|
|||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualString(".", archive_entry_pathname(ae));
|
||||
assertEqualIntA(a, 3443989665, archive_entry_atime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
|
||||
assertEqualIntA(a, 3443989665, archive_entry_ctime(ae));
|
||||
assertEqualInt(0, archive_entry_atime_is_set(ae));
|
||||
assertEqualInt(0, archive_entry_atime(ae));
|
||||
assertEqualInt(0, archive_entry_birthtime_is_set(ae));
|
||||
assertEqualInt(0, archive_entry_birthtime(ae));
|
||||
assertEqualInt(0, archive_entry_ctime_is_set(ae));
|
||||
assertEqualInt(0, archive_entry_ctime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_dev(ae));
|
||||
assertEqualIntA(a, AE_IFDIR, archive_entry_filetype(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_gid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_gname(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_ino(ae));
|
||||
assertEqualIntA(a, AE_IFDIR | 0700, archive_entry_mode(ae));
|
||||
assertEqualIntA(a, 3443989665, archive_entry_mtime(ae));
|
||||
assertEqualInt(0, archive_entry_mtime_is_set(ae));
|
||||
assertEqualInt(0, archive_entry_mtime(ae));
|
||||
assertEqualIntA(a, 4, archive_entry_nlink(ae));
|
||||
assertEqualIntA(a, 0700, archive_entry_perm(ae));
|
||||
assertEqualIntA(a, 2048, archive_entry_size(ae));
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ create_tree(void)
|
|||
#define LIMIT_USTAR 100
|
||||
|
||||
static void
|
||||
verify_tree(size_t limit)
|
||||
verify_tree(size_t limit, const char *format)
|
||||
{
|
||||
char name1[260];
|
||||
char name2[260];
|
||||
|
|
@ -203,6 +203,7 @@ verify_tree(size_t limit)
|
|||
/* Verify a file named "f/abcdef..." */
|
||||
snprintf(name1, sizeof(name1), "f/%s", filenames[i]);
|
||||
if (i <= limit) {
|
||||
failure("Verifying %s", format);
|
||||
assertFileExists(name1);
|
||||
assertFileContents(name1, (int)strlen(name1), name1);
|
||||
}
|
||||
|
|
@ -210,6 +211,7 @@ verify_tree(size_t limit)
|
|||
snprintf(name2, sizeof(name2), "l/%s", filenames[i]);
|
||||
if (i + 2 <= limit) {
|
||||
/* Verify hardlink "l/abcdef..." */
|
||||
failure("Verifying %s", format);
|
||||
assertIsHardlink(name1, name2);
|
||||
/* Verify hardlink "m/abcdef..." */
|
||||
name2[0] = 'm';
|
||||
|
|
@ -220,13 +222,16 @@ verify_tree(size_t limit)
|
|||
/* Verify symlink "s/abcdef..." */
|
||||
snprintf(name1, sizeof(name1), "s/%s", filenames[i]);
|
||||
snprintf(name2, sizeof(name2), "../f/%s", filenames[i]);
|
||||
if (strlen(name2) <= limit)
|
||||
if (strlen(name2) <= limit) {
|
||||
failure("Verifying %s", format);
|
||||
assertIsSymlink(name1, name2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify dir "d/abcdef...". */
|
||||
snprintf(name1, sizeof(name1), "d/%s", filenames[i]);
|
||||
if (i + 1 <= limit) { /* +1 for trailing slash */
|
||||
failure("Verifying %s", format);
|
||||
if (assertIsDir(name1, -1)) {
|
||||
/* TODO: opendir/readdir this
|
||||
* directory and make sure
|
||||
|
|
@ -246,7 +251,7 @@ verify_tree(size_t limit)
|
|||
char dir[2];
|
||||
dir[0] = *dp; dir[1] = '\0';
|
||||
d = opendir(dir);
|
||||
failure("Unable to open dir '%s'", dir);
|
||||
failure("Unable to open dir '%s' for testing %s", dir, format);
|
||||
if (!assert(d != NULL))
|
||||
continue;
|
||||
while ((de = readdir(d)) != NULL) {
|
||||
|
|
@ -278,25 +283,25 @@ verify_tree(size_t limit)
|
|||
}
|
||||
|
||||
static void
|
||||
copy_basic(void)
|
||||
copy_basic(const char *extra_args, const char *name)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* NOTE: for proper operation on cygwin-1.5 and windows, the
|
||||
* length of the name of the directory below, "plain", must be
|
||||
* length of the name of the directory below must be
|
||||
* less than or equal to the length of the name of the original
|
||||
* directory, "original" This restriction derives from the
|
||||
* extremely limited pathname lengths on those platforms.
|
||||
*/
|
||||
assertMakeDir("plain", 0775);
|
||||
assertEqualInt(0, chdir("plain"));
|
||||
assertMakeDir(name, 0775);
|
||||
assertEqualInt(0, chdir(name));
|
||||
|
||||
/*
|
||||
* Use the tar program to create an archive.
|
||||
*/
|
||||
r = systemf("%s cf archive -C ../original f d l m s >pack.out 2>pack.err",
|
||||
testprog);
|
||||
failure("Error invoking \"%s cf\"", testprog);
|
||||
r = systemf("%s cf archive %s -C ../original f d l m s >pack.out 2>pack.err",
|
||||
testprog, extra_args);
|
||||
failure("Error invoking \"%s cf archive %s\"", testprog, extra_args);
|
||||
assertEqualInt(r, 0);
|
||||
|
||||
/* Verify that nothing went to stdout or stderr. */
|
||||
|
|
@ -314,7 +319,7 @@ copy_basic(void)
|
|||
assertEmptyFile("unpack.err");
|
||||
assertEmptyFile("unpack.out");
|
||||
|
||||
verify_tree(LIMIT_NONE);
|
||||
verify_tree(LIMIT_NONE, name);
|
||||
assertEqualInt(0, chdir(".."));
|
||||
}
|
||||
|
||||
|
|
@ -357,8 +362,8 @@ copy_ustar(void)
|
|||
assertEmptyFile("unpack.err");
|
||||
assertEmptyFile("unpack.out");
|
||||
|
||||
verify_tree(LIMIT_USTAR);
|
||||
assertEqualInt(0, chdir("../.."));
|
||||
verify_tree(LIMIT_USTAR, "ustar");
|
||||
assertEqualInt(0, chdir(".."));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_copy)
|
||||
|
|
@ -367,8 +372,11 @@ DEFINE_TEST(test_copy)
|
|||
create_tree(); /* Create sample files in "original" dir. */
|
||||
|
||||
/* Test simple "tar -c | tar -x" pipeline copy. */
|
||||
copy_basic();
|
||||
copy_basic("", "default");
|
||||
|
||||
/* Same, but constrain to ustar format. */
|
||||
copy_ustar();
|
||||
|
||||
/* Same, but with pax format. */
|
||||
copy_basic(" --format pax", "pax");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@
|
|||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_ATTR_XATTR_H
|
||||
#if HAVE_SYS_XATTR_H
|
||||
#include <sys/xattr.h>
|
||||
#elif HAVE_ATTR_XATTR_H
|
||||
#include <attr/xattr.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
|
|
|
|||
Loading…
Reference in a new issue