Be a little more skeptical of dev/ino matches when reading cpio files.

This eliminates some false-positives in the hardlink detection logic.
This commit is contained in:
Tim Kientzle 2009-12-29 05:50:34 +00:00
parent 023a748ef3
commit 7f16f13149

View File

@ -92,7 +92,7 @@ struct links_entry {
struct links_entry *previous; struct links_entry *previous;
int links; int links;
dev_t dev; dev_t dev;
ino_t ino; int64_t ino;
char *name; char *name;
}; };
@ -727,51 +727,51 @@ atol16(const char *p, unsigned char_cnt)
static void static void
record_hardlink(struct cpio *cpio, struct archive_entry *entry) record_hardlink(struct cpio *cpio, struct archive_entry *entry)
{ {
struct links_entry *le; struct links_entry *le;
dev_t dev; dev_t dev;
ino_t ino; int64_t ino;
if (archive_entry_nlink(entry) <= 1) if (archive_entry_nlink(entry) <= 1)
return; return;
dev = archive_entry_dev(entry); dev = archive_entry_dev(entry);
ino = archive_entry_ino(entry); ino = archive_entry_ino64(entry);
/* /*
* First look in the list of multiply-linked files. If we've * First look in the list of multiply-linked files. If we've
* already dumped it, convert this entry to a hard link entry. * already dumped it, convert this entry to a hard link entry.
*/ */
for (le = cpio->links_head; le; le = le->next) { for (le = cpio->links_head; le; le = le->next) {
if (le->dev == dev && le->ino == ino) { if (le->dev == dev && le->ino == ino) {
archive_entry_copy_hardlink(entry, le->name); archive_entry_copy_hardlink(entry, le->name);
if (--le->links <= 0) { if (--le->links <= 0) {
if (le->previous != NULL) if (le->previous != NULL)
le->previous->next = le->next; le->previous->next = le->next;
if (le->next != NULL) if (le->next != NULL)
le->next->previous = le->previous; le->next->previous = le->previous;
if (cpio->links_head == le) if (cpio->links_head == le)
cpio->links_head = le->next; cpio->links_head = le->next;
free(le->name); 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) if (le == NULL)
__archive_errx(1, "Out of memory adding file to list"); __archive_errx(1, "Out of memory adding file to list");
if (cpio->links_head != NULL) if (cpio->links_head != NULL)
cpio->links_head->previous = le; cpio->links_head->previous = le;
le->next = cpio->links_head; le->next = cpio->links_head;
le->previous = NULL; le->previous = NULL;
cpio->links_head = le; cpio->links_head = le;
le->dev = dev; le->dev = dev;
le->ino = ino; le->ino = ino;
le->links = archive_entry_nlink(entry) - 1; le->links = archive_entry_nlink(entry) - 1;
le->name = strdup(archive_entry_pathname(entry)); le->name = strdup(archive_entry_pathname(entry));
if (le->name == NULL) if (le->name == NULL)
__archive_errx(1, "Out of memory adding file to list"); __archive_errx(1, "Out of memory adding file to list");
} }