Clean up some consistent confusion between "dev" and "rdev."
Mostly, these were being used correctly even though a lot of variables and function names were mis-named. In the process, I found and fixed a couple of latent bugs and added a guard against adding an archive to itself.
This commit is contained in:
parent
34ed55636f
commit
7cfb61a9b9
@ -339,16 +339,9 @@ archive_entry_new(void)
|
||||
*/
|
||||
|
||||
dev_t
|
||||
archive_entry_devmajor(struct archive_entry *entry)
|
||||
archive_entry_dev(struct archive_entry *entry)
|
||||
{
|
||||
return (major(entry->ae_stat.st_rdev));
|
||||
}
|
||||
|
||||
|
||||
dev_t
|
||||
archive_entry_devminor(struct archive_entry *entry)
|
||||
{
|
||||
return (minor(entry->ae_stat.st_rdev));
|
||||
return (entry->ae_stat.st_dev);
|
||||
}
|
||||
|
||||
void
|
||||
@ -403,13 +396,18 @@ archive_entry_hardlink(struct archive_entry *entry)
|
||||
return (aes_get_mbs(&entry->ae_hardlink));
|
||||
}
|
||||
|
||||
ino_t
|
||||
archive_entry_ino(struct archive_entry *entry)
|
||||
{
|
||||
return (entry->ae_stat.st_ino);
|
||||
}
|
||||
|
||||
mode_t
|
||||
archive_entry_mode(struct archive_entry *entry)
|
||||
{
|
||||
return (entry->ae_stat.st_mode);
|
||||
}
|
||||
|
||||
|
||||
time_t
|
||||
archive_entry_mtime(struct archive_entry *entry)
|
||||
{
|
||||
@ -434,6 +432,24 @@ archive_entry_pathname_w(struct archive_entry *entry)
|
||||
return (aes_get_wcs(&entry->ae_pathname));
|
||||
}
|
||||
|
||||
dev_t
|
||||
archive_entry_rdev(struct archive_entry *entry)
|
||||
{
|
||||
return (entry->ae_stat.st_rdev);
|
||||
}
|
||||
|
||||
dev_t
|
||||
archive_entry_rdevmajor(struct archive_entry *entry)
|
||||
{
|
||||
return (major(entry->ae_stat.st_rdev));
|
||||
}
|
||||
|
||||
dev_t
|
||||
archive_entry_rdevminor(struct archive_entry *entry)
|
||||
{
|
||||
return (minor(entry->ae_stat.st_rdev));
|
||||
}
|
||||
|
||||
int64_t
|
||||
archive_entry_size(struct archive_entry *entry)
|
||||
{
|
||||
@ -472,24 +488,6 @@ archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
|
||||
entry->ae_stat = *st;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_devmajor(struct archive_entry *entry, dev_t m)
|
||||
{
|
||||
dev_t d;
|
||||
|
||||
d = entry->ae_stat.st_rdev;
|
||||
entry->ae_stat.st_rdev = makedev(m, minor(d));
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_devminor(struct archive_entry *entry, dev_t m)
|
||||
{
|
||||
dev_t d;
|
||||
|
||||
d = entry->ae_stat.st_rdev;
|
||||
entry->ae_stat.st_rdev = makedev( major(d), m);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_fflags(struct archive_entry *entry,
|
||||
unsigned long set, unsigned long clear)
|
||||
@ -572,6 +570,24 @@ archive_entry_copy_pathname_w(struct archive_entry *entry, const wchar_t *name)
|
||||
aes_copy_wcs(&entry->ae_pathname, name);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m)
|
||||
{
|
||||
dev_t d;
|
||||
|
||||
d = entry->ae_stat.st_rdev;
|
||||
entry->ae_stat.st_rdev = makedev(m, minor(d));
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
|
||||
{
|
||||
dev_t d;
|
||||
|
||||
d = entry->ae_stat.st_rdev;
|
||||
entry->ae_stat.st_rdev = makedev( major(d), m);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_size(struct archive_entry *entry, int64_t s)
|
||||
{
|
||||
|
@ -66,18 +66,21 @@ struct archive_entry *archive_entry_new(void);
|
||||
* Retrieve fields from an archive_entry.
|
||||
*/
|
||||
|
||||
dev_t archive_entry_devmajor(struct archive_entry *);
|
||||
dev_t archive_entry_devminor(struct archive_entry *);
|
||||
dev_t archive_entry_dev(struct archive_entry *);
|
||||
const char *archive_entry_fflags_text(struct archive_entry *);
|
||||
void archive_entry_fflags(struct archive_entry *,
|
||||
unsigned long *set, unsigned long *clear);
|
||||
const char *archive_entry_gname(struct archive_entry *);
|
||||
const char *archive_entry_hardlink(struct archive_entry *);
|
||||
ino_t archive_entry_ino(struct archive_entry *);
|
||||
mode_t archive_entry_mode(struct archive_entry *);
|
||||
time_t archive_entry_mtime(struct archive_entry *);
|
||||
long archive_entry_mtime_nsec(struct archive_entry *);
|
||||
const char *archive_entry_pathname(struct archive_entry *);
|
||||
const wchar_t *archive_entry_pathname_w(struct archive_entry *);
|
||||
dev_t archive_entry_rdev(struct archive_entry *);
|
||||
dev_t archive_entry_rdevmajor(struct archive_entry *);
|
||||
dev_t archive_entry_rdevminor(struct archive_entry *);
|
||||
int64_t archive_entry_size(struct archive_entry *);
|
||||
const struct stat *archive_entry_stat(struct archive_entry *);
|
||||
const char *archive_entry_symlink(struct archive_entry *);
|
||||
@ -91,8 +94,6 @@ const char *archive_entry_uname(struct archive_entry *);
|
||||
*/
|
||||
|
||||
void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
|
||||
void archive_entry_set_devmajor(struct archive_entry *, dev_t);
|
||||
void archive_entry_set_devminor(struct archive_entry *, dev_t);
|
||||
void archive_entry_set_fflags(struct archive_entry *,
|
||||
unsigned long set, unsigned long clear);
|
||||
/* Returns pointer to start of first invalid token, or NULL if none. */
|
||||
@ -109,6 +110,8 @@ void archive_entry_set_link(struct archive_entry *, const char *);
|
||||
void archive_entry_set_mode(struct archive_entry *, mode_t);
|
||||
void archive_entry_set_pathname(struct archive_entry *, const char *);
|
||||
void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
|
||||
void archive_entry_set_rdevmajor(struct archive_entry *, dev_t);
|
||||
void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
|
||||
void archive_entry_set_size(struct archive_entry *, int64_t);
|
||||
void archive_entry_set_symlink(struct archive_entry *, const char *);
|
||||
void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
|
||||
|
@ -48,6 +48,11 @@ struct archive {
|
||||
unsigned state;
|
||||
|
||||
struct archive_entry *entry;
|
||||
uid_t user_uid; /* UID of current user. */
|
||||
|
||||
/* Dev/ino of the archive being read/written. */
|
||||
dev_t skip_file_dev;
|
||||
ino_t skip_file_ino;
|
||||
|
||||
/* Utility: Pointer to a block of nulls. */
|
||||
const char *nulls;
|
||||
@ -62,8 +67,6 @@ struct archive {
|
||||
off_t read_data_output_offset;
|
||||
size_t read_data_remaining;
|
||||
|
||||
uid_t user_uid; /* UID of current user. */
|
||||
|
||||
/* Callbacks to open/read/write/close archive stream. */
|
||||
archive_open_callback *client_opener;
|
||||
archive_read_callback *client_reader;
|
||||
|
@ -625,13 +625,13 @@ archive_read_extract_device(struct archive *a, struct archive_entry *entry,
|
||||
unlink(archive_entry_pathname(entry));
|
||||
|
||||
r = mknod(archive_entry_pathname(entry), mode,
|
||||
archive_entry_stat(entry)->st_rdev);
|
||||
archive_entry_rdev(entry));
|
||||
|
||||
/* Might be a non-existent parent dir; try fixing that. */
|
||||
if (r != 0 && errno == ENOENT) {
|
||||
mkdirpath(a, archive_entry_pathname(entry));
|
||||
r = mknod(archive_entry_pathname(entry), mode,
|
||||
archive_entry_stat(entry)->st_rdev);
|
||||
archive_entry_rdev(entry));
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
@ -654,7 +654,7 @@ archive_read_extract_char_device(struct archive *a,
|
||||
{
|
||||
mode_t mode;
|
||||
|
||||
mode = (archive_entry_stat(entry)->st_mode & ~S_IFMT) | S_IFCHR;
|
||||
mode = (archive_entry_mode(entry) & ~S_IFMT) | S_IFCHR;
|
||||
return (archive_read_extract_device(a, entry, flags, mode));
|
||||
}
|
||||
|
||||
@ -664,7 +664,7 @@ archive_read_extract_block_device(struct archive *a,
|
||||
{
|
||||
mode_t mode;
|
||||
|
||||
mode = (archive_entry_stat(entry)->st_mode & ~S_IFMT) | S_IFBLK;
|
||||
mode = (archive_entry_mode(entry) & ~S_IFMT) | S_IFBLK;
|
||||
return (archive_read_extract_device(a, entry, flags, mode));
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,8 @@ struct archive_entry_header_ustar {
|
||||
char version[2]; /* For POSIX: "00" */
|
||||
char uname[32];
|
||||
char gname[32];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char rdevmajor[8];
|
||||
char rdevminor[8];
|
||||
char prefix[155];
|
||||
};
|
||||
|
||||
@ -81,8 +81,8 @@ struct archive_entry_header_gnutar {
|
||||
char magic[8]; /* "ustar \0" (note blank/blank/null at end) */
|
||||
char uname[32];
|
||||
char gname[32];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char rdevmajor[8];
|
||||
char rdevminor[8];
|
||||
char atime[12];
|
||||
char ctime[12];
|
||||
char offset[12];
|
||||
@ -313,7 +313,7 @@ archive_read_format_tar_bid(struct archive *a)
|
||||
/* Not a valid mode; bail out here. */
|
||||
return (0);
|
||||
}
|
||||
/* TODO: Sanity test uid/gid/size/mtime/devmajor/devminor fields. */
|
||||
/* TODO: Sanity test uid/gid/size/mtime/rdevmajor/rdevminor fields. */
|
||||
|
||||
return (bid);
|
||||
}
|
||||
@ -932,8 +932,8 @@ header_ustar(struct archive *a, struct tar *tar, struct archive_entry *entry,
|
||||
/* Parse out device numbers only for char and block specials. */
|
||||
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
|
||||
st->st_rdev = makedev(
|
||||
tar_atol(header->devmajor, sizeof(header->devmajor)),
|
||||
tar_atol(header->devminor, sizeof(header->devminor)));
|
||||
tar_atol(header->rdevmajor, sizeof(header->rdevmajor)),
|
||||
tar_atol(header->rdevminor, sizeof(header->rdevminor)));
|
||||
}
|
||||
|
||||
tar->entry_bytes_remaining = st->st_size;
|
||||
@ -1070,9 +1070,9 @@ pax_attribute(struct archive_entry *entry, struct stat *st,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
|
||||
else if (wcscmp(key, L"SCHILY.devmajor")==0)
|
||||
st->st_rdev = makedev(tar_atol10(value, wcslen(value)),
|
||||
minor(st->st_dev));
|
||||
minor(st->st_rdev));
|
||||
else if (wcscmp(key, L"SCHILY.devminor")==0)
|
||||
st->st_rdev = makedev(major(st->st_dev),
|
||||
st->st_rdev = makedev(major(st->st_rdev),
|
||||
tar_atol10(value, wcslen(value)));
|
||||
else if (wcscmp(key, L"SCHILY.fflags")==0)
|
||||
archive_entry_copy_fflags_text_w(entry, value);
|
||||
@ -1234,8 +1234,8 @@ header_gnutar(struct archive *a, struct tar *tar, struct archive_entry *entry,
|
||||
/* Parse out device numbers only for char and block specials */
|
||||
if (header->typeflag[0] == '3' || header->typeflag[0] == '4')
|
||||
st->st_rdev = makedev (
|
||||
tar_atol(header->devmajor, sizeof(header->devmajor)),
|
||||
tar_atol(header->devminor, sizeof(header->devminor)));
|
||||
tar_atol(header->rdevmajor, sizeof(header->rdevmajor)),
|
||||
tar_atol(header->rdevminor, sizeof(header->rdevminor)));
|
||||
else
|
||||
st->st_rdev = 0;
|
||||
|
||||
@ -1333,7 +1333,7 @@ gnu_parse_sparse_data(struct archive *a, struct tar *tar,
|
||||
* all of the standard numeric fields. This is a significant limitation
|
||||
* in practice:
|
||||
* = file size is limited to 8GB
|
||||
* = devmajor and devminor are limited to 21 bits
|
||||
* = rdevmajor and rdevminor are limited to 21 bits
|
||||
* = uid/gid are limited to 21 bits
|
||||
*
|
||||
* There are two workarounds for this:
|
||||
|
@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <unistd.h>
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
extern char **environ;
|
||||
@ -186,6 +187,12 @@ archive_write_header(struct archive *a, struct archive_entry *entry)
|
||||
if (a->state & ARCHIVE_STATE_DATA)
|
||||
((a->format_finish_entry)(a));
|
||||
|
||||
if (archive_entry_dev(entry) == a->skip_file_dev &&
|
||||
archive_entry_ino(entry) == a->skip_file_ino) {
|
||||
archive_set_error(a, 0, "Can't add archive to itself.");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/* Format and write header. */
|
||||
ret = ((a->format_write_header)(a, entry));
|
||||
|
||||
|
@ -64,8 +64,9 @@ static int
|
||||
file_open(struct archive *a, void *client_data)
|
||||
{
|
||||
struct write_fd_data *mine;
|
||||
struct stat st;
|
||||
struct stat st, *pst;
|
||||
|
||||
pst = NULL;
|
||||
mine = client_data;
|
||||
|
||||
/*
|
||||
@ -75,12 +76,14 @@ file_open(struct archive *a, void *client_data)
|
||||
*/
|
||||
if (mine->fd >= 0 && a->bytes_in_last_block < 0) {
|
||||
/* Last block will be fully padded. */
|
||||
fstat(mine->fd, &st);
|
||||
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
|
||||
S_ISFIFO(st.st_mode))
|
||||
archive_write_set_bytes_in_last_block(a, 0);
|
||||
else
|
||||
archive_write_set_bytes_in_last_block(a, 1);
|
||||
if (fstat(mine->fd, &st) == 0) {
|
||||
pst = &st;
|
||||
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
|
||||
S_ISFIFO(st.st_mode))
|
||||
archive_write_set_bytes_in_last_block(a, 0);
|
||||
else
|
||||
archive_write_set_bytes_in_last_block(a, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (mine->fd == 1) {
|
||||
@ -94,6 +97,13 @@ file_open(struct archive *a, void *client_data)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
if (pst == NULL && fstat(mine->fd, &st) == 0)
|
||||
pst = &st;
|
||||
if (pst == NULL) {
|
||||
archive_set_error(a, errno, "Couldn't stat fd %d", mine->fd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
@ -76,8 +76,9 @@ file_open(struct archive *a, void *client_data)
|
||||
{
|
||||
int flags;
|
||||
struct write_file_data *mine;
|
||||
struct stat st;
|
||||
struct stat st, *pst;
|
||||
|
||||
pst = NULL;
|
||||
mine = client_data;
|
||||
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
|
||||
@ -91,13 +92,17 @@ file_open(struct archive *a, void *client_data)
|
||||
* otherwise leave it unpadded.
|
||||
*/
|
||||
if (mine->fd >= 0 && a->bytes_in_last_block < 0) {
|
||||
/* Last block will be fully padded. */
|
||||
fstat(mine->fd, &st);
|
||||
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
|
||||
S_ISFIFO(st.st_mode))
|
||||
archive_write_set_bytes_in_last_block(a, 0);
|
||||
else
|
||||
archive_write_set_bytes_in_last_block(a, 1);
|
||||
if (fstat(mine->fd, &st) == 0) {
|
||||
pst = &st;
|
||||
if (S_ISCHR(st.st_mode) ||
|
||||
S_ISBLK(st.st_mode) ||
|
||||
S_ISFIFO(st.st_mode))
|
||||
/* Pad last block. */
|
||||
archive_write_set_bytes_in_last_block(a, 0);
|
||||
else
|
||||
/* Don't pad last block. */
|
||||
archive_write_set_bytes_in_last_block(a, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mine->fd = 1;
|
||||
@ -112,6 +117,17 @@ file_open(struct archive *a, void *client_data)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
if (pst == NULL && fstat(mine->fd, &st) == 0)
|
||||
pst = &st;
|
||||
if (pst == NULL) {
|
||||
archive_set_error(a, errno, "Couldn't stat '%s'",
|
||||
mine->filename);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
a->skip_file_dev = pst->st_dev;
|
||||
a->skip_file_ino = pst->st_ino;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
@ -76,8 +76,9 @@ file_open(struct archive *a, void *client_data)
|
||||
{
|
||||
int flags;
|
||||
struct write_file_data *mine;
|
||||
struct stat st;
|
||||
struct stat st, *pst;
|
||||
|
||||
pst = NULL;
|
||||
mine = client_data;
|
||||
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
|
||||
@ -91,13 +92,17 @@ file_open(struct archive *a, void *client_data)
|
||||
* otherwise leave it unpadded.
|
||||
*/
|
||||
if (mine->fd >= 0 && a->bytes_in_last_block < 0) {
|
||||
/* Last block will be fully padded. */
|
||||
fstat(mine->fd, &st);
|
||||
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
|
||||
S_ISFIFO(st.st_mode))
|
||||
archive_write_set_bytes_in_last_block(a, 0);
|
||||
else
|
||||
archive_write_set_bytes_in_last_block(a, 1);
|
||||
if (fstat(mine->fd, &st) == 0) {
|
||||
pst = &st;
|
||||
if (S_ISCHR(st.st_mode) ||
|
||||
S_ISBLK(st.st_mode) ||
|
||||
S_ISFIFO(st.st_mode))
|
||||
/* Pad last block. */
|
||||
archive_write_set_bytes_in_last_block(a, 0);
|
||||
else
|
||||
/* Don't pad last block. */
|
||||
archive_write_set_bytes_in_last_block(a, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mine->fd = 1;
|
||||
@ -112,6 +117,17 @@ file_open(struct archive *a, void *client_data)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
if (pst == NULL && fstat(mine->fd, &st) == 0)
|
||||
pst = &st;
|
||||
if (pst == NULL) {
|
||||
archive_set_error(a, errno, "Couldn't stat '%s'",
|
||||
mine->filename);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
a->skip_file_dev = pst->st_dev;
|
||||
a->skip_file_ino = pst->st_ino;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
@ -446,26 +446,28 @@ archive_write_pax_header(struct archive *a,
|
||||
|
||||
/*
|
||||
* POSIX/SUSv3 doesn't provide a standard key for large device
|
||||
* numbers. I use the same keys here that Joerg Schilling used for
|
||||
* 'star.' No doubt, other implementations use other keys. Note that
|
||||
* there's no reason we can't write the same information into a number
|
||||
* of different keys.
|
||||
* numbers. I use the same keys here that Joerg Schilling
|
||||
* used for 'star.' (Which, somewhat confusingly, are called
|
||||
* "devXXX" even though they code "rdev" values.) No doubt,
|
||||
* other implementations use other keys. Note that there's no
|
||||
* reason we can't write the same information into a number of
|
||||
* different keys.
|
||||
*
|
||||
* Of course, this is only needed for block or char device entries.
|
||||
*/
|
||||
if (S_ISBLK(st_main->st_mode) ||
|
||||
S_ISCHR(st_main->st_mode)) {
|
||||
/*
|
||||
* If devmajor is too large, add 'SCHILY.devmajor' to
|
||||
* If rdevmajor is too large, add 'SCHILY.devmajor' to
|
||||
* extended attributes.
|
||||
*/
|
||||
dev_t devmajor, devminor;
|
||||
devmajor = major(st_main->st_rdev);
|
||||
devminor = minor(st_main->st_rdev);
|
||||
if (devmajor >= (1 << 18)) {
|
||||
dev_t rdevmajor, rdevminor;
|
||||
rdevmajor = major(st_main->st_rdev);
|
||||
rdevminor = minor(st_main->st_rdev);
|
||||
if (rdevmajor >= (1 << 18)) {
|
||||
add_pax_attr_int(&(pax->pax_header), "SCHILY.devmajor",
|
||||
devmajor);
|
||||
archive_entry_set_devmajor(entry_main, (1 << 18) - 1);
|
||||
rdevmajor);
|
||||
archive_entry_set_rdevmajor(entry_main, (1 << 18) - 1);
|
||||
need_extension = 1;
|
||||
}
|
||||
|
||||
@ -473,10 +475,10 @@ archive_write_pax_header(struct archive *a,
|
||||
* If devminor is too large, add 'SCHILY.devminor' to
|
||||
* extended attributes.
|
||||
*/
|
||||
if (devminor >= (1 << 18)) {
|
||||
if (rdevminor >= (1 << 18)) {
|
||||
add_pax_attr_int(&(pax->pax_header), "SCHILY.devminor",
|
||||
devminor);
|
||||
archive_entry_set_devminor(entry_main, (1 << 18) - 1);
|
||||
rdevminor);
|
||||
archive_entry_set_rdevminor(entry_main, (1 << 18) - 1);
|
||||
need_extension = 1;
|
||||
}
|
||||
}
|
||||
@ -558,6 +560,8 @@ archive_write_pax_header(struct archive *a,
|
||||
"SCHILY.acl.default", wp);
|
||||
|
||||
/* Include star-compatible metadata info. */
|
||||
/* Note: "SCHILY.dev{major,minor}" are NOT the
|
||||
* major/minor portions of "SCHILY.dev". */
|
||||
add_pax_attr_int(&(pax->pax_header), "SCHILY.dev",
|
||||
st_main->st_dev);
|
||||
add_pax_attr_int(&(pax->pax_header), "SCHILY.ino",
|
||||
|
@ -275,13 +275,13 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry)
|
||||
break;
|
||||
case S_IFCHR:
|
||||
shar_printf(a, "mknod %s c %d %d\n", name,
|
||||
archive_entry_devmajor(entry),
|
||||
archive_entry_devminor(entry));
|
||||
archive_entry_rdevmajor(entry),
|
||||
archive_entry_rdevminor(entry));
|
||||
break;
|
||||
case S_IFBLK:
|
||||
shar_printf(a, "mknod %s b %d %d\n", name,
|
||||
archive_entry_devmajor(entry),
|
||||
archive_entry_devminor(entry));
|
||||
archive_entry_rdevmajor(entry),
|
||||
archive_entry_rdevminor(entry));
|
||||
break;
|
||||
default:
|
||||
return (ARCHIVE_WARN);
|
||||
|
@ -65,10 +65,10 @@ struct archive_entry_header_ustar {
|
||||
char version[2]; /* For POSIX: "00" */
|
||||
char uname[32];
|
||||
char gname[32];
|
||||
char devmajor[6];
|
||||
char devmajor_padding[2];
|
||||
char devminor[6];
|
||||
char devminor_padding[2];
|
||||
char rdevmajor[6];
|
||||
char rdevmajor_padding[2];
|
||||
char rdevminor[6];
|
||||
char rdevminor_padding[2];
|
||||
char prefix[155];
|
||||
char padding[12];
|
||||
};
|
||||
@ -90,8 +90,8 @@ static const struct archive_entry_header_ustar template_header = {
|
||||
{ '0', '0' }, /* version */
|
||||
{ }, /* uname */
|
||||
{ }, /* gname */
|
||||
{ "000000" }, { ' ', '\0' }, /* devmajor, space-null termination */
|
||||
{ "000000" }, { ' ', '\0' }, /* devminor, space-null termination */
|
||||
{ "000000" }, { ' ', '\0' }, /* rdevmajor, space-null termination */
|
||||
{ "000000" }, { ' ', '\0' }, /* rdevminor, space-null termination */
|
||||
{ }, /* prefix */
|
||||
{ } /* padding */
|
||||
};
|
||||
@ -289,15 +289,15 @@ __archive_write_format_header_ustar(struct archive *a, char buff[512],
|
||||
}
|
||||
|
||||
if (S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode)) {
|
||||
if (format_octal(major(st->st_rdev), h->devmajor,
|
||||
sizeof(h->devmajor))) {
|
||||
if (format_octal(major(st->st_rdev), h->rdevmajor,
|
||||
sizeof(h->rdevmajor))) {
|
||||
archive_set_error(a, ERANGE,
|
||||
"Major device number too large");
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
|
||||
if (format_octal(minor(st->st_rdev), h->devminor,
|
||||
sizeof(h->devminor))) {
|
||||
if (format_octal(minor(st->st_rdev), h->rdevminor,
|
||||
sizeof(h->rdevminor))) {
|
||||
archive_set_error(a, ERANGE,
|
||||
"Minor device number too large");
|
||||
ret = ARCHIVE_WARN;
|
||||
|
Loading…
Reference in New Issue
Block a user