Use Gnulib’s same-inode module
This is more portable to non-POSIX systems. However, don’t bother trying to port to systems where st_ino is not a scalar of type dev_t, as these systems no longer seem to be active targets and it’s not worth the maintenance hassle. * gnulib.modules: Add same-inode, now that we use it explicitly rather than indirectly. * src/compare.c (diff_link): * src/create.c (compare_links, restore_parent_fd): * src/incremen.c (compare_directory_meta, procdir): * src/extract.c (dl_compare, repair_delayed_set_stat) (apply_nonancestor_delayed_set_stat, extract_link) (apply_delayed_link): * src/names.c (add_file_id): * src/system.c (sys_file_is_archive, sys_detect_dev_null_output): Include same-inode.h, and prefer its macros and functions to doing things by hand. * src/create.c (struct link): * src/extract.c (struct delayed_set_stat, struct delayed_link): * src/incremen.c (struct directory): * src/names.c (struct file_id_list): Rename members to st_dev and st_ino so that SAME_INODE and PSAME_INODE can be used on the type. All uses changed. * src/system.c (sys_compare_links): Remove. All uses replaced by psame_inode.
This commit is contained in:
@@ -94,6 +94,7 @@ root-uid
|
|||||||
rpmatch
|
rpmatch
|
||||||
full-read
|
full-read
|
||||||
safe-read
|
safe-read
|
||||||
|
same-inode
|
||||||
savedir
|
savedir
|
||||||
selinux-at
|
selinux-at
|
||||||
setenv
|
setenv
|
||||||
|
|||||||
@@ -942,7 +942,6 @@ void sys_spawn_shell (void);
|
|||||||
bool sys_compare_uid (struct stat *a, struct stat *b);
|
bool sys_compare_uid (struct stat *a, struct stat *b);
|
||||||
bool sys_compare_gid (struct stat *a, struct stat *b);
|
bool sys_compare_gid (struct stat *a, struct stat *b);
|
||||||
bool sys_file_is_archive (struct tar_stat_info *p);
|
bool sys_file_is_archive (struct tar_stat_info *p);
|
||||||
bool sys_compare_links (struct stat *link_data, struct stat *stat_data);
|
|
||||||
int sys_truncate (int fd);
|
int sys_truncate (int fd);
|
||||||
pid_t sys_child_open_for_compress (void);
|
pid_t sys_child_open_for_compress (void);
|
||||||
pid_t sys_child_open_for_uncompress (void);
|
pid_t sys_child_open_for_uncompress (void);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <alignalloc.h>
|
#include <alignalloc.h>
|
||||||
#include <quotearg.h>
|
#include <quotearg.h>
|
||||||
#include <rmt.h>
|
#include <rmt.h>
|
||||||
|
#include <same-inode.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/* Nonzero if we are verifying at the moment. */
|
/* Nonzero if we are verifying at the moment. */
|
||||||
@@ -251,7 +252,7 @@ diff_link (void)
|
|||||||
|
|
||||||
if (get_stat_data (current_stat_info.file_name, &file_data)
|
if (get_stat_data (current_stat_info.file_name, &file_data)
|
||||||
&& get_stat_data (current_stat_info.link_name, &link_data)
|
&& get_stat_data (current_stat_info.link_name, &link_data)
|
||||||
&& !sys_compare_links (&file_data, &link_data))
|
&& !psame_inode (&file_data, &link_data))
|
||||||
report_difference (¤t_stat_info,
|
report_difference (¤t_stat_info,
|
||||||
_("Not linked to %s"),
|
_("Not linked to %s"),
|
||||||
quote_n_colon (QUOTE_ARG,
|
quote_n_colon (QUOTE_ARG,
|
||||||
|
|||||||
23
src/create.c
23
src/create.c
@@ -24,6 +24,7 @@
|
|||||||
#include <areadlink.h>
|
#include <areadlink.h>
|
||||||
#include <flexmember.h>
|
#include <flexmember.h>
|
||||||
#include <quotearg.h>
|
#include <quotearg.h>
|
||||||
|
#include <same-inode.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
@@ -34,8 +35,8 @@ enum { IMPOSTOR_ERRNO = ENOENT };
|
|||||||
|
|
||||||
struct link
|
struct link
|
||||||
{
|
{
|
||||||
dev_t dev;
|
dev_t st_dev;
|
||||||
ino_t ino;
|
ino_t st_ino;
|
||||||
nlink_t nlink;
|
nlink_t nlink;
|
||||||
char name[FLEXIBLE_ARRAY_MEMBER];
|
char name[FLEXIBLE_ARRAY_MEMBER];
|
||||||
};
|
};
|
||||||
@@ -1387,7 +1388,7 @@ static size_t
|
|||||||
hash_link (void const *entry, size_t n_buckets)
|
hash_link (void const *entry, size_t n_buckets)
|
||||||
{
|
{
|
||||||
struct link const *l = entry;
|
struct link const *l = entry;
|
||||||
uintmax_t num = l->dev ^ l->ino;
|
uintmax_t num = l->st_dev ^ l->st_ino;
|
||||||
return num % n_buckets;
|
return num % n_buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1397,7 +1398,7 @@ compare_links (void const *entry1, void const *entry2)
|
|||||||
{
|
{
|
||||||
struct link const *link1 = entry1;
|
struct link const *link1 = entry1;
|
||||||
struct link const *link2 = entry2;
|
struct link const *link2 = entry2;
|
||||||
return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0;
|
return PSAME_INODE (link1, link2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1430,8 +1431,8 @@ dump_hard_link (struct tar_stat_info *st)
|
|||||||
off_t block_ordinal;
|
off_t block_ordinal;
|
||||||
union block *blk;
|
union block *blk;
|
||||||
|
|
||||||
lp.ino = st->stat.st_ino;
|
lp.st_dev = st->stat.st_dev;
|
||||||
lp.dev = st->stat.st_dev;
|
lp.st_ino = st->stat.st_ino;
|
||||||
|
|
||||||
if ((duplicate = hash_lookup (link_table, &lp)))
|
if ((duplicate = hash_lookup (link_table, &lp)))
|
||||||
{
|
{
|
||||||
@@ -1485,8 +1486,8 @@ file_count_links (struct tar_stat_info *st)
|
|||||||
}
|
}
|
||||||
|
|
||||||
lp = xmalloc (FLEXNSIZEOF (struct link, name, strlen (linkname) + 1));
|
lp = xmalloc (FLEXNSIZEOF (struct link, name, strlen (linkname) + 1));
|
||||||
lp->ino = st->stat.st_ino;
|
lp->st_dev = st->stat.st_dev;
|
||||||
lp->dev = st->stat.st_dev;
|
lp->st_ino = st->stat.st_ino;
|
||||||
lp->nlink = st->stat.st_nlink;
|
lp->nlink = st->stat.st_nlink;
|
||||||
strcpy (lp->name, linkname);
|
strcpy (lp->name, linkname);
|
||||||
free (linkname);
|
free (linkname);
|
||||||
@@ -1560,8 +1561,7 @@ restore_parent_fd (struct tar_stat_info const *st)
|
|||||||
if (parentfd < 0)
|
if (parentfd < 0)
|
||||||
parentfd = - errno;
|
parentfd = - errno;
|
||||||
else if (fstat (parentfd, &parentstat) < 0
|
else if (fstat (parentfd, &parentstat) < 0
|
||||||
|| parent->stat.st_ino != parentstat.st_ino
|
|| !psame_inode (&parent->stat, &parentstat))
|
||||||
|| parent->stat.st_dev != parentstat.st_dev)
|
|
||||||
{
|
{
|
||||||
close (parentfd);
|
close (parentfd);
|
||||||
parentfd = IMPOSTOR_ERRNO;
|
parentfd = IMPOSTOR_ERRNO;
|
||||||
@@ -1574,8 +1574,7 @@ restore_parent_fd (struct tar_stat_info const *st)
|
|||||||
if (0 <= origfd)
|
if (0 <= origfd)
|
||||||
{
|
{
|
||||||
if (fstat (parentfd, &parentstat) < 0
|
if (fstat (parentfd, &parentstat) < 0
|
||||||
|| parent->stat.st_ino != parentstat.st_ino
|
|| !psame_inode (&parent->stat, &parentstat))
|
||||||
|| parent->stat.st_dev != parentstat.st_dev)
|
|
||||||
close (origfd);
|
close (origfd);
|
||||||
else
|
else
|
||||||
parentfd = origfd;
|
parentfd = origfd;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <priv-set.h>
|
#include <priv-set.h>
|
||||||
#include <root-uid.h>
|
#include <root-uid.h>
|
||||||
|
#include <same-inode.h>
|
||||||
#include <utimens.h>
|
#include <utimens.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -85,8 +86,8 @@ struct delayed_set_stat
|
|||||||
struct delayed_set_stat *next;
|
struct delayed_set_stat *next;
|
||||||
|
|
||||||
/* Metadata for this directory. */
|
/* Metadata for this directory. */
|
||||||
dev_t dev;
|
dev_t st_dev;
|
||||||
ino_t ino;
|
ino_t st_ino;
|
||||||
mode_t mode; /* The desired mode is MODE & ~ current_umask. */
|
mode_t mode; /* The desired mode is MODE & ~ current_umask. */
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
@@ -147,8 +148,8 @@ struct delayed_link
|
|||||||
other process removes the placeholder. Don't use ctime as
|
other process removes the placeholder. Don't use ctime as
|
||||||
this would cause race conditions and other screwups, e.g.,
|
this would cause race conditions and other screwups, e.g.,
|
||||||
when restoring hard-linked symlinks. */
|
when restoring hard-linked symlinks. */
|
||||||
dev_t dev;
|
dev_t st_dev;
|
||||||
ino_t ino;
|
ino_t st_ino;
|
||||||
#if HAVE_BIRTHTIME
|
#if HAVE_BIRTHTIME
|
||||||
struct timespec birthtime;
|
struct timespec birthtime;
|
||||||
#endif
|
#endif
|
||||||
@@ -203,11 +204,11 @@ static size_t
|
|||||||
dl_hash (void const *entry, size_t table_size)
|
dl_hash (void const *entry, size_t table_size)
|
||||||
{
|
{
|
||||||
struct delayed_link const *dl = entry;
|
struct delayed_link const *dl = entry;
|
||||||
uintmax_t n = dl->dev;
|
uintmax_t n = dl->st_dev;
|
||||||
int nshift = TYPE_WIDTH (n) - TYPE_WIDTH (dl->dev);
|
int nshift = TYPE_WIDTH (n) - TYPE_WIDTH (dl->st_dev);
|
||||||
if (0 < nshift)
|
if (0 < nshift)
|
||||||
n <<= nshift;
|
n <<= nshift;
|
||||||
n ^= dl->ino;
|
n ^= dl->st_ino;
|
||||||
return n % table_size;
|
return n % table_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +216,7 @@ static bool
|
|||||||
dl_compare (void const *a, void const *b)
|
dl_compare (void const *a, void const *b)
|
||||||
{
|
{
|
||||||
struct delayed_link const *da = a, *db = b;
|
struct delayed_link const *da = a, *db = b;
|
||||||
return (da->dev == db->dev) & (da->ino == db->ino);
|
return PSAME_INODE (da, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
@@ -496,8 +497,8 @@ mark_after_links (struct delayed_set_stat *head)
|
|||||||
stat_error (h->file_name);
|
stat_error (h->file_name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
h->dev = st.st_dev;
|
h->st_dev = st.st_dev;
|
||||||
h->ino = st.st_ino;
|
h->st_ino = st.st_ino;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ((h = h->next) && ! h->after_links);
|
while ((h = h->next) && ! h->after_links);
|
||||||
@@ -551,8 +552,8 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data->dev = real_st.st_dev;
|
data->st_dev = real_st.st_dev;
|
||||||
data->ino = real_st.st_ino;
|
data->st_ino = real_st.st_ino;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -568,8 +569,8 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
|
|||||||
data->after_links = false;
|
data->after_links = false;
|
||||||
if (st)
|
if (st)
|
||||||
{
|
{
|
||||||
data->dev = st->stat.st_dev;
|
data->st_dev = st->stat.st_dev;
|
||||||
data->ino = st->stat.st_ino;
|
data->st_ino = st->stat.st_ino;
|
||||||
}
|
}
|
||||||
xattr_map_init (&data->xattr_map);
|
xattr_map_init (&data->xattr_map);
|
||||||
}
|
}
|
||||||
@@ -631,8 +632,8 @@ update_interdir_set_stat (char const *dir)
|
|||||||
data = hash_lookup (delayed_set_stat_table, &key);
|
data = hash_lookup (delayed_set_stat_table, &key);
|
||||||
if (data && data->interdir)
|
if (data && data->interdir)
|
||||||
{
|
{
|
||||||
data->dev = current_stat_info.stat.st_dev;
|
data->st_dev = current_stat_info.stat.st_dev;
|
||||||
data->ino = current_stat_info.stat.st_ino;
|
data->st_ino = current_stat_info.stat.st_ino;
|
||||||
data->mode = current_stat_info.stat.st_mode;
|
data->mode = current_stat_info.stat.st_mode;
|
||||||
data->uid = current_stat_info.stat.st_uid;
|
data->uid = current_stat_info.stat.st_uid;
|
||||||
data->gid = current_stat_info.stat.st_gid;
|
data->gid = current_stat_info.stat.st_gid;
|
||||||
@@ -663,11 +664,10 @@ repair_delayed_set_stat (char const *dir,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st.st_dev == dir_stat_info->st_dev
|
if (psame_inode (&st, dir_stat_info))
|
||||||
&& st.st_ino == dir_stat_info->st_ino)
|
|
||||||
{
|
{
|
||||||
data->dev = current_stat_info.stat.st_dev;
|
data->st_dev = current_stat_info.stat.st_dev;
|
||||||
data->ino = current_stat_info.stat.st_ino;
|
data->st_ino = current_stat_info.stat.st_ino;
|
||||||
data->mode = current_stat_info.stat.st_mode;
|
data->mode = current_stat_info.stat.st_mode;
|
||||||
data->uid = current_stat_info.stat.st_uid;
|
data->uid = current_stat_info.stat.st_uid;
|
||||||
data->gid = current_stat_info.stat.st_gid;
|
data->gid = current_stat_info.stat.st_gid;
|
||||||
@@ -1022,7 +1022,7 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
|
|||||||
{
|
{
|
||||||
current_mode = st.st_mode;
|
current_mode = st.st_mode;
|
||||||
current_mode_mask = all_mode_bits;
|
current_mode_mask = all_mode_bits;
|
||||||
if (! (st.st_dev == data->dev && st.st_ino == data->ino))
|
if (!SAME_INODE (st, *data))
|
||||||
{
|
{
|
||||||
paxerror (0,
|
paxerror (0,
|
||||||
_("%s: Directory renamed before its status"
|
_("%s: Directory renamed before its status"
|
||||||
@@ -1416,8 +1416,8 @@ find_delayed_link_source (char const *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct delayed_link dl;
|
struct delayed_link dl;
|
||||||
dl.dev = st.st_dev;
|
dl.st_dev = st.st_dev;
|
||||||
dl.ino = st.st_ino;
|
dl.st_ino = st.st_ino;
|
||||||
return hash_lookup (delayed_link_table, &dl) != NULL;
|
return hash_lookup (delayed_link_table, &dl) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1473,8 +1473,8 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
|
|||||||
xmalloc (FLEXNSIZEOF (struct delayed_link, target,
|
xmalloc (FLEXNSIZEOF (struct delayed_link, target,
|
||||||
strlen (current_stat_info.link_name) + 1));
|
strlen (current_stat_info.link_name) + 1));
|
||||||
p->next = NULL;
|
p->next = NULL;
|
||||||
p->dev = st.st_dev;
|
p->st_dev = st.st_dev;
|
||||||
p->ino = st.st_ino;
|
p->st_ino = st.st_ino;
|
||||||
#if HAVE_BIRTHTIME
|
#if HAVE_BIRTHTIME
|
||||||
p->birthtime = get_stat_birthtime (&st);
|
p->birthtime = get_stat_birthtime (&st);
|
||||||
#endif
|
#endif
|
||||||
@@ -1545,8 +1545,8 @@ extract_link (char *file_name, MAYBE_UNUSED char typeflag)
|
|||||||
&& fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW) == 0)
|
&& fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW) == 0)
|
||||||
{
|
{
|
||||||
struct delayed_link dl1;
|
struct delayed_link dl1;
|
||||||
dl1.ino = st1.st_ino;
|
dl1.st_ino = st1.st_ino;
|
||||||
dl1.dev = st1.st_dev;
|
dl1.st_dev = st1.st_dev;
|
||||||
struct delayed_link *ds = hash_lookup (delayed_link_table, &dl1);
|
struct delayed_link *ds = hash_lookup (delayed_link_table, &dl1);
|
||||||
if (ds && ds->change_dir == chdir_current
|
if (ds && ds->change_dir == chdir_current
|
||||||
&& BIRTHTIME_EQ (ds->birthtime, get_stat_birthtime (&st1)))
|
&& BIRTHTIME_EQ (ds->birthtime, get_stat_birthtime (&st1)))
|
||||||
@@ -1567,8 +1567,7 @@ extract_link (char *file_name, MAYBE_UNUSED char typeflag)
|
|||||||
== 0)
|
== 0)
|
||||||
&& (fstatat (chdir_fd, file_name, &st2, AT_SYMLINK_NOFOLLOW)
|
&& (fstatat (chdir_fd, file_name, &st2, AT_SYMLINK_NOFOLLOW)
|
||||||
== 0)
|
== 0)
|
||||||
&& st1.st_dev == st2.st_dev
|
&& psame_inode (&st1, &st2)))
|
||||||
&& st1.st_ino == st2.st_ino))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
errno = e;
|
errno = e;
|
||||||
@@ -1894,8 +1893,7 @@ apply_delayed_link (struct delayed_link *ds)
|
|||||||
don't create a link, as the placeholder was probably
|
don't create a link, as the placeholder was probably
|
||||||
removed by a later extraction. */
|
removed by a later extraction. */
|
||||||
if (fstatat (chdir_fd, source, &st, AT_SYMLINK_NOFOLLOW) == 0
|
if (fstatat (chdir_fd, source, &st, AT_SYMLINK_NOFOLLOW) == 0
|
||||||
&& st.st_dev == ds->dev
|
&& SAME_INODE (st, *ds)
|
||||||
&& st.st_ino == ds->ino
|
|
||||||
&& BIRTHTIME_EQ (get_stat_birthtime (&st), ds->birthtime))
|
&& BIRTHTIME_EQ (get_stat_birthtime (&st), ds->birthtime))
|
||||||
{
|
{
|
||||||
/* Unlink the placeholder, then create a hard link if possible,
|
/* Unlink the placeholder, then create a hard link if possible,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <flexmember.h>
|
#include <flexmember.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <quotearg.h>
|
#include <quotearg.h>
|
||||||
|
#include <same-inode.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
/* Incremental dump specialities. */
|
/* Incremental dump specialities. */
|
||||||
@@ -73,8 +74,8 @@ struct directory
|
|||||||
{
|
{
|
||||||
struct directory *next;
|
struct directory *next;
|
||||||
struct timespec mtime; /* Modification time */
|
struct timespec mtime; /* Modification time */
|
||||||
dev_t device_number; /* device number for directory */
|
dev_t st_dev; /* device number for directory */
|
||||||
ino_t inode_number; /* inode number for directory */
|
ino_t st_ino; /* inode number for directory */
|
||||||
struct dumpdir *dump; /* Directory contents */
|
struct dumpdir *dump; /* Directory contents */
|
||||||
struct dumpdir *idump; /* Initial contents if the directory was
|
struct dumpdir *idump; /* Initial contents if the directory was
|
||||||
rescanned */
|
rescanned */
|
||||||
@@ -284,7 +285,7 @@ hash_directory_meta (void const *entry, size_t n_buckets)
|
|||||||
{
|
{
|
||||||
struct directory const *directory = entry;
|
struct directory const *directory = entry;
|
||||||
/* FIXME: Work out a better algorytm */
|
/* FIXME: Work out a better algorytm */
|
||||||
return (directory->device_number + directory->inode_number) % n_buckets;
|
return (directory->st_dev + directory->st_ino) % n_buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare two directories for equality of their device and inode numbers. */
|
/* Compare two directories for equality of their device and inode numbers. */
|
||||||
@@ -293,8 +294,7 @@ compare_directory_meta (void const *entry1, void const *entry2)
|
|||||||
{
|
{
|
||||||
struct directory const *directory1 = entry1;
|
struct directory const *directory1 = entry1;
|
||||||
struct directory const *directory2 = entry2;
|
struct directory const *directory2 = entry2;
|
||||||
return directory1->device_number == directory2->device_number
|
return PSAME_INODE (directory1, directory2);
|
||||||
&& directory1->inode_number == directory2->inode_number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a directory entry for given relative NAME and canonical name CANAME.
|
/* Make a directory entry for given relative NAME and canonical name CANAME.
|
||||||
@@ -375,8 +375,8 @@ note_directory (char const *name, struct timespec mtime,
|
|||||||
struct directory *directory = attach_directory (name);
|
struct directory *directory = attach_directory (name);
|
||||||
|
|
||||||
directory->mtime = mtime;
|
directory->mtime = mtime;
|
||||||
directory->device_number = dev;
|
directory->st_dev = dev;
|
||||||
directory->inode_number = ino;
|
directory->st_ino = ino;
|
||||||
directory->children = CHANGED_CHILDREN;
|
directory->children = CHANGED_CHILDREN;
|
||||||
if (nfs)
|
if (nfs)
|
||||||
dir_set_flag (directory, DIRF_NFS);
|
dir_set_flag (directory, DIRF_NFS);
|
||||||
@@ -457,8 +457,8 @@ find_directory_meta (dev_t dev, ino_t ino)
|
|||||||
{
|
{
|
||||||
struct directory *dir = make_directory ("", NULL);
|
struct directory *dir = make_directory ("", NULL);
|
||||||
struct directory *ret;
|
struct directory *ret;
|
||||||
dir->device_number = dev;
|
dir->st_dev = dev;
|
||||||
dir->inode_number = ino;
|
dir->st_ino = ino;
|
||||||
ret = hash_lookup (directory_meta_table, dir);
|
ret = hash_lookup (directory_meta_table, dir);
|
||||||
free_directory (dir);
|
free_directory (dir);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -528,10 +528,9 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
|
|||||||
directories, consider all NFS devices as equal,
|
directories, consider all NFS devices as equal,
|
||||||
relying on the i-node to establish differences. */
|
relying on the i-node to establish differences. */
|
||||||
|
|
||||||
if (! ((!check_device_option
|
if (! (!check_device_option || (dir_is_nfs (directory) && nfs)
|
||||||
|| (dir_is_nfs (directory) && nfs)
|
? directory->st_ino == stat_data->st_ino
|
||||||
|| directory->device_number == stat_data->st_dev)
|
: PSAME_INODE (directory, stat_data)))
|
||||||
&& directory->inode_number == stat_data->st_ino))
|
|
||||||
{
|
{
|
||||||
/* FIXME: find_directory_meta ignores nfs */
|
/* FIXME: find_directory_meta ignores nfs */
|
||||||
struct directory *d = find_directory_meta (stat_data->st_dev,
|
struct directory *d = find_directory_meta (stat_data->st_dev,
|
||||||
@@ -555,8 +554,8 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
|
|||||||
{
|
{
|
||||||
perhaps_renamed = true;
|
perhaps_renamed = true;
|
||||||
directory->children = ALL_CHILDREN;
|
directory->children = ALL_CHILDREN;
|
||||||
directory->device_number = stat_data->st_dev;
|
directory->st_dev = stat_data->st_dev;
|
||||||
directory->inode_number = stat_data->st_ino;
|
directory->st_ino = stat_data->st_ino;
|
||||||
}
|
}
|
||||||
if (nfs)
|
if (nfs)
|
||||||
dir_set_flag (directory, DIRF_NFS);
|
dir_set_flag (directory, DIRF_NFS);
|
||||||
@@ -1439,10 +1438,10 @@ write_directory_file_entry (void *entry, void *data)
|
|||||||
fwrite (s, strlen (s) + 1, 1, fp);
|
fwrite (s, strlen (s) + 1, 1, fp);
|
||||||
int ns = directory->mtime.tv_nsec;
|
int ns = directory->mtime.tv_nsec;
|
||||||
fprintf (fp, "%d%c", ns, 0);
|
fprintf (fp, "%d%c", ns, 0);
|
||||||
s = sysinttostr (directory->device_number,
|
s = sysinttostr (directory->st_dev,
|
||||||
TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), buf);
|
TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), buf);
|
||||||
fwrite (s, strlen (s) + 1, 1, fp);
|
fwrite (s, strlen (s) + 1, 1, fp);
|
||||||
s = sysinttostr (directory->inode_number,
|
s = sysinttostr (directory->st_ino,
|
||||||
TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), buf);
|
TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), buf);
|
||||||
fwrite (s, strlen (s) + 1, 1, fp);
|
fwrite (s, strlen (s) + 1, 1, fp);
|
||||||
|
|
||||||
|
|||||||
11
src/names.c
11
src/names.c
@@ -21,6 +21,7 @@
|
|||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <quotearg.h>
|
#include <quotearg.h>
|
||||||
|
#include <same-inode.h>
|
||||||
#include <wordsplit.h>
|
#include <wordsplit.h>
|
||||||
#include <argp.h>
|
#include <argp.h>
|
||||||
|
|
||||||
@@ -881,8 +882,8 @@ name_init (void)
|
|||||||
struct file_id_list
|
struct file_id_list
|
||||||
{
|
{
|
||||||
struct file_id_list *next;
|
struct file_id_list *next;
|
||||||
ino_t ino;
|
dev_t st_dev;
|
||||||
dev_t dev;
|
ino_t st_ino;
|
||||||
const char *from_file;
|
const char *from_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -913,7 +914,7 @@ add_file_id (const char *filename)
|
|||||||
stat_fatal (filename);
|
stat_fatal (filename);
|
||||||
reading_from = file_list_name ();
|
reading_from = file_list_name ();
|
||||||
for (p = file_id_list; p; p = p->next)
|
for (p = file_id_list; p; p = p->next)
|
||||||
if (p->ino == st.st_ino && p->dev == st.st_dev)
|
if (SAME_INODE (*p, st))
|
||||||
{
|
{
|
||||||
int oldc = set_char_quoting (NULL, ':', 1);
|
int oldc = set_char_quoting (NULL, ':', 1);
|
||||||
paxerror (0, _("%s: file list requested from %s already read from %s"),
|
paxerror (0, _("%s: file list requested from %s already read from %s"),
|
||||||
@@ -924,8 +925,8 @@ add_file_id (const char *filename)
|
|||||||
}
|
}
|
||||||
p = xmalloc (sizeof *p);
|
p = xmalloc (sizeof *p);
|
||||||
p->next = file_id_list;
|
p->next = file_id_list;
|
||||||
p->ino = st.st_ino;
|
p->st_dev = st.st_dev;
|
||||||
p->dev = st.st_dev;
|
p->st_ino = st.st_ino;
|
||||||
p->from_file = reading_from;
|
p->from_file = reading_from;
|
||||||
file_id_list = p;
|
file_id_list = p;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
20
src/system.c
20
src/system.c
@@ -25,6 +25,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <priv-set.h>
|
#include <priv-set.h>
|
||||||
#include <rmt.h>
|
#include <rmt.h>
|
||||||
|
#include <same-inode.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <wordsplit.h>
|
#include <wordsplit.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
@@ -125,12 +126,6 @@ sys_compare_gid (struct stat *a, struct stat *b)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
sys_compare_links (struct stat *link_data, struct stat *stat_data)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
sys_truncate (int fd)
|
sys_truncate (int fd)
|
||||||
{
|
{
|
||||||
@@ -194,8 +189,7 @@ bool
|
|||||||
sys_file_is_archive (struct tar_stat_info *p)
|
sys_file_is_archive (struct tar_stat_info *p)
|
||||||
{
|
{
|
||||||
return (!dev_null_output && !_isrmt (archive)
|
return (!dev_null_output && !_isrmt (archive)
|
||||||
&& p->stat.st_dev == archive_stat.st_dev
|
&& psame_inode (&p->stat, &archive_stat));
|
||||||
&& p->stat.st_ino == archive_stat.st_ino);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char const dev_null[] = "/dev/null";
|
static char const dev_null[] = "/dev/null";
|
||||||
@@ -211,8 +205,7 @@ sys_detect_dev_null_output (void)
|
|||||||
&& S_ISCHR (archive_stat.st_mode)
|
&& S_ISCHR (archive_stat.st_mode)
|
||||||
&& (dev_null_stat.st_ino != 0
|
&& (dev_null_stat.st_ino != 0
|
||||||
|| stat (dev_null, &dev_null_stat) == 0)
|
|| stat (dev_null, &dev_null_stat) == 0)
|
||||||
&& archive_stat.st_ino == dev_null_stat.st_ino
|
&& psame_inode (&archive_stat, &dev_null_stat)));
|
||||||
&& archive_stat.st_dev == dev_null_stat.st_dev));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -279,13 +272,6 @@ sys_compare_gid (struct stat *a, struct stat *b)
|
|||||||
return a->st_gid == b->st_gid;
|
return a->st_gid == b->st_gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
sys_compare_links (struct stat *link_data, struct stat *stat_data)
|
|
||||||
{
|
|
||||||
return stat_data->st_dev == link_data->st_dev
|
|
||||||
&& stat_data->st_ino == link_data->st_ino;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
sys_truncate (int fd)
|
sys_truncate (int fd)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user