/*
* Ported to Linux's Second Extended File System as part of the
* dump and restore backup suit
- * Remy Card <card@Linux.EU.Org>, 1994, 1995, 1996
- *
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <pop@cybercable.fr>, 1999
*/
/*
*/
#ifndef lint
-static char sccsid[] = "@(#)tape.c 8.9 (Berkeley) 5/1/95";
+static const char rcsid[] =
+ "$Id: tape.c,v 1.9 1999/11/22 21:39:42 tiniou Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/file.h>
-#include <sys/ioctl.h>
#include <sys/mtio.h>
#include <sys/stat.h>
#include <protocols/dumprestore.h>
#include <errno.h>
+#include <compaterr.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
static long fssize = MAXBSIZE;
static int mt = -1;
static int pipein = 0;
-static char magtape[BUFSIZ];
+static char magtape[NAME_MAX];
+static char magtapeprefix[NAME_MAX];
static int blkcnt;
static int numtrec;
static char *tapebuf;
static long blksread; /* blocks read since last header */
static long tpblksread = 0; /* TP_BSIZE blocks read */
static long tapesread;
-static jmp_buf restart;
+static sigjmp_buf restart;
static int gettingfile = 0; /* restart has a valid frame */
static char *host = NULL;
static int gethead __P((struct s_spcl *));
static void readtape __P((char *));
static void setdumpnum __P((void));
+static u_int swabi __P((u_int));
static u_long swabl __P((u_long));
-static u_char *swablong __P((u_char *, int));
-static u_char *swabshort __P((u_char *, int));
+static u_char *swab64 __P((u_char *, int));
+static u_char *swab32 __P((u_char *, int));
+static u_char *swab16 __P((u_char *, int));
static void terminateinput __P((void));
-static void xtrfile __P((char *, long));
-static void xtrlnkfile __P((char *, long));
-static void xtrlnkskip __P((char *, long));
-static void xtrmap __P((char *, long));
-static void xtrmapskip __P((char *, long));
-static void xtrskip __P((char *, long));
+static void xtrfile __P((char *, size_t));
+static void xtrlnkfile __P((char *, size_t));
+static void xtrlnkskip __P((char *, size_t));
+static void xtrmap __P((char *, size_t));
+static void xtrmapskip __P((char *, size_t));
+static void xtrskip __P((char *, size_t));
+
+static int readmapflag;
/*
* Set up an input source
*/
void
-setinput(source)
- char *source;
+setinput(char *source)
{
FLUSHTAPEBUF();
if (bflag)
source = strchr(host, ':');
*source++ = '\0';
if (rmthost(host) == 0)
- done(1);
+ exit(1);
} else
#endif
if (strcmp(source, "-") == 0) {
*/
terminal = fopen(_PATH_TTY, "r");
if (terminal == NULL) {
- (void)fprintf(stderr, "cannot open %s: %s\n",
- _PATH_TTY, strerror(errno));
+ warn("cannot open %s", _PATH_TTY);
terminal = fopen(_PATH_DEVNULL, "r");
- if (terminal == NULL) {
- (void)fprintf(stderr, "cannot open %s: %s\n",
- _PATH_DEVNULL, strerror(errno));
- done(1);
- }
+ if (terminal == NULL)
+ err(1, "cannot open %s", _PATH_DEVNULL);
}
pipein++;
}
setuid(getuid()); /* no longer need or want root privileges */
- (void) strcpy(magtape, source);
+ if (Mflag) {
+ strncpy(magtapeprefix, source, NAME_MAX);
+ magtapeprefix[NAME_MAX-1] = '\0';
+ snprintf(magtape, NAME_MAX, "%s%03d", source, 1);
+ }
+ else
+ strncpy(magtape, source, NAME_MAX);
+ magtape[NAME_MAX - 1] = '\0';
}
void
-newtapebuf(size)
- long size;
+newtapebuf(long size)
{
- static tapebufsize = -1;
+ static int tapebufsize = -1;
ntrec = size;
if (size <= tapebufsize)
if (tapebuf != NULL)
free(tapebuf);
tapebuf = malloc(size * TP_BSIZE);
- if (tapebuf == NULL) {
- fprintf(stderr, "Cannot allocate space for tape buffer\n");
- done(1);
- }
+ if (tapebuf == NULL)
+ errx(1, "Cannot allocate space for tape buffer");
tapebufsize = size;
}
* that it actually is a dump tape.
*/
void
-setup()
+setup(void)
{
int i, j, *ip;
struct stat stbuf;
- vprintf(stdout, "Verify tape and initialize maps\n");
+ Vprintf(stdout, "Verify tape and initialize maps\n");
#ifdef RRESTORE
if (host)
mt = rmtopen(magtape, 0);
mt = 0;
else
mt = open(magtape, O_RDONLY, 0);
- if (mt < 0) {
- fprintf(stderr, "%s: %s\n", magtape, strerror(errno));
- done(1);
- }
+ if (mt < 0)
+ err(1, "%s", magtape);
volno = 1;
setdumpnum();
FLUSHTAPEBUF();
blksread--;
tpblksread--;
cvtflag++;
- if (gethead(&spcl) == FAIL) {
- fprintf(stderr, "Tape is not a dump tape\n");
- done(1);
- }
+ if (gethead(&spcl) == FAIL)
+ errx(1, "Tape is not a dump tape");
fprintf(stderr, "Converting to new file system format.\n");
}
if (pipein) {
}
dumptime = spcl.c_ddate;
dumpdate = spcl.c_date;
- if (stat(".", &stbuf) < 0) {
- fprintf(stderr, "cannot stat .: %s\n", strerror(errno));
- done(1);
- }
- if (stbuf.st_blksize > 0 && stbuf.st_blksize <= MAXBSIZE)
+ if (stat(".", &stbuf) < 0)
+ err(1, "cannot stat .");
+ if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE )
+ fssize = TP_BSIZE;
+ if (stbuf.st_blksize >= TP_BSIZE && stbuf.st_blksize <= MAXBSIZE)
fssize = stbuf.st_blksize;
- if (((fssize - 1) & fssize) != 0) {
- fprintf(stderr, "bad block size %d\n", fssize);
- done(1);
- }
- if (spcl.c_volume != 1) {
- fprintf(stderr, "Tape is not volume 1 of the dump\n");
- done(1);
- }
+ if (((fssize - 1) & fssize) != 0)
+ errx(1, "bad block size %ld", fssize);
+ if (spcl.c_volume != 1)
+ errx(1, "Tape is not volume 1 of the dump");
if (gethead(&spcl) == FAIL) {
- dprintf(stdout, "header read failed at %d blocks\n", blksread);
+ Dprintf(stdout, "header read failed at %ld blocks\n", (long)blksread);
panic("no header after volume mark!\n");
}
findinode(&spcl);
- if (spcl.c_type != TS_CLRI) {
- fprintf(stderr, "Cannot find file removal list\n");
- done(1);
- }
+ if (spcl.c_type != TS_CLRI)
+ errx(1, "Cannot find file removal list");
maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1;
- dprintf(stdout, "maxino = %d\n", maxino);
+ Dprintf(stdout, "maxino = %ld\n", maxino);
map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
if (map == NULL)
panic("no memory for active inode map\n");
usedinomap = map;
curfile.action = USING;
getfile(xtrmap, xtrmapskip);
- if (spcl.c_type != TS_BITS) {
- fprintf(stderr, "Cannot find file dump list\n");
- done(1);
- }
+ if (spcl.c_type != TS_BITS)
+ 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");
* Prompt user to load a new dump volume.
* "Nextvol" is the next suggested volume to use.
* This suggested volume is enforced when doing full
- * or incremental restores, but can be overrridden by
+ * or incremental restores, but can be overridden by
* the user when only extracting a subset of the files.
*/
void
-getvol(nextvol)
- long nextvol;
+getvol(long nextvol)
{
- long newvol, savecnt, wantnext, i;
+ long newvol = 0, savecnt = 0, wantnext = 0, i;
union u_spcl tmpspcl;
# define tmpbuf tmpspcl.s_spcl
char buf[TP_BSIZE];
+ int haderror = 0;
if (nextvol == 1) {
tapesread = 0;
savecnt = blksread;
again:
if (pipein)
- done(1); /* pipes do not get a second chance */
+ exit(1); /* pipes do not get a second chance */
if (command == 'R' || command == 'r' || curfile.action != SKIP) {
newvol = nextvol;
wantnext = 1;
- } else {
+ } else {
newvol = 0;
wantnext = 0;
}
strcpy(buf, ": ");
for (i = 1; i < 32; i++)
if (tapesread & (1 << i)) {
- fprintf(stderr, "%s%d", buf, i);
+ fprintf(stderr, "%s%ld", buf, (long)i);
strcpy(buf, ", ");
}
fprintf(stderr, "\n");
(void) fgets(buf, BUFSIZ, terminal);
} while (!feof(terminal) && buf[0] == '\n');
if (feof(terminal))
- done(1);
+ exit(1);
newvol = atoi(buf);
if (newvol <= 0) {
fprintf(stderr,
return;
}
closemt();
- fprintf(stderr, "Mount tape volume %d\n", newvol);
- 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);
- if (feof(terminal))
- done(1);
- if (!strcmp(buf, "none\n")) {
- terminateinput();
- return;
- }
- if (buf[0] != '\n') {
- (void) strcpy(magtape, buf);
- magtape[strlen(magtape) - 1] = '\0';
+ if (Mflag) {
+ snprintf(magtape, NAME_MAX, "%s%03ld", magtapeprefix, newvol);
+ magtape[NAME_MAX - 1] = '\0';
+ }
+ if (!Mflag || haderror) {
+ haderror = 0;
+ fprintf(stderr, "Mount tape volume %ld\n", (long)newvol);
+ 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);
+ if (feof(terminal))
+ exit(1);
+ if (!strcmp(buf, "none\n")) {
+ terminateinput();
+ return;
+ }
+ if (buf[0] != '\n') {
+ (void) strcpy(magtape, buf);
+ magtape[strlen(magtape) - 1] = '\0';
+ }
}
#ifdef RRESTORE
if (host)
if (mt == -1) {
fprintf(stderr, "Cannot open %s\n", magtape);
volno = -1;
+ haderror = 1;
goto again;
}
gethdr:
setdumpnum();
FLUSHTAPEBUF();
if (gethead(&tmpbuf) == FAIL) {
- dprintf(stdout, "header read failed at %d blocks\n", blksread);
+ Dprintf(stdout, "header read failed at %ld blocks\n", (long)blksread);
fprintf(stderr, "tape is not dump tape\n");
volno = 0;
+ haderror = 1;
goto again;
}
if (tmpbuf.c_volume != volno) {
fprintf(stderr, "Wrong volume (%d)\n", tmpbuf.c_volume);
volno = 0;
+ haderror = 1;
goto again;
}
if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) {
fprintf(stderr, "\twanted: %s", ctime(&dumpdate));
#endif
volno = 0;
+ haderror = 1;
goto again;
}
tapesread |= 1 << volno;
* If coming to this volume at random, skip to the beginning
* of the next record.
*/
- dprintf(stdout, "read %ld recs, tape starts with %ld\n",
- tpblksread, tmpbuf.c_firstrec);
+ Dprintf(stdout, "read %ld recs, tape starts with %ld\n",
+ tpblksread, (long)tmpbuf.c_firstrec);
if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
if (!wantnext) {
tpblksread = tmpbuf.c_firstrec;
* -1 since we've read the volume header
*/
i = tpblksread - tmpbuf.c_firstrec - 1;
- dprintf(stderr, "Skipping %d duplicate record%s.\n",
- i, i > 1 ? "s" : "");
+ Dprintf(stderr, "Skipping %ld duplicate record%s.\n",
+ (long)i, i > 1 ? "s" : "");
while (--i >= 0)
readtape(buf);
}
findinode(&spcl);
if (gettingfile) {
gettingfile = 0;
- longjmp(restart, 1);
+ siglongjmp(restart, 1);
}
}
* Handle unexpected EOF.
*/
static void
-terminateinput()
+terminateinput(void)
{
if (gettingfile && curfile.action == USING) {
curfile.ino = maxino;
if (gettingfile) {
gettingfile = 0;
- longjmp(restart, 1);
+ siglongjmp(restart, 1);
}
}
* appropriate one.
*/
static void
-setdumpnum()
+setdumpnum(void)
{
struct mtop tcom;
if (dumpnum == 1 || volno != 1)
return;
- if (pipein) {
- fprintf(stderr, "Cannot have multiple dumps on pipe input\n");
- done(1);
- }
+ if (pipein)
+ errx(1, "Cannot have multiple dumps on pipe input");
tcom.mt_op = MTFSF;
tcom.mt_count = dumpnum - 1;
#ifdef RRESTORE
if (host)
rmtioctl(MTFSF, dumpnum - 1);
- else
+ else
#endif
if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0)
- fprintf(stderr, "ioctl MTFSF: %s\n", strerror(errno));
+ warn("ioctl MTFSF");
}
void
-printdumpinfo()
+printdumpinfo(void)
{
#ifdef __linux__
fprintf(stdout, "Dump date: %s", ctime4(&spcl.c_date));
}
int
-extractfile(name)
- char *name;
+extractfile(char *name)
{
- int flags;
+ unsigned int flags;
mode_t mode;
struct timeval timep[2];
struct entry *ep;
-#ifdef __linux__
- int err;
- uid_t uid;
- gid_t gid;
-#endif
curfile.name = name;
curfile.action = USING;
return (FAIL);
case IFSOCK:
- vprintf(stdout, "skipped socket %s\n", name);
+ Vprintf(stdout, "skipped socket %s\n", name);
skipfile();
return (GOOD);
skipfile();
return (GOOD);
}
- vprintf(stdout, "extract file %s\n", name);
+ Vprintf(stdout, "extract file %s\n", name);
return (genliteraldir(name, curfile.ino));
case IFLNK:
+ {
+#ifdef HAVE_LCHOWN
+ uid_t luid = curfile.dip->di_uid;
+ gid_t lgid = curfile.dip->di_gid;
+#endif
lnkbuf[0] = '\0';
pathlen = 0;
-#ifdef __linux__
- uid = curfile.dip->di_uid;
- gid = curfile.dip->di_gid;
-#endif
getfile(xtrlnkfile, xtrlnkskip);
if (pathlen == 0) {
- vprintf(stdout,
+ Vprintf(stdout,
"%s: zero length symbolic link (ignored)\n", name);
return (GOOD);
}
-#ifdef __linux__
- err = linkit(lnkbuf, name, SYMLINK);
- if (err == GOOD)
- (void) chown(name, uid, gid);
- return (err);
-#else
- return (linkit(lnkbuf, name, SYMLINK));
+ if (linkit(lnkbuf, name, SYMLINK) == FAIL)
+ return (FAIL);
+#ifdef HAVE_LCHOWN
+ (void) lchown(name, luid, lgid);
#endif
+ return (GOOD);
+ }
- case IFCHR:
- case IFBLK:
- vprintf(stdout, "extract special file %s\n", name);
+ case IFIFO:
+ Vprintf(stdout, "extract fifo %s\n", name);
if (Nflag) {
skipfile();
return (GOOD);
}
- if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) {
- fprintf(stderr, "%s: cannot create special file: %s\n",
- name, strerror(errno));
+ if (uflag && !Nflag)
+ (void)unlink(name);
+ if (mkfifo(name, mode) < 0) {
+ warn("%s: cannot create fifo", name);
skipfile();
return (FAIL);
}
(void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
(void) chmod(name, mode);
-#ifdef __linux__
- (void) fsetflags(name, flags);
+ if (flags)
+#ifdef __linux__
+ (void) fsetflags(name, flags);
#else
- (void) chflags(name, flags);
+ (void) chflags(name, flags);
#endif
skipfile();
utimes(name, timep);
return (GOOD);
- case IFIFO:
- vprintf(stdout, "extract fifo %s\n", name);
+ case IFCHR:
+ case IFBLK:
+ Vprintf(stdout, "extract special file %s\n", name);
if (Nflag) {
skipfile();
return (GOOD);
}
- if (mkfifo(name, mode) < 0) {
- fprintf(stderr, "%s: cannot create fifo: %s\n",
- name, strerror(errno));
+ if (uflag)
+ (void)unlink(name);
+ if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) {
+ warn("%s: cannot create special file", name);
skipfile();
return (FAIL);
}
(void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
(void) chmod(name, mode);
+ if (flags)
#ifdef __linux__
- (void) fsetflags(name, flags);
+ {
+ warn("%s: fsetflags called on a special file", name);
+ (void) fsetflags(name, flags);
+ }
#else
- (void) chflags(name, flags);
+ (void) chflags(name, flags);
#endif
skipfile();
utimes(name, timep);
return (GOOD);
case IFREG:
- vprintf(stdout, "extract file %s\n", name);
+ Vprintf(stdout, "extract file %s\n", name);
if (Nflag) {
skipfile();
return (GOOD);
}
+ if (uflag)
+ (void)unlink(name);
if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC,
0666)) < 0) {
- fprintf(stderr, "%s: cannot create file: %s\n",
- name, strerror(errno));
+ warn("%s: cannot create file", name);
skipfile();
return (FAIL);
}
(void) fchown(ofile, curfile.dip->di_uid, curfile.dip->di_gid);
(void) fchmod(ofile, mode);
+ if (flags)
#ifdef __linux__
- (void) fsetflags(ofile, flags);
+ (void) setflags(ofile, flags);
#else
- (void) fchflags(ofile, flags);
+ (void) fchflags(ofile, flags);
#endif
getfile(xtrfile, xtrskip);
(void) close(ofile);
* skip over bit maps on the tape
*/
void
-skipmaps()
+skipmaps(void)
{
while (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI)
* skip over a file on the tape
*/
void
-skipfile()
+skipfile(void)
{
curfile.action = SKIP;
* to the skip function.
*/
void
-getfile(fill, skip)
- void (*fill) __P((char *, long));
- void (*skip) __P((char *, long));
+getfile(void (*fill) __P((char *, size_t)), void (*skip) __P((char *, size_t)))
{
register int i;
- int curblk = 0;
- quad_t size = spcl.c_dinode.di_size;
- int last_write_was_hole = 0;
- long origsize = size;
+ volatile int curblk = 0;
+ volatile quad_t size = spcl.c_dinode.di_size;
+ volatile int last_write_was_hole = 0;
+ quad_t origsize = size;
static char clearedbuf[MAXBSIZE];
char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
char junk[TP_BSIZE];
gettingfile++;
loop:
for (i = 0; i < spcl.c_count; i++) {
- if (spcl.c_addr[i]) {
+ if (readmapflag || spcl.c_addr[i]) {
readtape(&buf[curblk++][0]);
if (curblk == fssize / TP_BSIZE) {
- (*fill)((char *)buf, (long)(size > TP_BSIZE ?
+ (*fill)((char *)buf, (size_t)(size > TP_BSIZE ?
fssize : (curblk - 1) * TP_BSIZE + size));
curblk = 0;
last_write_was_hole = 0;
}
} else {
if (curblk > 0) {
- (*fill)((char *)buf, (long)(size > TP_BSIZE ?
+ (*fill)((char *)buf, (size_t)(size > TP_BSIZE ?
curblk * TP_BSIZE :
(curblk - 1) * TP_BSIZE + size));
curblk = 0;
}
if ((size -= TP_BSIZE) <= 0) {
for (i++; i < spcl.c_count; i++)
- if (spcl.c_addr[i])
+ if (readmapflag || spcl.c_addr[i])
readtape(junk);
break;
}
if (gethead(&spcl) == GOOD && size > 0) {
if (spcl.c_type == TS_ADDR)
goto loop;
- dprintf(stdout,
- "Missing address (header) block for %s at %d blocks\n",
- curfile.name, blksread);
+ Dprintf(stdout,
+ "Missing address (header) block for %s at %ld blocks\n",
+ curfile.name, (long)blksread);
}
if (curblk > 0) {
- (*fill)((char *)buf, (curblk * TP_BSIZE) + size);
+ (*fill)((char *)buf, (size_t)(curblk * TP_BSIZE) + size);
last_write_was_hole = 0;
}
if (last_write_was_hole) {
* Write out the next block of a file.
*/
static void
-xtrfile(buf, size)
- char *buf;
- long size;
+xtrfile(char *buf, size_t size)
{
if (Nflag)
return;
- if (write(ofile, buf, (int) size) == -1) {
- fprintf(stderr,
- "write error extracting inode %d, name %s\nwrite: %s\n",
- curfile.ino, curfile.name, strerror(errno));
- done(1);
- }
+ if (write(ofile, buf, (int) size) == -1)
+ err(1, "write error extracting inode %lu, name %s\nwrite",
+ (unsigned long)curfile.ino, curfile.name);
}
/*
*/
/* ARGSUSED */
static void
-xtrskip(buf, size)
- char *buf;
- long size;
+xtrskip(char *buf, size_t size)
{
- if (lseek(ofile, size, SEEK_CUR) == -1) {
- fprintf(stderr,
- "seek error extracting inode %d, name %s\nlseek: %s\n",
- curfile.ino, curfile.name, strerror(errno));
- done(1);
- }
+ if (lseek(ofile, (off_t)size, SEEK_CUR) == -1)
+ err(1, "seek error extracting inode %lu, name %s\nlseek",
+ (unsigned long)curfile.ino, curfile.name);
}
/*
* Collect the next block of a symbolic link.
*/
static void
-xtrlnkfile(buf, size)
- char *buf;
- long size;
+xtrlnkfile(char *buf, size_t size)
{
pathlen += size;
- if (pathlen > MAXPATHLEN) {
- fprintf(stderr, "symbolic link name: %s->%s%s; too long %d\n",
+ if (pathlen > MAXPATHLEN)
+ errx(1, "symbolic link name: %s->%s%s; too long %d",
curfile.name, lnkbuf, buf, pathlen);
- done(1);
- }
(void) strcat(lnkbuf, buf);
}
*/
/* ARGSUSED */
static void
-xtrlnkskip(buf, size)
- char *buf;
- long size;
+xtrlnkskip(char *buf, size_t size)
{
- fprintf(stderr, "unallocated block in symbolic link %s\n",
- curfile.name);
- done(1);
+ errx(1, "unallocated block in symbolic link %s", curfile.name);
}
/*
* Collect the next block of a bit map.
*/
static void
-xtrmap(buf, size)
- char *buf;
- long size;
+xtrmap(char *buf, size_t size)
{
memmove(map, buf, size);
*/
/* ARGSUSED */
static void
-xtrmapskip(buf, size)
- char *buf;
- long size;
+xtrmapskip(char *buf, size_t size)
{
panic("hole in map\n");
*/
/* ARGSUSED */
void
-xtrnull(buf, size)
- char *buf;
- long size;
+xtrnull(char *buf, size_t size)
{
return;
}
-int
+static int
do_cmpfiles(int fd_tape, int fd_disk, long size)
{
-#ifndef BUFSIZE
-#define BUFSIZE 1024
-#endif
static char buf_tape[BUFSIZ];
static char buf_disk[BUFSIZ];
- int left = size;
- int n_tape;
- int n_disk;
+ ssize_t n_tape;
+ ssize_t n_disk;
while (size > 0) {
- if ((n_tape = read(fd_tape, buf_tape, BUFSIZE)) < 1) {
+ if ((n_tape = read(fd_tape, buf_tape, sizeof(buf_tape))) < 1) {
close(fd_tape), close(fd_disk);
panic("do_cmpfiles: unexpected EOF[1]");
}
- if ((n_disk = read(fd_disk, buf_disk, BUFSIZE)) < 1) {
+ if ((n_disk = read(fd_disk, buf_disk, sizeof(buf_tape))) < 1) {
close(fd_tape), close(fd_disk);
panic("do_cmpfiles: unexpected EOF[2]");
}
close(fd_tape), close(fd_disk);
panic("do_cmpfiles: sizes different!");
}
- if (memcmp(buf_tape, buf_disk, n_tape) != 0) return (1);
+ if (memcmp(buf_tape, buf_disk, (size_t)n_tape) != 0) return (1);
size -= n_tape;
}
return (0);
/* for debugging compare problems */
#undef COMPARE_FAIL_KEEP_FILE
+static
#ifdef COMPARE_FAIL_KEEP_FILE
/* return true if tapefile should be unlinked after compare */
int
if (sbuf_disk->st_size != sbuf_tape.st_size) {
fprintf(stderr,
- "%s: size changed from %d to %d.\n",
- diskfile, sbuf_tape.st_size, sbuf_disk->st_size);
+ "%s: size changed from %ld to %ld.\n",
+ diskfile, (long)sbuf_tape.st_size, (long)sbuf_disk->st_size);
#ifdef COMPARE_FAIL_KEEP_FILE
return (0);
#else
if (!p) {
panic("can't find / in %s\n", diskfile);
}
- sprintf(newname, "%s/debug/%s", tmpdir, p + 1);
+ snprintf(newname, sizeof(newname), "%s/debug/%s", tmpdir, p + 1);
if (rename(tapefile, newname)) {
panic("rename from %s to %s failed: %s\n",
tapefile, newname,
#endif
}
-static char tmpfilename[128];
+static char tmpfilename[MAXPATHLEN];
void
-comparefile(name)
- char *name;
+comparefile(char *name)
{
static char *tmpfile = NULL;
int mode;
int r;
if ((r = lstat(name, &sb)) != 0) {
- fprintf(stderr, "%s: does not exist (%d, %d).\n", name, r, errno);
+ warn("%s: does not exist (%d)", name, r);
skipfile();
return;
}
curfile.name = name;
+ curfile.action = USING;
mode = curfile.dip->di_mode;
- vprintf(stdout, "comparing %s (size: %d, mode: 0%o)\n", name,
- sb.st_size, mode);
+ Vprintf(stdout, "comparing %s (size: %ld, mode: 0%o)\n", name,
+ (long)sb.st_size, mode);
if (sb.st_mode != mode) {
fprintf(stderr, "%s: mode changed from 0%o to 0%o.\n",
fprintf(stderr,
"%s: device changed from %d,%d to %d,%d.\n",
name,
- ((int)curfile.dip->di_rdev >> 8) & 0xf,
- (int)curfile.dip->di_rdev & 0xf,
- (sb.st_rdev >> 8) & 0xf,
- sb.st_rdev & 0xf);
+ ((int)curfile.dip->di_rdev >> 8) & 0xff,
+ (int)curfile.dip->di_rdev & 0xff,
+ ((int)sb.st_rdev >> 8) & 0xff,
+ (int)sb.st_rdev & 0xff);
}
skipfile();
return;
case IFREG:
if (tmpfile == NULL) {
/* argument to mktemp() must not be in RO space: */
- sprintf(tmpfilename, "%s/restoreCXXXXXX", tmpdir);
+ snprintf(tmpfilename, sizeof(tmpfilename), "%s/restoreCXXXXXX", tmpdir);
tmpfile = mktemp(&tmpfilename[0]);
}
if ((stat(tmpfile, &stemp) == 0) && (unlink(tmpfile) != 0)) {
* Handle read errors, and end of media.
*/
static void
-readtape(buf)
- char *buf;
+readtape(char *buf)
{
- long rd, newvol, i;
+ ssize_t rd, newvol, i;
int cnt, seek_failed;
if (blkcnt < numtrec) {
- memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
+ memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
blksread++;
tpblksread++;
return;
* If found, skip rest of buffer and start with the next.
*/
if (!pipein && numtrec < ntrec && i > 0) {
- dprintf(stdout, "mid-media short read error.\n");
+ Dprintf(stdout, "mid-media short read error.\n");
numtrec = ntrec;
}
/*
* Short read. Process the blocks read.
*/
if (i % TP_BSIZE != 0)
- vprintf(stdout,
- "partial block read: %d should be %d\n",
- i, ntrec * TP_BSIZE);
+ Vprintf(stdout,
+ "partial block read: %ld should be %ld\n",
+ (long)i, ntrec * TP_BSIZE);
numtrec = i / TP_BSIZE;
}
}
fprintf(stderr, "restoring %s\n", curfile.name);
break;
case SKIP:
- fprintf(stderr, "skipping over inode %d\n",
- curfile.ino);
+ fprintf(stderr, "skipping over inode %lu\n",
+ (unsigned long)curfile.ino);
break;
}
if (!yflag && !reply("continue"))
- done(1);
+ exit(1);
i = ntrec * TP_BSIZE;
- memset(tapebuf, 0, i);
+ memset(tapebuf, 0, (size_t)i);
#ifdef RRESTORE
if (host)
seek_failed = (rmtseek(i, 1) < 0);
#endif
seek_failed = (lseek(mt, i, SEEK_CUR) == (off_t)-1);
- if (seek_failed) {
- fprintf(stderr,
- "continuation failed: %s\n", strerror(errno));
- done(1);
- }
+ if (seek_failed)
+ err(1, "continuation failed");
}
/*
* Handle end of tape.
*/
if (i == 0) {
- vprintf(stdout, "End-of-tape encountered\n");
+ Vprintf(stdout, "End-of-tape encountered\n");
if (!pipein) {
newvol = volno + 1;
volno = 0;
panic("partial block read: %d should be %d\n",
rd, ntrec * TP_BSIZE);
terminateinput();
- memmove(&tapebuf[rd], &endoftapemark, (long)TP_BSIZE);
+ memmove(&tapebuf[rd], &endoftapemark, TP_BSIZE);
}
blkcnt = 0;
- memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
+ memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
blksread++;
tpblksread++;
}
static void
-findtapeblksize()
+findtapeblksize(void)
{
register long i;
blkcnt = 0;
#ifdef RRESTORE
if (host)
- i = rmtread(tapebuf, ntrec * TP_BSIZE);
+ i = rmtread(tapebuf, (size_t)(ntrec * TP_BSIZE));
else
#endif
- i = read(mt, tapebuf, ntrec * TP_BSIZE);
+ i = read(mt, tapebuf, (size_t)(ntrec * TP_BSIZE));
- if (i <= 0) {
- fprintf(stderr, "tape read error: %s\n", strerror(errno));
- done(1);
- }
- if (i % TP_BSIZE != 0) {
- fprintf(stderr, "Tape block size (%d) %s (%d)\n",
- i, "is not a multiple of dump block size", TP_BSIZE);
- done(1);
- }
+ if (i <= 0)
+ err(1, "tape read error");
+ if (i % TP_BSIZE != 0)
+ errx(1, "Tape block size (%ld) is not a multiple of dump block size (%d)",
+ (long)i, TP_BSIZE);
ntrec = i / TP_BSIZE;
numtrec = ntrec;
- vprintf(stdout, "Tape block size is %d\n", ntrec);
+ Vprintf(stdout, "Tape block size is %ld\n", ntrec);
}
void
-closemt()
+closemt(void)
{
if (mt < 0)
* If it is not any valid header, return an error.
*/
static int
-gethead(buf)
- struct s_spcl *buf;
+gethead(struct s_spcl *buf)
{
- long i;
+ int32_t i;
union {
quad_t qval;
- long val[2];
+ int32_t val[2];
} qcvt;
union u_ospcl {
char dummy[TP_BSIZE];
struct s_ospcl {
- long c_type;
- long c_date;
- long c_ddate;
- long c_volume;
- long c_tapea;
- u_short c_inumber;
- long c_magic;
- long c_checksum;
+ int32_t c_type;
+ int32_t c_date;
+ int32_t c_ddate;
+ int32_t c_volume;
+ int32_t c_tapea;
+ u_int16_t c_inumber;
+ int32_t c_magic;
+ int32_t c_checksum;
struct odinode {
- unsigned short odi_mode;
- u_short odi_nlink;
- u_short odi_uid;
- u_short odi_gid;
- long odi_size;
- long odi_rdev;
+ u_int16_t odi_mode;
+ u_int16_t odi_nlink;
+ u_int16_t odi_uid;
+ u_int16_t odi_gid;
+ int32_t odi_size;
+ int32_t odi_rdev;
char odi_addr[36];
- long odi_atime;
- long odi_mtime;
- long odi_ctime;
+ int32_t odi_atime;
+ int32_t odi_mtime;
+ int32_t odi_ctime;
} c_dinode;
- long c_count;
+ int32_t c_count;
char c_addr[256];
} s_ospcl;
} u_ospcl;
if (!cvtflag) {
readtape((char *)buf);
if (buf->c_magic != NFS_MAGIC) {
- if (swabl(buf->c_magic) != NFS_MAGIC)
+ if (swabi(buf->c_magic) != NFS_MAGIC)
return (FAIL);
if (!Bcvt) {
- vprintf(stdout, "Note: Doing Byte swapping\n");
+ Vprintf(stdout, "Note: Doing Byte swapping\n");
Bcvt = 1;
}
}
if (checksum((int *)buf) == FAIL)
return (FAIL);
if (Bcvt)
- swabst((u_char *)"8l4s31l", (u_char *)buf);
+ swabst((u_char *)"8i4s31i528bi192b2i", (u_char *)buf);
goto good;
}
readtape((char *)(&u_ospcl.s_ospcl));
qcvt.val[0] = i;
buf->c_dinode.di_size = qcvt.qval;
}
+ readmapflag = 0;
switch (buf->c_type) {
*/
buf->c_inumber = 0;
buf->c_dinode.di_size = buf->c_count * TP_BSIZE;
- for (i = 0; i < buf->c_count; i++)
- buf->c_addr[i]++;
+ if (buf->c_count > TP_NINDIR)
+ readmapflag = 1;
+ else
+ for (i = 0; i < buf->c_count; i++)
+ buf->c_addr[i]++;
break;
case TS_TAPE:
break;
}
/*
- * If we are restoring a filesystem with old format inodes,
+ * If we are restoring a filesystem with old format inodes,
* copy the uid/gid to the new location.
*/
if (oldinofmt) {
* Check that a header is where it belongs and predict the next header
*/
static void
-accthdr(header)
- struct s_spcl *header;
+accthdr(struct s_spcl *header)
{
static ino_t previno = 0x7fffffff;
static int prevtype;
fprintf(stderr, "Used inodes map header");
break;
case TS_INODE:
- fprintf(stderr, "File header, ino %d", previno);
+ fprintf(stderr, "File header, ino %lu", (unsigned long)previno);
break;
case TS_ADDR:
- fprintf(stderr, "File continuation header, ino %d", previno);
+ fprintf(stderr, "File continuation header, ino %ld", previno);
break;
case TS_END:
fprintf(stderr, "End of tape header");
break;
}
if (predict != blksread - 1)
- fprintf(stderr, "; predicted %d blocks, got %d blocks",
+ fprintf(stderr, "; predicted %ld blocks, got %ld blocks",
predict, blksread - 1);
fprintf(stderr, "\n");
newcalc:
blks = 0;
if (header->c_type != TS_END)
for (i = 0; i < header->c_count; i++)
- if (header->c_addr[i] != 0)
+ if (readmapflag || header->c_addr[i] != 0)
blks++;
predict = blks;
blksread = 0;
* Complain if had to skip, and complain is set.
*/
static void
-findinode(header)
- struct s_spcl *header;
+findinode(struct s_spcl *header)
{
static long skipcnt = 0;
long i;
}
} while (header->c_type == TS_ADDR);
if (skipcnt > 0)
- fprintf(stderr, "resync restore, skipped %d blocks\n", skipcnt);
+ fprintf(stderr, "resync restore, skipped %ld blocks\n",
+ skipcnt);
skipcnt = 0;
}
static int
-checksum(buf)
- register int *buf;
+checksum(int *buf)
{
register int i, j;
} else {
/* What happens if we want to read restore tapes
for a 16bit int machine??? */
- do
- i += swabl(*buf++);
+ do
+ i += swabi(*buf++);
while (--j);
}
-
+
if (i != CHECKSUM) {
- fprintf(stderr, "Checksum error %o, inode %d file %s\n", i,
- curfile.ino, curfile.name);
+ fprintf(stderr, "Checksum error %o, inode %lu file %s\n", i,
+ (unsigned long)curfile.ino, curfile.name);
return(FAIL);
}
return(GOOD);
}
#ifdef RRESTORE
-#if __STDC__
+#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
void
-#if __STDC__
+#ifdef __STDC__
msg(const char *fmt, ...)
#else
msg(fmt, va_alist)
#endif
{
va_list ap;
-#if __STDC__
+#ifdef __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif /* RRESTORE */
static u_char *
-swabshort(sp, n)
- register u_char *sp;
- register int n;
+swab16(u_char *sp, int n)
{
char c;
}
static u_char *
-swablong(sp, n)
- register u_char *sp;
- register int n;
+swab32(u_char *sp, int n)
{
char c;
while (--n >= 0) {
c = sp[0]; sp[0] = sp[3]; sp[3] = c;
- c = sp[2]; sp[2] = sp[1]; sp[1] = c;
+ c = sp[1]; sp[1] = sp[2]; sp[2] = c;
sp += 4;
}
return (sp);
}
+static u_char *
+swab64(u_char *sp, int n)
+{
+ char c;
+
+ while (--n >= 0) {
+ c = sp[0]; sp[0] = sp[7]; sp[7] = c;
+ c = sp[1]; sp[1] = sp[6]; sp[6] = c;
+ c = sp[2]; sp[2] = sp[5]; sp[5] = c;
+ c = sp[3]; sp[3] = sp[4]; sp[4] = c;
+ sp += 8;
+ }
+ return (sp);
+}
+
void
-swabst(cp, sp)
- register u_char *cp, *sp;
+swabst(u_char *cp, u_char *sp)
{
int n = 0;
case '5': case '6': case '7': case '8': case '9':
n = (n * 10) + (*cp++ - '0');
continue;
-
+
case 's': case 'w': case 'h':
if (n == 0)
n = 1;
- sp = swabshort(sp, n);
+ sp = swab16(sp, n);
+ break;
+
+ case 'i':
+ if (n == 0)
+ n = 1;
+ sp = swab32(sp, n);
break;
case 'l':
if (n == 0)
n = 1;
- sp = swablong(sp, n);
+ sp = swab64(sp, n);
break;
default: /* Any other character, like 'b' counts as byte. */
}
}
+static u_int
+swabi(u_int x)
+{
+ swabst((u_char *)"i", (u_char *)&x);
+ return (x);
+}
+
static u_long
-swabl(x)
- u_long x;
+swabl(u_long x)
{
swabst((u_char *)"l", (u_char *)&x);
return (x);