From: Tim Kientzle Date: Thu, 24 Sep 2009 15:06:56 +0000 (-0400) Subject: Use int64_t for storing inode values internally. X-Git-Tag: v2.8.0~345 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=835b0b1bf11cb59dca9390c67d005bf28935c073;p=thirdparty%2Flibarchive.git Use int64_t for storing inode values internally. 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 --- diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c index 2c4745b83..579ae1f4f 100644 --- a/libarchive/archive_entry.c +++ b/libarchive/archive_entry.c @@ -618,6 +618,12 @@ archive_entry_ino(struct archive_entry *entry) 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) { @@ -817,6 +823,13 @@ archive_entry_set_ino(struct archive_entry *entry, unsigned long ino) 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) { diff --git a/libarchive/archive_entry.h b/libarchive/archive_entry.h index 54a755bd3..9e4a7b6e4 100644 --- a/libarchive/archive_entry.h +++ b/libarchive/archive_entry.h @@ -40,6 +40,10 @@ #include /* for wchar_t */ #include +#if defined(_WIN32) && !defined(__CYGWIN__) +#include +#endif + /* Get appropriate definitions of standard POSIX-style types. */ /* These should match the types used in 'struct stat' */ #if defined(_WIN32) && !defined(__CYGWIN__) @@ -194,6 +198,7 @@ __LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *); __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 *); @@ -227,6 +232,10 @@ __LA_DECL const wchar_t *archive_entry_uname_w(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); @@ -251,7 +260,13 @@ __LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char __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 *); diff --git a/libarchive/archive_entry_link_resolver.c b/libarchive/archive_entry_link_resolver.c index 9300fe311..51c347520 100644 --- a/libarchive/archive_entry_link_resolver.c +++ b/libarchive/archive_entry_link_resolver.c @@ -249,7 +249,7 @@ find_entry(struct archive_entry_linkresolver *res, struct links_entry *le; int hash, bucket; dev_t dev; - ino_t ino; + int64_t ino; /* Free a held entry. */ if (res->spare != NULL) { @@ -264,15 +264,15 @@ find_entry(struct archive_entry_linkresolver *res, 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 @@ -350,7 +350,7 @@ insert_entry(struct archive_entry_linkresolver *res, 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. */ diff --git a/libarchive/archive_entry_private.h b/libarchive/archive_entry_private.h index c1d7c3f94..0c8c032a1 100644 --- a/libarchive/archive_entry_private.h +++ b/libarchive/archive_entry_private.h @@ -119,7 +119,7 @@ struct archive_entry { 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; diff --git a/libarchive/archive_entry_stat.c b/libarchive/archive_entry_stat.c index 315d5cf61..bb6f221e1 100644 --- a/libarchive/archive_entry_stat.c +++ b/libarchive/archive_entry_stat.c @@ -72,7 +72,7 @@ archive_entry_stat(struct archive_entry *entry) 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); diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c index 104e7f6e7..3c96ecfce 100644 --- a/libarchive/archive_read_support_format_cpio.c +++ b/libarchive/archive_read_support_format_cpio.c @@ -92,7 +92,7 @@ struct links_entry { struct links_entry *previous; int links; dev_t dev; - ino_t ino; + int64_t ino; char *name; }; @@ -727,48 +727,48 @@ atol16(const char *p, unsigned char_cnt) 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"); } diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c index 60d42e65e..b13c3cbba 100644 --- a/libarchive/archive_write.c +++ b/libarchive/archive_write.c @@ -423,7 +423,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry) 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); diff --git a/libarchive/archive_write_private.h b/libarchive/archive_write_private.h index 6192071ff..4b55079dc 100644 --- a/libarchive/archive_write_private.h +++ b/libarchive/archive_write_private.h @@ -41,7 +41,7 @@ struct archive_write { /* 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; diff --git a/libarchive/archive_write_set_format_cpio.c b/libarchive/archive_write_set_format_cpio.c index 043bf3ccd..d6090a6b7 100644 --- a/libarchive/archive_write_set_format_cpio.c +++ b/libarchive/archive_write_set_format_cpio.c @@ -126,14 +126,14 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry) * 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)); diff --git a/libarchive/archive_write_set_format_cpio_newc.c b/libarchive/archive_write_set_format_cpio_newc.c index 099c4ff51..06805cfd6 100644 --- a/libarchive/archive_write_set_format_cpio_newc.c +++ b/libarchive/archive_write_set_format_cpio_newc.c @@ -130,12 +130,12 @@ archive_write_newc_header(struct archive_write *a, struct archive_entry *entry) 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)); diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c index c0073c5ce..0ff69d9c4 100644 --- a/libarchive/archive_write_set_format_pax.c +++ b/libarchive/archive_write_set_format_pax.c @@ -819,7 +819,7 @@ archive_write_pax_header(struct archive_write *a, 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));