X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Frestore.c;h=780fd76f04bdd0a3d61297acf9719c0295a6a805;hp=94e0bb6cc8f853c5a4243aeaf0c2dcf738568a2c;hb=f6e1ffa4b425c735543d6c87f93c2e4bf207f1bb;hpb=c21722b0a369bad430dc8c06d645cfd75854a6ec diff --git a/restore/restore.c b/restore/restore.c index 94e0bb6..780fd76 100644 --- a/restore/restore.c +++ b/restore/restore.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: restore.c,v 1.36 2005/03/18 22:12:55 stelian Exp $"; + "$Id: restore.c,v 1.39 2010/03/22 16:08:10 stelian Exp $"; #endif /* not lint */ #include @@ -566,6 +566,9 @@ keyval(int key) /* * Find unreferenced link names. + * + * This also takes care of directories which were missed by removeoldleaves(), + * because their inode has been reused, but excluded from the dump. */ void findunreflinks(void) @@ -581,14 +584,21 @@ findunreflinks(void) continue; if (ep->e_entries == NULL) continue; - for (j = 0; j < DIRHASH_SIZE; j++) { + for (j = 0; j < dirhash_size; j++) { for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) { - if (np->e_flags == 0) { + if ((np->e_flags & ~TMPNAME) == 0) { Dprintf(stdout, "%s: remove unreferenced name\n", myname(np)); - removeleaf(np); - freeentry(np); + if (np->e_type == LEAF) { + removeleaf(np); + freeentry(np); + } else { + np->e_flags |= TMPNAME; + deleteino(np->e_ino); + np->e_next = removelist; + removelist = np; + } } } } @@ -599,7 +609,7 @@ findunreflinks(void) for (ep = removelist; ep != NULL; ep = ep->e_next) { if (ep->e_entries == NULL) continue; - for (j = 0; j < DIRHASH_SIZE; j++) { + for (j = 0; j < dirhash_size; j++) { for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) { if (np->e_type == LEAF) { if (np->e_flags != 0) @@ -609,6 +619,17 @@ findunreflinks(void) myname(np)); removeleaf(np); freeentry(np); + } else { + if ((np->e_flags & ~TMPNAME) != 0) + badentry(np, "unreferenced with flags"); + + if (np->e_flags == 0) { + Dprintf(stdout, + "%s: remove unreferenced name\n", + myname(np)); + np->e_next = ep->e_next; + ep->e_next = np; + } } } } @@ -638,7 +659,7 @@ removeoldnodes(void) int docont = 0; if (ep->e_entries != NULL) { int i; - for (i = 0; i < DIRHASH_SIZE; i++) { + for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i] != NULL) { prev = &ep->e_next; docont = 1; @@ -716,7 +737,6 @@ compareleaves(void) if (first != curfile.ino) { fprintf(stderr, "expected next file %ld, got %lu\n", (long)first, (unsigned long)curfile.ino); - do_compare_error; skipfile(); goto next; }