* Ported to Linux's Second Extended File System as part of the
* dump and restore backup suit
* Remy Card <card@Linux.EU.Org>, 1994-1997
- * Stelian Pop <pop@noos.fr>, 1999-2000
- * Stelian Pop <pop@noos.fr> - Alcôve <www.alcove.fr>, 2000
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
*/
/*
#ifndef lint
static const char rcsid[] =
- "$Id: restore.c,v 1.17 2001/04/26 08:28:29 stelian Exp $";
+ "$Id: restore.c,v 1.26 2002/01/25 15:08:59 stelian Exp $";
#endif /* not lint */
#include <config.h>
#include <sys/param.h>
#include <sys/time.h>
#include <time.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
#include <linux/ext2_fs.h>
+#endif
#include <bsdcompat.h>
#else /* __linux__ */
#include <ufs/ufs/dinode.h>
long descend = hflag ? GOOD : FAIL;
#ifdef USE_QFA
long tnum;
- long tpos;
+ long long tpos;
#endif
if (TSTINO(ino, dumpmap) == 0)
#ifdef USE_QFA
if (tapeposflag) { /* add QFA positions to output */
(void)Inode2Tapepos(ino, &tnum, &tpos, 1);
- fprintf(stdout, "%10lu\t%ld\t%ld\t%s\n", (unsigned long)ino,
+ fprintf(stdout, "%10lu\t%ld\t%lld\t%s\n", (unsigned long)ino,
tnum, tpos, name);
}
else
long
addfile(char *name, dump_ino_t ino, int type)
{
- register struct entry *ep, *np;
+ struct entry *ep, *np;
long descend = hflag ? GOOD : FAIL;
char buf[100];
void
removeoldleaves(void)
{
- register struct entry *ep, *nextep;
- register dump_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))) {
long
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;
if (compare_ignore_not_found) break;
fprintf(stderr, "%s: (inode %lu) not found on tape\n",
name, (unsigned long)ino);
- compare_errors = 1;
+ do_compare_error;
break;
/*
void
findunreflinks(void)
{
- register struct entry *ep, *np;
- register dump_ino_t i;
+ struct entry *ep, *np;
+ dump_ino_t i;
Vprintf(stdout, "Find unreferenced names.\n");
for (i = ROOTINO; i < maxino; i++) {
void
removeoldnodes(void)
{
- register struct entry *ep, **prev;
+ struct entry *ep, **prev;
long change;
Vprintf(stdout, "Remove old nodes (directories).\n");
{
if ((ep->e_flags & (NEW|EXTRACT)) == 0) {
badentry(ep, "unexpected file on tape");
- compare_errors = 1;
+ do_compare_error;
}
if (do_compare) (void) comparefile(myname(ep));
ep->e_flags &= ~(NEW|EXTRACT);
void
compareleaves(void)
{
- register struct entry *ep;
+ struct entry *ep;
dump_ino_t first;
long curvol;
if (ep == NULL)
panic("%d: bad first\n", first);
fprintf(stderr, "%s: not found on tape\n", myname(ep));
- compare_errors = 1;
+ do_compare_error;
ep->e_flags &= ~(NEW|EXTRACT);
first = lowerbnd(first);
}
if (first != curfile.ino) {
fprintf(stderr, "expected next file %ld, got %lu\n",
(long)first, (unsigned long)curfile.ino);
- compare_errors = 1;
+ do_compare_error;
skipfile();
goto next;
}
ep = lookupino(curfile.ino);
if (ep == NULL) {
panic("unknown file on tape\n");
- compare_errors = 1;
+ do_compare_error;
}
compare_entry(ep, 1);
for (ep = ep->e_links; ep != NULL; ep = ep->e_links) {
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);
+ }
}
/*
void
createleaves(char *symtabfile)
{
- register struct entry *ep;
+ struct entry *ep;
dump_ino_t first;
long curvol;
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);
}
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);
+ }
}
/*
void
createfiles(void)
{
- register dump_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, tpos, curtpos, tmpcnt;
+ long tnum, tmpcnt;
+ long long tpos, curtpos;
time_t tistart, tiend, titaken;
#endif
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);
*/
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();
}
* might be too slow */
if (tpos > curtpos) {
#ifdef DEBUG_QFA
- msg("positioning tape %ld from %ld to %ld for inode %10lu ...\n", volno, curtpos, tpos, (unsigned long)next);
+ msg("positioning tape %ld from %lld to %lld for inode %10lu ...\n", volno, curtpos, tpos, (unsigned long)next);
#endif
if (GotoTapePos(tpos) == 0) {
#ifdef DEBUG_QFA
}
}
}
+ else
#endif /* USA_QFA */
+ if (volinfo[1] == ROOTINO) {
+ int i, goodvol = 1;
+
+ for (i = 1; i < TP_NINOS && volinfo[i] != 0; ++i)
+ if (volinfo[i] < next)
+ goodvol = i;
+
+ if (goodvol != volno)
+ RequestVol(goodvol);
+ }
do {
curvol = volno;
ep = lookupino(next);
if (ep == NULL)
panic("corrupted symbol table\n");
- fprintf(stderr, "%s: not found on tape\n", myname(ep));
+ fprintf(stderr, "%s: (inode %lu) not found on tape\n",
+ myname(ep), (unsigned long)next);
ep->e_flags &= ~NEW;
next = lowerbnd(next);
}
void
createlinks(void)
{
- register struct entry *np, *ep;
- register dump_ino_t i;
+ struct entry *np, *ep;
+ dump_ino_t i;
char name[BUFSIZ];
if ((ep = lookupino(WINO))) {
void
checkrestore(void)
{
- register struct entry *ep;
- register dump_ino_t i;
+ struct entry *ep;
+ dump_ino_t i;
Vprintf(stdout, "Check the symbol table.\n");
for (i = WINO; i < maxino; i++) {