* 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@cybercable.fr>, 1999
+ * Stelian Pop <pop@cybercable.fr>, 1999-2000
*/
/*
#ifndef lint
static const char rcsid[] =
- "$Id: tape.c,v 1.9 1999/11/22 21:39:42 tiniou Exp $";
+ "$Id: tape.c,v 1.19 2000/08/19 22:39:35 stelian Exp $";
#endif /* not lint */
#include <sys/param.h>
static long fssize = MAXBSIZE;
static int mt = -1;
static int pipein = 0;
-static char magtape[NAME_MAX];
-static char magtapeprefix[NAME_MAX];
+static char magtape[MAXPATHLEN];
+static char magtapeprefix[MAXPATHLEN];
static int blkcnt;
static int numtrec;
static char *tapebuf;
static void xtrmapskip __P((char *, size_t));
static void xtrskip __P((char *, size_t));
+#define COMPARE_ONTHEFLY 1
+
+#if COMPARE_ONTHEFLY
+static int ifile; /* input file for compare */
+static int cmperror; /* compare error */
+static void xtrcmpfile __P((char *, size_t));
+static void xtrcmpskip __P((char *, size_t));
+#endif
+
static int readmapflag;
/*
}
setuid(getuid()); /* no longer need or want root privileges */
if (Mflag) {
- strncpy(magtapeprefix, source, NAME_MAX);
- magtapeprefix[NAME_MAX-1] = '\0';
- snprintf(magtape, NAME_MAX, "%s%03d", source, 1);
+ strncpy(magtapeprefix, source, MAXPATHLEN);
+ magtapeprefix[MAXPATHLEN-1] = '\0';
+ snprintf(magtape, MAXPATHLEN, "%s%03d", source, 1);
}
else
- strncpy(magtape, source, NAME_MAX);
- magtape[NAME_MAX - 1] = '\0';
+ strncpy(magtape, source, MAXPATHLEN);
+ magtape[MAXPATHLEN - 1] = '\0';
}
void
}
if (vflag || command == 't' || command == 'C')
printdumpinfo();
- if (filesys == NULL) {
- filesys = spcl.c_filesys;
+ if (filesys[0] == '\0') {
+ char *dirptr;
+ strncpy(filesys, spcl.c_filesys, NAMELEN);
+ filesys[NAMELEN - 1] = '\0';
+ dirptr = strstr(filesys, " (dir");
+ if (dirptr != NULL)
+ *dirptr = '\0';
}
dumptime = spcl.c_ddate;
dumpdate = spcl.c_date;
if (spcl.c_type != TS_CLRI)
errx(1, "Cannot find file removal list");
maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1;
- Dprintf(stdout, "maxino = %ld\n", maxino);
+ Dprintf(stdout, "maxino = %ld\n", (long)maxino);
map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
if (map == NULL)
- panic("no memory for active inode map\n");
+ errx(1, "no memory for active inode map");
usedinomap = map;
curfile.action = USING;
getfile(xtrmap, xtrmapskip);
errx(1, "Cannot find file dump list");
map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
if (map == (char *)NULL)
- panic("no memory for file dump list\n");
+ errx(1, "no memory for file dump list");
dumpmap = map;
curfile.action = USING;
getfile(xtrmap, xtrmapskip);
do {
fprintf(stderr, "Specify next volume #: ");
(void) fflush(stderr);
- (void) fgets(buf, BUFSIZ, terminal);
+ (void) fgets(buf, TP_BSIZE, terminal);
} while (!feof(terminal) && buf[0] == '\n');
if (feof(terminal))
exit(1);
}
closemt();
if (Mflag) {
- snprintf(magtape, NAME_MAX, "%s%03ld", magtapeprefix, newvol);
- magtape[NAME_MAX - 1] = '\0';
+ snprintf(magtape, MAXPATHLEN, "%s%03ld", magtapeprefix, newvol);
+ magtape[MAXPATHLEN - 1] = '\0';
}
if (!Mflag || haderror) {
haderror = 0;
fprintf(stderr, "Enter ``none'' if there are no more tapes\n");
fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape);
(void) fflush(stderr);
- (void) fgets(buf, BUFSIZ, terminal);
+ (void) fgets(buf, TP_BSIZE, terminal);
if (feof(terminal))
exit(1);
if (!strcmp(buf, "none\n")) {
#endif
if (spcl.c_host[0] == '\0')
return;
- fprintf(stderr, "Level %d dump of %s on %s:%s\n",
+ fprintf(stdout, "Level %d dump of %s on %s:%s\n",
spcl.c_level, spcl.c_filesys, spcl.c_host, spcl.c_dev);
- fprintf(stderr, "Label: %s\n", spcl.c_label);
+ fprintf(stdout, "Label: %s\n", spcl.c_label);
}
int
return;
}
+#if COMPARE_ONTHEFLY
+/*
+ * Compare the next block of a file.
+ */
+static void
+xtrcmpfile(char *buf, size_t size)
+{
+ static char cmpbuf[MAXBSIZE];
+
+ if (cmperror)
+ return;
+
+ if (read(ifile, cmpbuf, size) != size) {
+ fprintf(stderr, "%s: size has changed.\n",
+ curfile.name);
+ cmperror = 1;
+ return;
+ }
+
+ if (memcmp(buf, cmpbuf, size) != 0) {
+ fprintf(stderr, "%s: tape and disk copies are different\n",
+ curfile.name);
+ cmperror = 1;
+ return;
+ }
+}
+
+/*
+ * Skip over a hole in a file.
+ */
+static void
+xtrcmpskip(char *buf, size_t size)
+{
+ static char cmpbuf[MAXBSIZE];
+ int i;
+
+ if (cmperror)
+ return;
+
+ if (read(ifile, cmpbuf, size) != size) {
+ fprintf(stderr, "%s: size has changed.\n",
+ curfile.name);
+ cmperror = 1;
+ return;
+ }
+
+ for (i = 0; i < size; ++i)
+ if (cmpbuf[i] != '\0') {
+ fprintf(stderr, "%s: tape and disk copies are different\n",
+ curfile.name);
+ cmperror = 1;
+ return;
+ }
+}
+#endif /* COMPARE_ONTHEFLY */
+
+#if !COMPARE_ONTHEFLY
static int
do_cmpfiles(int fd_tape, int fd_disk, long size)
{
if (stat(tapefile, &sbuf_tape) != 0) {
panic("Can't lstat tmp file %s: %s\n", tapefile,
strerror(errno));
+ compare_errors = 1;
}
if (sbuf_disk->st_size != sbuf_tape.st_size) {
fprintf(stderr,
"%s: size changed from %ld to %ld.\n",
diskfile, (long)sbuf_tape.st_size, (long)sbuf_disk->st_size);
+ compare_errors = 1;
#ifdef COMPARE_FAIL_KEEP_FILE
return (0);
#else
if ((fd_tape = open(tapefile, O_RDONLY)) < 0) {
panic("Can't open %s: %s\n", tapefile, strerror(errno));
+ compare_errors = 1;
}
if ((fd_disk = open(diskfile, O_RDONLY)) < 0) {
close(fd_tape);
panic("Can't open %s: %s\n", diskfile, strerror(errno));
+ compare_errors = 1;
}
if (do_cmpfiles(fd_tape, fd_disk, sbuf_tape.st_size)) {
diskfile);
close(fd_tape);
close(fd_disk);
+ compare_errors = 1;
#ifdef COMPARE_FAIL_KEEP_FILE
/* rename the file to live in /tmp */
/* rename `tapefile' to /tmp/<basename of diskfile> */
return (1);
#endif
}
+#endif /* !COMPARE_ONTHEFLY */
+#if !COMPARE_ONTHEFLY
static char tmpfilename[MAXPATHLEN];
+#endif
void
comparefile(char *name)
{
- static char *tmpfile = NULL;
int mode;
- struct stat sb, stemp;
+ struct stat sb;
int r;
+#if !COMPARE_ONTHEFLY
+ static char *tmpfile = NULL;
+ struct stat stemp;
+#endif
if ((r = lstat(name, &sb)) != 0) {
warn("%s: does not exist (%d)", name, r);
+ compare_errors = 1;
skipfile();
return;
}
if (sb.st_mode != mode) {
fprintf(stderr, "%s: mode changed from 0%o to 0%o.\n",
name, mode & 07777, sb.st_mode & 07777);
+ compare_errors = 1;
}
switch (mode & IFMT) {
default:
if (!(sb.st_mode & S_IFLNK)) {
fprintf(stderr, "%s: is no longer a symbolic link\n",
name);
+ compare_errors = 1;
return;
}
lnkbuf[0] = '\0';
fprintf(stderr,
"%s: zero length symbolic link (ignored)\n",
name);
+ compare_errors = 1;
return;
}
if ((lsize = readlink(name, lbuf, MAXPATHLEN)) < 0) {
panic("readlink of %s failed: %s", name,
strerror(errno));
+ compare_errors = 1;
}
lbuf[lsize] = 0;
if (strcmp(lbuf, lnkbuf) != 0) {
fprintf(stderr,
"%s: symbolic link changed from %s to %s.\n",
name, lnkbuf, lbuf);
+ compare_errors = 1;
return;
}
return;
if (!(sb.st_mode & (S_IFCHR|S_IFBLK))) {
fprintf(stderr, "%s: no longer a special file\n",
name);
+ compare_errors = 1;
skipfile();
return;
}
(int)curfile.dip->di_rdev & 0xff,
((int)sb.st_rdev >> 8) & 0xff,
(int)sb.st_rdev & 0xff);
+ compare_errors = 1;
}
skipfile();
return;
case IFREG:
+#if COMPARE_ONTHEFLY
+ if ((ifile = open(name, O_RDONLY)) < 0) {
+ panic("Can't open %s: %s\n", name, strerror(errno));
+ skipfile();
+ compare_errors = 1;
+ }
+ else {
+ cmperror = 0;
+ getfile(xtrcmpfile, xtrcmpskip);
+ if (!cmperror) {
+ char c;
+ if (read(ifile, &c, 1) != 0) {
+ fprintf(stderr, "%s: size has changed.\n",
+ name);
+ cmperror = 1;
+ }
+ }
+ if (cmperror)
+ compare_errors = 1;
+ close(ifile);
+ }
+#else
if (tmpfile == NULL) {
/* argument to mktemp() must not be in RO space: */
snprintf(tmpfilename, sizeof(tmpfilename), "%s/restoreCXXXXXX", tmpdir);
cmpfiles(tmpfile, name, &sb);
unlink(tmpfile);
#endif
+#endif /* COMPARE_ONTHEFLY */
return;
}
/* NOTREACHED */
fprintf(stderr, "File header, ino %lu", (unsigned long)previno);
break;
case TS_ADDR:
- fprintf(stderr, "File continuation header, ino %ld", previno);
+ fprintf(stderr, "File continuation header, ino %ld", (long)previno);
break;
case TS_END:
fprintf(stderr, "End of tape header");