X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Frestore.c;h=94e0bb6cc8f853c5a4243aeaf0c2dcf738568a2c;hp=533ae5b781659bc7e90b8a87e429b151d9ff2ff9;hb=c21722b0a369bad430dc8c06d645cfd75854a6ec;hpb=1227625a12a66e0ded78a1997c2d23f23202a382 diff --git a/restore/restore.c b/restore/restore.c index 533ae5b..94e0bb6 100644 --- a/restore/restore.c +++ b/restore/restore.c @@ -1,8 +1,9 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 - * + * Remy Card , 1994-1997 + * Stelian Pop , 1999-2000 + * Stelian Pop - AlcĂ´ve , 2000-2002 */ /* @@ -17,11 +18,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -39,22 +36,38 @@ */ #ifndef lint -static char sccsid[] = "@(#)restore.c 8.3 (Berkeley) 9/13/94"; +static const char rcsid[] = + "$Id: restore.c,v 1.36 2005/03/18 22:12:55 stelian Exp $"; #endif /* not lint */ +#include #include -#include #ifdef __linux__ +#include #include +#include +#ifdef HAVE_EXT2FS_EXT2_FS_H +#include +#else #include +#endif #include #else /* __linux__ */ +#ifdef sunos +#include +#include +#else #include +#endif #endif /* __linux__ */ +#include + +#include #include #include +#include #ifdef __linux__ #include @@ -70,17 +83,26 @@ static char *keyval __P((int)); * List entries on the tape. */ long -listfile(name, ino, type) - char *name; - ino_t ino; - int type; +listfile(char *name, dump_ino_t ino, int type) { long descend = hflag ? GOOD : FAIL; +#ifdef USE_QFA + long tnum; + long long tpos; +#endif if (TSTINO(ino, dumpmap) == 0) return (descend); - vprintf(stdout, "%s", type == LEAF ? "leaf" : "dir "); - fprintf(stdout, "%10d\t%s\n", ino, name); + Vprintf(stdout, "%s", type == LEAF ? "leaf" : "dir "); +#ifdef USE_QFA + if (tapeposflag) { /* add QFA positions to output */ + (void)Inode2Tapepos(ino, &tnum, &tpos, 1); + fprintf(stdout, "%10lu\t%ld\t%lld\t%s\n", (unsigned long)ino, + tnum, tpos, name); + } + else +#endif + fprintf(stdout, "%10lu\t%s\n", (unsigned long)ino, name); return (descend); } @@ -89,23 +111,20 @@ listfile(name, ino, type) * Request that new entries be extracted. */ long -addfile(name, ino, type) - char *name; - ino_t ino; - int type; +addfile(char *name, dump_ino_t ino, int type) { - register struct entry *ep; + struct entry *ep, *np; long descend = hflag ? GOOD : FAIL; char buf[100]; if (TSTINO(ino, dumpmap) == 0) { - dprintf(stdout, "%s: not on the tape\n", name); + Dprintf(stdout, "%s: not on the tape\n", name); return (descend); } if (ino == WINO && command == 'i' && !vflag) return (descend); if (!mflag) { - (void) sprintf(buf, "./%u", ino); + (void) snprintf(buf, sizeof(buf), "./%lu", (unsigned long)ino); name = buf; if (type == NODE) { (void) genliteraldir(name, ino); @@ -119,9 +138,18 @@ addfile(name, ino, type) return (descend); } type |= LINK; + for (np = ep->e_links; np; np = np->e_links) + if (strcmp(name, myname(np)) == 0) { + np->e_flags |= NEW; + return (descend); + } } ep = addentry(name, ino, type); +#ifdef USE_QFA + if ((type == NODE) && (!createtapeposflag)) +#else if (type == NODE) +#endif newnode(ep); ep->e_flags |= NEW; return (descend); @@ -133,10 +161,7 @@ addfile(name, ino, type) */ /* ARGSUSED */ long -deletefile(name, ino, type) - char *name; - ino_t ino; - int type; +deletefile(char *name, dump_ino_t ino, UNUSED(int type)) { long descend = hflag ? GOOD : FAIL; struct entry *ep; @@ -153,7 +178,7 @@ deletefile(name, ino, type) return (descend); } -/* +/* * The following four routines implement the incremental * restore algorithm. The first removes old entries, the second * does renames and calculates the extraction list, the third @@ -162,7 +187,7 @@ deletefile(name, ino, type) * * Directories cannot be immediately deleted, as they may have * other files in them which need to be moved out first. As - * directories to be deleted are found, they are put on the + * directories to be deleted are found, they are put on the * following deletion list. After all deletions and renames * are done, this list is actually deleted. */ @@ -174,14 +199,14 @@ static struct entry *removelist; * Remove directories from the lookup chains. */ void -removeoldleaves() +removeoldleaves(void) { - register struct entry *ep, *nextep; - register ino_t i, mydirino; + struct entry *ep, *nextep; + dump_ino_t i, mydirino; - vprintf(stdout, "Mark entries to be removed.\n"); - if (ep = lookupino(WINO)) { - vprintf(stdout, "Delete whiteouts\n"); + Vprintf(stdout, "Mark entries to be removed.\n"); + if ((ep = lookupino(WINO))) { + Vprintf(stdout, "Delete whiteouts\n"); for ( ; ep != NULL; ep = nextep) { nextep = ep->e_links; mydirino = ep->e_parent->e_ino; @@ -194,8 +219,11 @@ removeoldleaves() continue; #ifdef __linux__ (void)fprintf(stderr, "BUG! Should call delwhiteout\n"); +#else +#ifdef sunos #else delwhiteout(ep); +#endif #endif freeentry(ep); } @@ -207,7 +235,7 @@ removeoldleaves() if (TSTINO(i, usedinomap)) continue; for ( ; ep != NULL; ep = ep->e_links) { - dprintf(stdout, "%s: REMOVE\n", myname(ep)); + Dprintf(stdout, "%s: REMOVE\n", myname(ep)); if (ep->e_type == LEAF) { removeleaf(ep); freeentry(ep); @@ -231,12 +259,9 @@ removeoldleaves() * Renames are done at the same time. */ long -nodeupdates(name, ino, type) - char *name; - ino_t ino; - int type; +nodeupdates(char *name, dump_ino_t ino, int type) { - register struct entry *ep, *np, *ip; + struct entry *ep, *np, *ip; long descend = GOOD; int lookuptype = 0; int key = 0; @@ -247,7 +272,7 @@ nodeupdates(name, ino, type) # define MODECHG 0x8 /* mode of inode changed */ /* - * This routine is called once for each element in the + * This routine is called once for each element in the * directory hierarchy, with a full path name. * The "type" value is incorrectly specified as LEAF for * directories that are not on the dump tape. @@ -300,7 +325,7 @@ nodeupdates(name, ino, type) removeleaf(np); freeentry(np); } else { - dprintf(stdout, "name/inode conflict, mktempname %s\n", + Dprintf(stdout, "name/inode conflict, mktempname %s\n", myname(np)); mktempname(np); } @@ -328,7 +353,7 @@ nodeupdates(name, ino, type) */ case INOFND|NAMEFND: ip->e_flags |= KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(ip)); break; @@ -364,7 +389,7 @@ nodeupdates(name, ino, type) if (type == NODE) newnode(ep); ep->e_flags |= NEW|KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(ep)); break; @@ -388,7 +413,7 @@ nodeupdates(name, ino, type) renameit(myname(ip), name); moveentry(ip, name); ip->e_flags |= KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(ip)); break; } @@ -401,7 +426,7 @@ nodeupdates(name, ino, type) } ep = addentry(name, ino, type|LINK); ep->e_flags |= NEW; - dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name, flagvalues(ep)); break; @@ -418,14 +443,14 @@ nodeupdates(name, ino, type) if (type == NODE) newnode(ep); ep->e_flags |= NEW|KEEP; - dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name, flagvalues(ep)); break; } if (type == LEAF && lookuptype != LINK) np->e_flags |= EXTRACT; np->e_flags |= KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(np)); break; @@ -438,7 +463,7 @@ nodeupdates(name, ino, type) * that we need to rename, so we delete it from the symbol * table, and put it on the list to be deleted eventually. * Conversely if a directory is to be created, it must be - * done immediately, rather than waiting until the + * done immediately, rather than waiting until the * extraction phase. */ case ONTAPE|INOFND|MODECHG: @@ -449,8 +474,12 @@ nodeupdates(name, ino, type) } if (ip->e_type == LEAF) { /* changing from leaf to node */ - removeleaf(ip); - freeentry(ip); + for ( ; ip != NULL; ip = ip->e_links) { + if (ip->e_type != LEAF) + badentry(ip, "NODE and LEAF links to same inode"); + removeleaf(ip); + freeentry(ip); + } ip = addentry(name, ino, type); newnode(ip); } else { @@ -463,16 +492,16 @@ nodeupdates(name, ino, type) ip = addentry(name, ino, type); } ip->e_flags |= NEW|KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(ip)); break; /* - * A hard link to a diirectory that has been removed. + * A hard link to a directory that has been removed. * Ignore it. */ case NAMEFND: - dprintf(stdout, "[%s] %s: Extraneous name\n", keyval(key), + Dprintf(stdout, "[%s] %s: Extraneous name\n", keyval(key), name); descend = FAIL; break; @@ -484,10 +513,11 @@ nodeupdates(name, ino, type) * for it, we discard the name knowing that it will be on the * next incremental tape. */ - case NULL: + case 0: if (compare_ignore_not_found) break; - fprintf(stderr, "%s: (inode %d) not found on tape\n", - name, ino); + fprintf(stderr, "%s: (inode %lu) not found on tape\n", + name, (unsigned long)ino); + do_compare_error; break; /* @@ -509,7 +539,7 @@ nodeupdates(name, ino, type) default: panic("[%s] %s: impossible state\n", keyval(key), name); break; - } + } return (descend); } @@ -517,8 +547,7 @@ nodeupdates(name, ino, type) * Calculate the active flags in a key. */ static char * -keyval(key) - int key; +keyval(int key) { static char keybuf[32]; @@ -539,23 +568,28 @@ keyval(key) * Find unreferenced link names. */ void -findunreflinks() +findunreflinks(void) { - register struct entry *ep, *np; - register ino_t i; + struct entry *ep, *np; + dump_ino_t i; + int j; - vprintf(stdout, "Find unreferenced names.\n"); + Vprintf(stdout, "Find unreferenced names.\n"); for (i = ROOTINO; i < maxino; i++) { ep = lookupino(i); if (ep == NULL || ep->e_type == LEAF || TSTINO(i, dumpmap) == 0) continue; - for (np = ep->e_entries; np != NULL; np = np->e_sibling) { - if (np->e_flags == 0) { - dprintf(stdout, - "%s: remove unreferenced name\n", - myname(np)); - removeleaf(np); - freeentry(np); + if (ep->e_entries == NULL) + continue; + for (j = 0; j < DIRHASH_SIZE; j++) { + for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) { + if (np->e_flags == 0) { + Dprintf(stdout, + "%s: remove unreferenced name\n", + myname(np)); + removeleaf(np); + freeentry(np); + } } } } @@ -563,15 +597,19 @@ findunreflinks() * Any leaves remaining in removed directories is unreferenced. */ for (ep = removelist; ep != NULL; ep = ep->e_next) { - for (np = ep->e_entries; np != NULL; np = np->e_sibling) { - if (np->e_type == LEAF) { - if (np->e_flags != 0) - badentry(np, "unreferenced with flags"); - dprintf(stdout, - "%s: remove unreferenced name\n", - myname(np)); - removeleaf(np); - freeentry(np); + if (ep->e_entries == NULL) + continue; + 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) + badentry(np, "unreferenced with flags"); + Dprintf(stdout, + "%s: remove unreferenced name\n", + myname(np)); + removeleaf(np); + freeentry(np); + } } } } @@ -587,20 +625,29 @@ findunreflinks() * time O(N). */ void -removeoldnodes() +removeoldnodes(void) { - register struct entry *ep, **prev; + struct entry *ep, **prev; long change; - vprintf(stdout, "Remove old nodes (directories).\n"); + Vprintf(stdout, "Remove old nodes (directories).\n"); do { change = 0; prev = &removelist; for (ep = removelist; ep != NULL; ep = *prev) { + int docont = 0; if (ep->e_entries != NULL) { - prev = &ep->e_next; - continue; + int i; + for (i = 0; i < DIRHASH_SIZE; i++) { + if (ep->e_entries[i] != NULL) { + prev = &ep->e_next; + docont = 1; + break; + } + } } + if (docont) + continue; *prev = ep->e_next; removenode(ep); freeentry(ep); @@ -615,11 +662,17 @@ removeoldnodes() /* current copy of this file on disk. If do_compare is 0, then just */ /* make our caller think we did it--this is used to handle hard links */ /* to files and devices. */ +static void compare_entry(struct entry *ep, int do_compare) { - if ((ep->e_flags & (NEW|EXTRACT)) == 0) + if ((ep->e_flags & (NEW|EXTRACT)) == 0) { badentry(ep, "unexpected file on tape"); - if (do_compare) (void) comparefile(myname(ep)); + do_compare_error; + } + if (do_compare) { + (void) comparefile(myname(ep)); + skipxattr(); + } ep->e_flags &= ~(NEW|EXTRACT); } @@ -627,10 +680,10 @@ compare_entry(struct entry *ep, int do_compare) * This is the routine used to compare files for the 'C' command. */ void -compareleaves() +compareleaves(void) { - register struct entry *ep; - ino_t first; + struct entry *ep; + dump_ino_t first; long curvol; first = lowerbnd(ROOTINO); @@ -649,6 +702,7 @@ compareleaves() if (ep == NULL) panic("%d: bad first\n", first); fprintf(stderr, "%s: not found on tape\n", myname(ep)); + do_compare_error; ep->e_flags &= ~(NEW|EXTRACT); first = lowerbnd(first); } @@ -660,14 +714,17 @@ compareleaves() * on the next incremental tape. */ if (first != curfile.ino) { - fprintf(stderr, "expected next file %d, got %d\n", - first, curfile.ino); + fprintf(stderr, "expected next file %ld, got %lu\n", + (long)first, (unsigned long)curfile.ino); + do_compare_error; skipfile(); goto next; } ep = lookupino(curfile.ino); - if (ep == NULL) + if (ep == NULL) { panic("unknown file on tape\n"); + do_compare_error; + } compare_entry(ep, 1); for (ep = ep->e_links; ep != NULL; ep = ep->e_links) { compare_entry(ep, 0); @@ -684,6 +741,25 @@ compareleaves() curvol = volno; } } + /* + * If we encounter the end of the tape and the next available + * file is not the one which we expect then we have missed one + * or more files. Since we do not request files that were not + * on the tape, the lost files must have been due to a tape + * read error, or a file that was removed while the dump was + * in progress. + */ + first = lowerbnd(first); + while (first < curfile.ino) { + ep = lookupino(first); + if (ep == NULL) + panic("%d: bad first\n", first); + fprintf(stderr, "%s: (inode %lu) not found on tape\n", + myname(ep), (unsigned long)first); + do_compare_error; + ep->e_flags &= ~(NEW|EXTRACT); + first = lowerbnd(first); + } } /* @@ -691,17 +767,17 @@ compareleaves() * Extract new leaves. */ void -createleaves(symtabfile) - char *symtabfile; +createleaves(char *symtabfile) { - register struct entry *ep; - ino_t first; + struct entry *ep; + dump_ino_t first; long curvol; + int doremove; if (command == 'R') { - vprintf(stdout, "Continue extraction of new leaves\n"); + Vprintf(stdout, "Continue extraction of new leaves\n"); } else { - vprintf(stdout, "Extract new leaves.\n"); + Vprintf(stdout, "Extract new leaves.\n"); dumpsymtable(symtabfile, volno); } first = lowerbnd(ROOTINO); @@ -719,20 +795,21 @@ createleaves(symtabfile) ep = lookupino(first); if (ep == NULL) panic("%d: bad first\n", first); - fprintf(stderr, "%s: not found on tape\n", myname(ep)); + fprintf(stderr, "%s: (inode %lu) not found on tape\n", + myname(ep), (unsigned long)first); ep->e_flags &= ~(NEW|EXTRACT); first = lowerbnd(first); } /* * If we find files on the tape that have no corresponding * directory entries, then we must have found a file that - * was created while the dump was in progress. Since we have + * was created while the dump was in progress. Since we have * no name for it, we discard it knowing that it will be * on the next incremental tape. */ if (first != curfile.ino) { - fprintf(stderr, "expected next file %d, got %d\n", - first, curfile.ino); + fprintf(stderr, "expected next file %ld, got %lu\n", + (long)first, (unsigned long)curfile.ino); skipfile(); goto next; } @@ -744,26 +821,47 @@ createleaves(symtabfile) /* * If the file is to be extracted, then the old file must * be removed since its type may change from one leaf type - * to another (eg "file" to "character special"). + * to another (e.g. "file" to "character special"). */ - if ((ep->e_flags & EXTRACT) != 0) { - removeleaf(ep); - ep->e_flags &= ~REMOVED; - } - (void) extractfile(myname(ep)); + if ((ep->e_flags & EXTRACT) != 0) + doremove = 1; + else + doremove = 0; + (void) extractfile(ep, doremove); + skipxattr(); ep->e_flags &= ~(NEW|EXTRACT); + /* * We checkpoint the restore after every tape reel, so - * as to simplify the amount of work re quired by the + * as to simplify the amount of work required by the * 'R' command. */ - next: +next: if (curvol != volno) { dumpsymtable(symtabfile, volno); skipmaps(); curvol = volno; } } + /* + * If we encounter the end of the tape and the next available + * file is not the one which we expect then we have missed one + * or more files. Since we do not request files that were not + * on the tape, the lost files must have been due to a tape + * read error, or a file that was removed while the dump was + * in progress. + */ + first = lowerbnd(first); + while (first < curfile.ino) { + ep = lookupino(first); + if (ep == NULL) + panic("%d: bad first\n", first); + fprintf(stderr, "%s: (inode %lu) not found on tape\n", + myname(ep), (unsigned long)first); + do_compare_error; + ep->e_flags &= ~(NEW|EXTRACT); + first = lowerbnd(first); + } } /* @@ -771,20 +869,37 @@ createleaves(symtabfile) * Efficiently extract a subset of the files on a tape. */ void -createfiles() +createfiles(void) { - register ino_t first, next, last; - register struct entry *ep; + dump_ino_t first, next, last; + struct entry *ep; long curvol; +#ifdef USE_QFA + long tnum, tmpcnt; + long long tpos, curtpos = 0; + time_t tistart, tiend, titaken; + int volChg; +#endif - vprintf(stdout, "Extract requested files\n"); + Vprintf(stdout, "Extract requested files\n"); curfile.action = SKIP; - getvol((long)1); +#ifdef USE_QFA + if (tapeposflag) + curfile.ino = 0; + else +#endif + if (volinfo[1] == ROOTINO) + curfile.ino = 0; + else + getvol((long)1); skipmaps(); skipdirs(); first = lowerbnd(ROOTINO); last = upperbnd(maxino - 1); for (;;) { +#ifdef USE_QFA + tmpcnt = 1; +#endif first = lowerbnd(first); last = upperbnd(last); /* @@ -798,7 +913,21 @@ createfiles() */ while (curfile.ino > last) { curfile.action = SKIP; - getvol((long)0); + if (!pipein) + getvol((long)0); + if (curfile.ino == maxino) { + next = lowerbnd(first); + while (next < curfile.ino) { + ep = lookupino(next); + if (ep == NULL) + panic("corrupted symbol table\n"); + fprintf(stderr, "%s: (inode %lu) not found on tape\n", + myname(ep), (unsigned long)next); + ep->e_flags &= ~NEW; + next = lowerbnd(next); + } + return; + } skipmaps(); skipdirs(); } @@ -808,13 +937,82 @@ createfiles() * or an out of order volume change is encountered */ next = lowerbnd(curfile.ino); +#ifdef USE_QFA + tistart = time(NULL); + if (tapeposflag) { + /* get tape position for inode */ + (void)Inode2Tapepos(next, &tnum, &tpos, 0); + if (tpos != 0) { + if (tnum != volno) { + (void)RequestVol(tnum); + volChg = 1; + } else { + volChg = 0; + } + if (GetTapePos(&curtpos) == 0) { + /* curtpos +1000 ???, some drives + * might be too slow */ + if (((tpos > (curtpos + 1000)) && (volChg == 0)) || ((tpos != curtpos) && (volChg == 1))) { + volChg = 0; +#ifdef DEBUG_QFA + msg("positioning tape %ld from %lld to %lld for inode %lu ...\n", volno, curtpos, tpos, (unsigned long)next); +#endif + if (GotoTapePos(tpos) == 0) { +#ifdef DEBUG_QFA + if (GetTapePos(&curtpos) == 0) { + msg("before resnyc at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name); + } +#endif + ReReadInodeFromTape(next); +#ifdef DEBUG_QFA + if (GetTapePos(&curtpos) == 0) { + msg("after resnyc at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name); + } +#endif + } + } else { +#ifdef DEBUG_QFA + msg("already at tape %ld position %ld for inode %lu ...\n", volno, tpos, (unsigned long)next); +#endif + } + } + } + } + else +#endif /* USA_QFA */ + if (volinfo[1] == ROOTINO) { + int i, goodvol = 1; + + for (i = 1; i < (int)TP_NINOS && volinfo[i] != 0; ++i) + if (volinfo[i] < next) + goodvol = i; + + if (goodvol != volno) + RequestVol(goodvol); + } + do { curvol = volno; - while (next > curfile.ino && volno == curvol) + while (next > curfile.ino && volno == curvol) { +#ifdef USE_QFA + ++tmpcnt; +#endif skipfile(); + } skipmaps(); skipdirs(); } while (volno == curvol + 1); +#ifdef USE_QFA + tiend = time(NULL); + titaken = tiend - tistart; +#ifdef DEBUG_QFA + if (titaken / 60 > 0) + msg("%ld reads took %d:%02d:%02d\n", + tmpcnt, titaken / 3600, + (titaken % 3600) / 60, titaken % 60); +#endif +#endif /* USE_QFA */ + /* * If volume change out of order occurred the * current state must be recalculated @@ -835,7 +1033,11 @@ createfiles() ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); - fprintf(stderr, "%s: not found on tape\n", myname(ep)); +#ifdef USE_QFA + if (!createtapeposflag) +#endif + fprintf(stderr, "%s: (inode %lu) not found on tape\n", + myname(ep), (unsigned long)next); ep->e_flags &= ~NEW; next = lowerbnd(next); } @@ -847,7 +1049,23 @@ createfiles() ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); - (void) extractfile(myname(ep)); +#ifdef USE_QFA + if (createtapeposflag) { +#ifdef DEBUG_QFA + msg("inode %ld at tapepos %ld\n", curfile.ino, curtapepos); +#endif + sprintf(gTps, "%ld\t%ld\t%lld\n", (unsigned long)curfile.ino, volno, curtapepos); + if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) + warn("error writing tapepos file.\n"); + skipfile(); + } else { +#endif /* USE_QFA */ + (void) extractfile(ep, 0); + skipxattr(); + +#ifdef USE_QFA + } +#endif /* USE_QFA */ ep->e_flags &= ~NEW; if (volno != curvol) skipmaps(); @@ -859,26 +1077,29 @@ createfiles() * Add links. */ void -createlinks() +createlinks(void) { - register struct entry *np, *ep; - register ino_t i; + struct entry *np, *ep; + dump_ino_t i; char name[BUFSIZ]; - if (ep = lookupino(WINO)) { - vprintf(stdout, "Add whiteouts\n"); + if ((ep = lookupino(WINO))) { + Vprintf(stdout, "Add whiteouts\n"); for ( ; ep != NULL; ep = ep->e_links) { if ((ep->e_flags & NEW) == 0) continue; #ifdef __linux__ (void)fprintf(stderr, "BUG! Should call addwhiteout\n"); +#else +#ifdef sunos #else (void) addwhiteout(myname(ep)); +#endif #endif ep->e_flags &= ~NEW; } } - vprintf(stdout, "Add links\n"); + Vprintf(stdout, "Add links\n"); for (i = ROOTINO; i < maxino; i++) { ep = lookupino(i); if (ep == NULL) @@ -903,12 +1124,12 @@ createlinks() * that no temporary names remain. */ void -checkrestore() +checkrestore(void) { - register struct entry *ep; - register ino_t i; + struct entry *ep; + dump_ino_t i; - vprintf(stdout, "Check the symbol table.\n"); + Vprintf(stdout, "Check the symbol table.\n"); for (i = WINO; i < maxino; i++) { for (ep = lookupino(i); ep != NULL; ep = ep->e_links) { ep->e_flags &= ~KEEP; @@ -925,10 +1146,7 @@ checkrestore() * A paranoid check that things are as they should be. */ long -verifyfile(name, ino, type) - char *name; - ino_t ino; - int type; +verifyfile(char *name, dump_ino_t ino, int type) { struct entry *np, *ep; long descend = GOOD;