This fixes some hardlink-detection issues on Windows: NTFS uses 64-bit inode values, but Windows ino_t is only 16 bits.
SVN-Revision: 1463
return (entry->ae_stat.aest_ino);
}
+int64_t
+archive_entry_ino64(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_ino);
+}
+
mode_t
archive_entry_mode(struct archive_entry *entry)
{
entry->ae_stat.aest_ino = ino;
}
+void
+archive_entry_set_ino64(struct archive_entry *entry, int64_t ino)
+{
+ entry->stat_valid = 0;
+ entry->ae_stat.aest_ino = ino;
+}
+
void
archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
{
#include <stddef.h> /* for wchar_t */
#include <time.h>
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <windows.h>
+#endif
+
/* Get appropriate definitions of standard POSIX-style types. */
/* These should match the types used in 'struct stat' */
#if defined(_WIN32) && !defined(__CYGWIN__)
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
__LA_DECL __LA_INO_T archive_entry_ino(struct archive_entry *);
+__LA_DECL int64_t archive_entry_ino64(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_atime(struct archive_entry *);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *,
+ BY_HANDLE_FILE_INFORMATION *);
+#endif
__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
+#if ARCHIVE_VERSION_NUMBER >= 3000000
+/* Starting with libarchive 3.0, this will be synonym for ino64. */
+__LA_DECL void archive_entry_set_ino(struct archive_entry *, int64_t);
+#else
__LA_DECL void archive_entry_set_ino(struct archive_entry *, unsigned long);
+#endif
+__LA_DECL void archive_entry_set_ino64(struct archive_entry *, int64_t);
__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
struct links_entry *le;
int hash, bucket;
dev_t dev;
- ino_t ino;
+ int64_t ino;
/* Free a held entry. */
if (res->spare != NULL) {
return (NULL);
dev = archive_entry_dev(entry);
- ino = archive_entry_ino(entry);
- hash = dev ^ ino;
+ ino = archive_entry_ino64(entry);
+ hash = (int)(dev ^ ino);
/* Try to locate this entry in the links cache. */
bucket = hash % res->number_buckets;
for (le = res->buckets[bucket]; le != NULL; le = le->next) {
if (le->hash == hash
&& dev == archive_entry_dev(le->canonical)
- && ino == archive_entry_ino(le->canonical)) {
+ && ino == archive_entry_ino64(le->canonical)) {
/*
* Decrement link count each time and release
* the entry if it hits zero. This saves
if (res->number_entries > res->number_buckets * 2)
grow_hash(res);
- hash = archive_entry_dev(entry) ^ archive_entry_ino(entry);
+ hash = archive_entry_dev(entry) ^ archive_entry_ino64(entry);
bucket = hash % res->number_buckets;
/* If we could allocate the entry, record it. */
int64_t aest_birthtime;
uint32_t aest_birthtime_nsec;
gid_t aest_gid;
- ino_t aest_ino;
+ int64_t aest_ino;
mode_t aest_mode;
uint32_t aest_nlink;
uint64_t aest_size;
st->st_dev = archive_entry_dev(entry);
st->st_gid = archive_entry_gid(entry);
st->st_uid = archive_entry_uid(entry);
- st->st_ino = archive_entry_ino(entry);
+ st->st_ino = archive_entry_ino64(entry);
st->st_nlink = archive_entry_nlink(entry);
st->st_rdev = archive_entry_rdev(entry);
st->st_size = archive_entry_size(entry);
struct links_entry *previous;
int links;
dev_t dev;
- ino_t ino;
+ int64_t ino;
char *name;
};
static void
record_hardlink(struct cpio *cpio, struct archive_entry *entry)
{
- struct links_entry *le;
+ struct links_entry *le;
dev_t dev;
- ino_t ino;
+ int64_t ino;
dev = archive_entry_dev(entry);
- ino = archive_entry_ino(entry);
-
- /*
- * First look in the list of multiply-linked files. If we've
- * already dumped it, convert this entry to a hard link entry.
- */
- for (le = cpio->links_head; le; le = le->next) {
- if (le->dev == dev && le->ino == ino) {
- archive_entry_copy_hardlink(entry, le->name);
-
- if (--le->links <= 0) {
- if (le->previous != NULL)
- le->previous->next = le->next;
- if (le->next != NULL)
- le->next->previous = le->previous;
- if (cpio->links_head == le)
- cpio->links_head = le->next;
+ ino = archive_entry_ino64(entry);
+
+ /*
+ * First look in the list of multiply-linked files. If we've
+ * already dumped it, convert this entry to a hard link entry.
+ */
+ for (le = cpio->links_head; le; le = le->next) {
+ if (le->dev == dev && le->ino == ino) {
+ archive_entry_copy_hardlink(entry, le->name);
+
+ if (--le->links <= 0) {
+ if (le->previous != NULL)
+ le->previous->next = le->next;
+ if (le->next != NULL)
+ le->next->previous = le->previous;
+ if (cpio->links_head == le)
+ cpio->links_head = le->next;
free(le->name);
- free(le);
- }
+ free(le);
+ }
- return;
- }
- }
+ return;
+ }
+ }
- le = (struct links_entry *)malloc(sizeof(struct links_entry));
+ le = (struct links_entry *)malloc(sizeof(struct links_entry));
if (le == NULL)
__archive_errx(1, "Out of memory adding file to list");
- if (cpio->links_head != NULL)
- cpio->links_head->previous = le;
- le->next = cpio->links_head;
- le->previous = NULL;
- cpio->links_head = le;
- le->dev = dev;
- le->ino = ino;
- le->links = archive_entry_nlink(entry) - 1;
- le->name = strdup(archive_entry_pathname(entry));
+ if (cpio->links_head != NULL)
+ cpio->links_head->previous = le;
+ le->next = cpio->links_head;
+ le->previous = NULL;
+ cpio->links_head = le;
+ le->dev = dev;
+ le->ino = ino;
+ le->links = archive_entry_nlink(entry) - 1;
+ le->name = strdup(archive_entry_pathname(entry));
if (le->name == NULL)
__archive_errx(1, "Out of memory adding file to list");
}
if (a->skip_file_dev != 0 &&
archive_entry_dev(entry) == a->skip_file_dev &&
a->skip_file_ino != 0 &&
- archive_entry_ino(entry) == a->skip_file_ino) {
+ archive_entry_ino64(entry) == a->skip_file_ino) {
archive_set_error(&a->archive, 0,
"Can't add archive to itself");
return (ARCHIVE_FAILED);
/* Dev/ino of the archive being written. */
dev_t skip_file_dev;
- ino_t skip_file_ino;
+ int64_t skip_file_ino;
/* Utility: Pointer to a block of nulls. */
const unsigned char *nulls;
* re-using the ones off the disk. That way, the 18-bit c_ino
* field only limits the number of files in the archive.
*/
- ino = (int64_t)archive_entry_ino(entry);
+ ino = archive_entry_ino64(entry);
if (ino < 0 || ino > 0777777) {
archive_set_error(&a->archive, ERANGE,
"large inode number truncated");
ret = ARCHIVE_WARN;
}
- format_octal(archive_entry_ino(entry) & 0777777, &h.c_ino, sizeof(h.c_ino));
+ format_octal(archive_entry_ino64(entry) & 0777777, &h.c_ino, sizeof(h.c_ino));
format_octal(archive_entry_mode(entry), &h.c_mode, sizeof(h.c_mode));
format_octal(archive_entry_uid(entry), &h.c_uid, sizeof(h.c_uid));
format_octal(archive_entry_gid(entry), &h.c_gid, sizeof(h.c_gid));
format_hex(0x070701, &h.c_magic, sizeof(h.c_magic));
format_hex(archive_entry_devmajor(entry), &h.c_devmajor, sizeof(h.c_devmajor));
format_hex(archive_entry_devminor(entry), &h.c_devminor, sizeof(h.c_devminor));
- if (archive_entry_ino(entry) > 0xffffffff) {
+ if (archive_entry_ino64(entry) > 0xffffffff) {
archive_set_error(&a->archive, ERANGE, "large inode number truncated");
ret = ARCHIVE_WARN;
}
- format_hex(archive_entry_ino(entry) & 0xffffffff, &h.c_ino, sizeof(h.c_ino));
+ format_hex(archive_entry_ino64(entry) & 0xffffffff, &h.c_ino, sizeof(h.c_ino));
format_hex(archive_entry_mode(entry), &h.c_mode, sizeof(h.c_mode));
format_hex(archive_entry_uid(entry), &h.c_uid, sizeof(h.c_uid));
format_hex(archive_entry_gid(entry), &h.c_gid, sizeof(h.c_gid));
add_pax_attr_int(&(pax->pax_header), "SCHILY.dev",
archive_entry_dev(entry_main));
add_pax_attr_int(&(pax->pax_header), "SCHILY.ino",
- archive_entry_ino(entry_main));
+ archive_entry_ino64(entry_main));
add_pax_attr_int(&(pax->pax_header), "SCHILY.nlink",
archive_entry_nlink(entry_main));