]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Use int64_t for storing inode values internally.
authorTim Kientzle <kientzle@gmail.com>
Thu, 24 Sep 2009 15:06:56 +0000 (11:06 -0400)
committerTim Kientzle <kientzle@gmail.com>
Thu, 24 Sep 2009 15:06:56 +0000 (11:06 -0400)
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

libarchive/archive_entry.c
libarchive/archive_entry.h
libarchive/archive_entry_link_resolver.c
libarchive/archive_entry_private.h
libarchive/archive_entry_stat.c
libarchive/archive_read_support_format_cpio.c
libarchive/archive_write.c
libarchive/archive_write_private.h
libarchive/archive_write_set_format_cpio.c
libarchive/archive_write_set_format_cpio_newc.c
libarchive/archive_write_set_format_pax.c

index 2c4745b833cd4bb784af4cb1cabed4224e7bf82a..579ae1f4fb92d3bf1ded58233357c5a3370532ed 100644 (file)
@@ -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)
 {
index 54a755bd3a32c3909d3ed72d451dd988974c2eff..9e4a7b6e41795f5763f2692c361823073f139063 100644 (file)
 #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__)
@@ -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 *);
index 9300fe311f069ed065a49e8f1a532569bb7cde3f..51c347520f317629c8146f7ad3081cbb4909d298 100644 (file)
@@ -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. */
index c1d7c3f94aa27a373d22487ec2456f3d8b959126..0c8c032a15c43c008e627b956645bcffaa6efb4c 100644 (file)
@@ -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;
index 315d5cf61511db132df63381c0bf87d295875c1c..bb6f221e198f89ee06f4cdd37400993042856e01 100644 (file)
@@ -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);
index 104e7f6e77ed04e53dcee3f162b67ee98b8c8a6d..3c96ecfce1349bcd07700ecda2c869741653bdf2 100644 (file)
@@ -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");
 }
index 60d42e65ec793b7246bba0b8081d4aac91830742..b13c3cbba5b12d364ff54eebfda6eef9dafb1008 100644 (file)
@@ -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);
index 6192071ffb95c54e39a5100c13fb1780c86f18ef..4b55079dc0fbf6d7ce88a2d88d78dc77622289bd 100644 (file)
@@ -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;
index 043bf3ccd94035d5b6e8ef4bedcc2e540ed2bee4..d6090a6b7ddd178abc3eb11bb09c57b599db42e8 100644 (file)
@@ -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));
index 099c4ff514844b78a21d78ab5118af9ebb630961..06805cfd6aaef15abeb16b0b75d8d844736d377d 100644 (file)
@@ -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));
index c0073c5ce0a67a8236c6ae42cbb4e99dbd544574..0ff69d9c466d5770d309b158adcbf0d9893954fc 100644 (file)
@@ -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));