X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/15822e16d4dcdb9c406ecc5141a3015ee91b9924..9a0abc6288eadc9c872c99ab1523e171bd806a59:/usr/src/sbin/restore/tape.c diff --git a/usr/src/sbin/restore/tape.c b/usr/src/sbin/restore/tape.c index af8fa7283f..f539cfff06 100644 --- a/usr/src/sbin/restore/tape.c +++ b/usr/src/sbin/restore/tape.c @@ -1,30 +1,46 @@ /* - * Copyright (c) 1983 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. * * %sccs.include.redist.c% */ #ifndef lint -static char sccsid[] = "@(#)tape.c 5.26 (Berkeley) %G%"; +static char sccsid[] = "@(#)tape.c 8.4 (Berkeley) %G%"; #endif /* not lint */ -#include "restore.h" -#include +#include +#include #include #include -#include -#include #include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "restore.h" +#include "extern.h" #include "pathnames.h" static long fssize = MAXBSIZE; static int mt = -1; static int pipein = 0; static char magtape[BUFSIZ]; -static int bct; +static int blkcnt; static int numtrec; -static char *tbf; +static char *tapebuf; static union u_spcl endoftapemark; static long blksread; /* blocks read since last header */ static long tpblksread = 0; /* TP_BSIZE blocks read */ @@ -38,20 +54,38 @@ static char *map; static char lnkbuf[MAXPATHLEN + 1]; static int pathlen; +int oldinofmt; /* old inode format conversion required */ int Bcvt; /* Swap Bytes (for CCI or sun) */ static int Qcvt; /* Swap quads (for sun) */ -u_long swabl(); + +#define FLUSHTAPEBUF() blkcnt = ntrec + 1 + +static void accthdr __P((struct s_spcl *)); +static int checksum __P((int *)); +static void findinode __P((struct s_spcl *)); +static void findtapeblksize __P((void)); +static int gethead __P((struct s_spcl *)); +static void readtape __P((char *)); +static void setdumpnum __P((void)); +static u_long swabl __P((u_long)); +static u_char *swablong __P((u_char *, int)); +static u_char *swabshort __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)); /* * Set up an input source */ +void setinput(source) char *source; { - extern int errno; - char *strerror(); - - flsht(); + FLUSHTAPEBUF(); if (bflag) newtapebuf(ntrec); else @@ -74,12 +108,12 @@ setinput(source) */ terminal = fopen(_PATH_TTY, "r"); if (terminal == NULL) { - (void)fprintf(stderr, "Cannot open %s: %s\n", - _PATH_TTY, strerror(errno)); + (void)fprintf(stderr, "cannot open %s: %s\n", + _PATH_TTY, strerror(errno)); terminal = fopen(_PATH_DEVNULL, "r"); if (terminal == NULL) { - (void)fprintf(stderr, "Cannot open %s: %s\n", - _PATH_DEVNULL, strerror(errno)); + (void)fprintf(stderr, "cannot open %s: %s\n", + _PATH_DEVNULL, strerror(errno)); done(1); } } @@ -89,33 +123,34 @@ setinput(source) (void) strcpy(magtape, source); } +void newtapebuf(size) long size; { - static tbfsize = -1; + static tapebufsize = -1; ntrec = size; - if (size <= tbfsize) + if (size <= tapebufsize) return; - if (tbf != NULL) - free(tbf); - tbf = (char *)malloc(size * TP_BSIZE); - if (tbf == NULL) { + if (tapebuf != NULL) + free(tapebuf); + tapebuf = malloc(size * TP_BSIZE); + if (tapebuf == NULL) { fprintf(stderr, "Cannot allocate space for tape buffer\n"); done(1); } - tbfsize = size; + tapebufsize = size; } /* * Verify that the tape drive can be accessed and * that it actually is a dump tape. */ +void setup() { int i, j, *ip; struct stat stbuf; - extern int xtrmap(), xtrmapskip(); vprintf(stdout, "Verify tape and initialize maps\n"); #ifdef RRESTORE @@ -126,18 +161,18 @@ setup() if (pipein) mt = 0; else - mt = open(magtape, 0); + mt = open(magtape, O_RDONLY, 0); if (mt < 0) { - perror(magtape); + fprintf(stderr, "%s: %s\n", magtape, strerror(errno)); done(1); } volno = 1; setdumpnum(); - flsht(); + FLUSHTAPEBUF(); if (!pipein && !bflag) findtapeblksize(); if (gethead(&spcl) == FAIL) { - bct--; /* push back this block */ + blkcnt--; /* push back this block */ blksread--; tpblksread--; cvtflag++; @@ -163,7 +198,7 @@ setup() dumptime = spcl.c_ddate; dumpdate = spcl.c_date; if (stat(".", &stbuf) < 0) { - perror("cannot stat ."); + fprintf(stderr, "cannot stat .: %s\n", strerror(errno)); done(1); } if (stbuf.st_blksize > 0 && stbuf.st_blksize <= MAXBSIZE) @@ -172,26 +207,28 @@ setup() fprintf(stderr, "bad block size %d\n", fssize); done(1); } - if (checkvol(&spcl, (long)1) == FAIL) { + if (spcl.c_volume != 1) { fprintf(stderr, "Tape is not volume 1 of the dump\n"); done(1); } - if (readhdr(&spcl) == FAIL) + if (gethead(&spcl) == FAIL) { + dprintf(stdout, "header read failed at %d blocks\n", blksread); panic("no header after volume mark!\n"); + } findinode(&spcl); - if (checktype(&spcl, TS_CLRI) == FAIL) { + if (spcl.c_type != TS_CLRI) { fprintf(stderr, "Cannot find file removal list\n"); done(1); } maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1; dprintf(stdout, "maxino = %d\n", maxino); map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); - if (map == (char *)NIL) + if (map == NULL) panic("no memory for file removal list\n"); clrimap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip); - if (checktype(&spcl, TS_BITS) == FAIL) { + if (spcl.c_type != TS_BITS) { fprintf(stderr, "Cannot find file dump list\n"); done(1); } @@ -210,6 +247,7 @@ setup() * or incremental restores, but can be overrridden by * the user when only extracting a subset of the files. */ +void getvol(nextvol) long nextvol; { @@ -217,7 +255,6 @@ getvol(nextvol) union u_spcl tmpspcl; # define tmpbuf tmpspcl.s_spcl char buf[TP_BSIZE]; - extern char *ctime(); if (nextvol == 1) { tapesread = 0; @@ -251,22 +288,22 @@ again: " towards towards the first.\n"); } else { fprintf(stderr, "You have read volumes"); - strcpy(tbf, ": "); + strcpy(buf, ": "); for (i = 1; i < 32; i++) if (tapesread & (1 << i)) { - fprintf(stderr, "%s%d", tbf, i); - strcpy(tbf, ", "); + fprintf(stderr, "%s%d", buf, i); + strcpy(buf, ", "); } fprintf(stderr, "\n"); } do { fprintf(stderr, "Specify next volume #: "); (void) fflush(stderr); - (void) fgets(tbf, BUFSIZ, terminal); - } while (!feof(terminal) && tbf[0] == '\n'); + (void) fgets(buf, BUFSIZ, terminal); + } while (!feof(terminal) && buf[0] == '\n'); if (feof(terminal)) done(1); - newvol = atoi(tbf); + newvol = atoi(buf); if (newvol <= 0) { fprintf(stderr, "Volume numbers are positive numerics\n"); @@ -281,21 +318,15 @@ again: 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(tbf, BUFSIZ, terminal); + (void) fgets(buf, BUFSIZ, terminal); if (feof(terminal)) done(1); - if (!strcmp(tbf, "none\n")) { - curfile.name = ""; - curfile.action = UNKNOWN; - curfile.dip = (struct dinode *)NIL; - curfile.ino = maxino; - if (gettingfile) { - gettingfile = 0; - longjmp(restart, 1); - } + if (!strcmp(buf, "none\n")) { + terminateinput(); + return; } - if (tbf[0] != '\n') { - (void) strcpy(magtape, tbf); + if (buf[0] != '\n') { + (void) strcpy(magtape, buf); magtape[strlen(magtape) - 1] = '\0'; } #ifdef RRESTORE @@ -303,7 +334,7 @@ again: mt = rmtopen(magtape, 0); else #endif - mt = open(magtape, 0); + mt = open(magtape, O_RDONLY, 0); if (mt == -1) { fprintf(stderr, "Cannot open %s\n", magtape); @@ -313,13 +344,14 @@ again: gethdr: volno = newvol; setdumpnum(); - flsht(); - if (readhdr(&tmpbuf) == FAIL) { + FLUSHTAPEBUF(); + if (gethead(&tmpbuf) == FAIL) { + dprintf(stdout, "header read failed at %d blocks\n", blksread); fprintf(stderr, "tape is not dump tape\n"); volno = 0; goto again; } - if (checkvol(&tmpbuf, volno) == FAIL) { + if (tmpbuf.c_volume != volno) { fprintf(stderr, "Wrong volume (%d)\n", tmpbuf.c_volume); volno = 0; goto again; @@ -378,10 +410,32 @@ gethdr: } } +/* + * Handle unexpected EOF. + */ +static void +terminateinput() +{ + + if (gettingfile && curfile.action == USING) { + printf("Warning: %s %s\n", + "End-of-input encountered while extracting", curfile.name); + } + curfile.name = ""; + curfile.action = UNKNOWN; + curfile.dip = NULL; + curfile.ino = maxino; + if (gettingfile) { + gettingfile = 0; + longjmp(restart, 1); + } +} + /* * handle multiple dumps per tape by skipping forward to the * appropriate one. */ +static void setdumpnum() { struct mtop tcom; @@ -400,13 +454,12 @@ setdumpnum() else #endif if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0) - perror("ioctl MTFSF"); + fprintf(stderr, "ioctl MTFSF: %s\n", strerror(errno)); } +void printdumpinfo() { - extern char *ctime(); - fprintf(stdout, "Dump date: %s", ctime(&spcl.c_date)); fprintf(stdout, "Dumped from: %s", (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&spcl.c_ddate)); @@ -417,22 +470,23 @@ printdumpinfo() fprintf(stderr, "Label: %s\n", spcl.c_label); } +int extractfile(name) char *name; { - int mode; + int flags; + mode_t mode; struct timeval timep[2]; struct entry *ep; - extern int xtrlnkfile(), xtrlnkskip(); - extern int xtrfile(), xtrskip(); curfile.name = name; curfile.action = USING; - timep[0].tv_sec = curfile.dip->di_atime; - timep[0].tv_usec = 0; - timep[1].tv_sec = curfile.dip->di_mtime; - timep[1].tv_usec = 0; + timep[0].tv_sec = curfile.dip->di_atime.ts_sec; + timep[0].tv_usec = curfile.dip->di_atime.ts_nsec / 1000; + timep[1].tv_sec = curfile.dip->di_mtime.ts_sec; + timep[1].tv_usec = curfile.dip->di_mtime.ts_nsec / 1000; mode = curfile.dip->di_mode; + flags = curfile.dip->di_flags; switch (mode & IFMT) { default: @@ -448,7 +502,7 @@ extractfile(name) case IFDIR: if (mflag) { ep = lookupname(name); - if (ep == NIL || ep->e_flags & EXTRACT) + if (ep == NULL || ep->e_flags & EXTRACT) panic("unextracted directory %s\n", name); skipfile(); return (GOOD); @@ -475,14 +529,33 @@ extractfile(name) return (GOOD); } if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) { - fprintf(stderr, "%s: ", name); - (void) fflush(stderr); - perror("cannot create special file"); + fprintf(stderr, "%s: cannot create special file: %s\n", + name, strerror(errno)); + skipfile(); + return (FAIL); + } + (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid); + (void) chmod(name, mode); + (void) chflags(name, flags); + skipfile(); + utimes(name, timep); + return (GOOD); + + case IFIFO: + vprintf(stdout, "extract fifo %s\n", name); + if (Nflag) { + skipfile(); + return (GOOD); + } + if (mkfifo(name, mode) < 0) { + fprintf(stderr, "%s: cannot create fifo: %s\n", + name, strerror(errno)); skipfile(); return (FAIL); } (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid); (void) chmod(name, mode); + (void) chflags(name, flags); skipfile(); utimes(name, timep); return (GOOD); @@ -494,14 +567,14 @@ extractfile(name) return (GOOD); } if ((ofile = creat(name, 0666)) < 0) { - fprintf(stderr, "%s: ", name); - (void) fflush(stderr); - perror("cannot create file"); + fprintf(stderr, "%s: cannot create file: %s\n", + name, strerror(errno)); skipfile(); return (FAIL); } (void) fchown(ofile, curfile.dip->di_uid, curfile.dip->di_gid); (void) fchmod(ofile, mode); + (void) fchflags(ofile, flags); getfile(xtrfile, xtrskip); (void) close(ofile); utimes(name, timep); @@ -513,42 +586,46 @@ extractfile(name) /* * skip over bit maps on the tape */ +void skipmaps() { - while (checktype(&spcl, TS_CLRI) == GOOD || - checktype(&spcl, TS_BITS) == GOOD) + while (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI) skipfile(); } /* * skip over a file on the tape */ +void skipfile() { - extern int null(); curfile.action = SKIP; - getfile(null, null); + getfile(xtrnull, xtrnull); } /* - * Do the file extraction, calling the supplied functions - * with the blocks + * Extract a file from the tape. + * When an allocated block is found it is passed to the fill function; + * when an unallocated block (hole) is found, a zeroed buffer is passed + * to the skip function. */ -getfile(f1, f2) - int (*f2)(), (*f1)(); +void +getfile(fill, skip) + void (*fill) __P((char *, long)); + void (*skip) __P((char *, long)); { register int i; int curblk = 0; - off_t size = spcl.c_dinode.di_size; + long size = spcl.c_dinode.di_size; static char clearedbuf[MAXBSIZE]; char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE]; char junk[TP_BSIZE]; - if (checktype(&spcl, TS_END) == GOOD) + if (spcl.c_type == TS_END) panic("ran off end of tape\n"); - if (ishead(&spcl) == FAIL) + if (spcl.c_magic != NFS_MAGIC) panic("not at beginning of a file\n"); if (!gettingfile && setjmp(restart) != 0) return; @@ -558,19 +635,19 @@ loop: if (spcl.c_addr[i]) { readtape(&buf[curblk++][0]); if (curblk == fssize / TP_BSIZE) { - (*f1)(buf, size > TP_BSIZE ? + (*fill)((char *)buf, size > TP_BSIZE ? (long) (fssize) : (curblk - 1) * TP_BSIZE + size); curblk = 0; } } else { if (curblk > 0) { - (*f1)(buf, size > TP_BSIZE ? + (*fill)((char *)buf, size > TP_BSIZE ? (long) (curblk * TP_BSIZE) : (curblk - 1) * TP_BSIZE + size); curblk = 0; } - (*f2)(clearedbuf, size > TP_BSIZE ? + (*skip)(clearedbuf, size > TP_BSIZE ? (long) TP_BSIZE : size); } if ((size -= TP_BSIZE) <= 0) { @@ -580,22 +657,23 @@ loop: break; } } - if (readhdr(&spcl) == GOOD && size > 0) { - if (checktype(&spcl, TS_ADDR) == GOOD) + if (gethead(&spcl) == GOOD && size > 0) { + if (spcl.c_type == TS_ADDR) goto loop; - dprintf(stdout, "Missing address (header) block for %s\n", - curfile.name); + dprintf(stdout, + "Missing address (header) block for %s at %d blocks\n", + curfile.name, blksread); } if (curblk > 0) - (*f1)(buf, (curblk * TP_BSIZE) + size); + (*fill)((char *)buf, (curblk * TP_BSIZE) + size); findinode(&spcl); gettingfile = 0; } /* - * The next routines are called during file extraction to - * put the data into the right form and place. + * Write out the next block of a file. */ +static void xtrfile(buf, size) char *buf; long size; @@ -604,29 +682,35 @@ xtrfile(buf, size) if (Nflag) return; if (write(ofile, buf, (int) size) == -1) { - fprintf(stderr, "write error extracting inode %d, name %s\n", - curfile.ino, curfile.name); - perror("write"); + fprintf(stderr, + "write error extracting inode %d, name %s\nwrite: %s\n", + curfile.ino, curfile.name, strerror(errno)); done(1); } } +/* + * Skip over a hole in a file. + */ +/* ARGSUSED */ +static void xtrskip(buf, size) char *buf; long size; { -#ifdef lint - buf = buf; -#endif - if (lseek(ofile, size, 1) == (long)-1) { - fprintf(stderr, "seek error extracting inode %d, name %s\n", - curfile.ino, curfile.name); - perror("lseek"); + 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); } } +/* + * Collect the next block of a symbolic link. + */ +static void xtrlnkfile(buf, size) char *buf; long size; @@ -641,19 +725,25 @@ xtrlnkfile(buf, size) (void) strcat(lnkbuf, buf); } +/* + * Skip over a hole in a symbolic link (should never happen). + */ +/* ARGSUSED */ +static void xtrlnkskip(buf, size) char *buf; long size; { -#ifdef lint - buf = buf, size = size; -#endif fprintf(stderr, "unallocated block in symbolic link %s\n", curfile.name); done(1); } +/* + * Collect the next block of a bit map. + */ +static void xtrmap(buf, size) char *buf; long size; @@ -663,40 +753,52 @@ xtrmap(buf, size) map += size; } +/* + * Skip over a hole in a bit map (should never happen). + */ +/* ARGSUSED */ +static void xtrmapskip(buf, size) char *buf; long size; { -#ifdef lint - buf = buf; -#endif panic("hole in map\n"); map += size; } -null() {;} +/* + * Noop, when an extraction function is not needed. + */ +/* ARGSUSED */ +void +xtrnull(buf, size) + char *buf; + long size; +{ + + return; +} /* - * Do the tape i/o, dealing with volume changes - * etc.. + * Read TP_BSIZE blocks from the input. + * Handle read errors, and end of media. */ -readtape(b) - char *b; +static void +readtape(buf) + char *buf; { - register long i; - long rd, newvol; - int cnt; - int seek_failed; + long rd, newvol, i; + int cnt, seek_failed; - if (bct < numtrec) { - bcopy(&tbf[(bct++*TP_BSIZE)], b, (long)TP_BSIZE); + if (blkcnt < numtrec) { + bcopy(&tapebuf[(blkcnt++ * TP_BSIZE)], buf, (long)TP_BSIZE); blksread++; tpblksread++; return; } for (i = 0; i < ntrec; i++) - ((struct s_spcl *)&tbf[i*TP_BSIZE])->c_magic = 0; + ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0; if (numtrec == 0) numtrec = ntrec; cnt = ntrec * TP_BSIZE; @@ -704,10 +806,10 @@ readtape(b) getmore: #ifdef RRESTORE if (host) - i = rmtread(&tbf[rd], cnt); + i = rmtread(&tapebuf[rd], cnt); else #endif - i = read(mt, &tbf[rd], cnt); + i = read(mt, &tapebuf[rd], cnt); /* * Check for mid-tape short read error. * If found, skip rest of buffer and start with the next. @@ -719,7 +821,9 @@ getmore: /* * Handle partial block read. */ - if (i > 0 && i != ntrec * TP_BSIZE) { + if (pipein && i == 0 && rd > 0) + i = rd; + else if (i > 0 && i != ntrec * TP_BSIZE) { if (pipein) { rd += i; cnt -= i; @@ -759,17 +863,18 @@ getmore: } if (!yflag && !reply("continue")) done(1); - i = ntrec*TP_BSIZE; - bzero(tbf, i); + i = ntrec * TP_BSIZE; + bzero(tapebuf, i); #ifdef RRESTORE if (host) seek_failed = (rmtseek(i, 1) < 0); else #endif - seek_failed = (lseek(mt, i, 1) == (long)-1); + seek_failed = (lseek(mt, i, SEEK_CUR) == (off_t)-1); if (seek_failed) { - perror("continuation failed"); + fprintf(stderr, + "continuation failed: %s\n", strerror(errno)); done(1); } } @@ -783,36 +888,38 @@ getmore: volno = 0; numtrec = 0; getvol(newvol); - readtape(b); + readtape(buf); return; } if (rd % TP_BSIZE != 0) panic("partial block read: %d should be %d\n", rd, ntrec * TP_BSIZE); - bcopy((char *)&endoftapemark, &tbf[rd], (long)TP_BSIZE); + terminateinput(); + bcopy((char *)&endoftapemark, &tapebuf[rd], (long)TP_BSIZE); } - bct = 0; - bcopy(&tbf[(bct++*TP_BSIZE)], b, (long)TP_BSIZE); + blkcnt = 0; + bcopy(&tapebuf[(blkcnt++ * TP_BSIZE)], buf, (long)TP_BSIZE); blksread++; tpblksread++; } +static void findtapeblksize() { register long i; for (i = 0; i < ntrec; i++) - ((struct s_spcl *)&tbf[i * TP_BSIZE])->c_magic = 0; - bct = 0; + ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0; + blkcnt = 0; #ifdef RRESTORE if (host) - i = rmtread(tbf, ntrec * TP_BSIZE); + i = rmtread(tapebuf, ntrec * TP_BSIZE); else #endif - i = read(mt, tbf, ntrec * TP_BSIZE); + i = read(mt, tapebuf, ntrec * TP_BSIZE); if (i <= 0) { - perror("Tape read error"); + fprintf(stderr, "tape read error: %s\n", strerror(errno)); done(1); } if (i % TP_BSIZE != 0) { @@ -825,14 +932,10 @@ findtapeblksize() vprintf(stdout, "Tape block size is %d\n", ntrec); } -flsht() -{ - - bct = ntrec+1; -} - +void closemt() { + if (mt < 0) return; #ifdef RRESTORE @@ -843,31 +946,13 @@ closemt() (void) close(mt); } -checkvol(b, t) - struct s_spcl *b; - long t; -{ - - if (b->c_volume != t) - return(FAIL); - return(GOOD); -} - -readhdr(b) - struct s_spcl *b; -{ - - if (gethead(b) == FAIL) { - dprintf(stdout, "readhdr fails at %d blocks\n", blksread); - return(FAIL); - } - return(GOOD); -} - /* - * read the tape into buf, then return whether or - * or not it is a header block. + * Read the next block from the tape. + * Check to see if it is one of several vintage headers. + * If it is an old style header, convert it to a new style header. + * If it is not any valid header, return an error. */ +static int gethead(buf) struct s_spcl *buf; { @@ -917,7 +1002,7 @@ gethead(buf) if (checksum((int *)buf) == FAIL) return (FAIL); if (Bcvt) - swabst("8l4s31l", (char *)buf); + swabst((u_char *)"8l4s31l", (u_char *)buf); goto good; } readtape((char *)(&u_ospcl.s_ospcl)); @@ -936,9 +1021,9 @@ gethead(buf) buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid; buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size; buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev; - buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime; - buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime; - buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime; + buf->c_dinode.di_atime.ts_sec = u_ospcl.s_ospcl.c_dinode.odi_atime; + buf->c_dinode.di_mtime.ts_sec = u_ospcl.s_ospcl.c_dinode.odi_mtime; + buf->c_dinode.di_ctime.ts_sec = u_ospcl.s_ospcl.c_dinode.odi_ctime; buf->c_count = u_ospcl.s_ospcl.c_count; bcopy(u_ospcl.s_ospcl.c_addr, buf->c_addr, (long)256); if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC || @@ -960,6 +1045,7 @@ good: i = qcvt.val[1]; qcvt.val[1] = qcvt.val[0]; qcvt.val[0] = i; + buf->c_dinode.di_size = qcvt.qval; } switch (buf->c_type) { @@ -976,6 +1062,9 @@ good: break; case TS_TAPE: + if ((buf->c_flags & DR_NEWINODEFMT) == 0) + oldinofmt = 1; + /* fall through */ case TS_END: buf->c_inumber = 0; break; @@ -988,6 +1077,14 @@ good: panic("gethead: unknown inode type %d\n", buf->c_type); break; } + /* + * If we are restoring a filesystem with old format inodes, + * copy the uid/gid to the new location. + */ + if (oldinofmt) { + buf->c_dinode.di_uid = buf->c_dinode.di_ouid; + buf->c_dinode.di_gid = buf->c_dinode.di_ogid; + } if (dflag) accthdr(buf); return(GOOD); @@ -996,6 +1093,7 @@ good: /* * Check that a header is where it belongs and predict the next header */ +static void accthdr(header) struct s_spcl *header; { @@ -1005,9 +1103,10 @@ accthdr(header) long blks, i; if (header->c_type == TS_TAPE) { - fprintf(stderr, "Volume header"); + fprintf(stderr, "Volume header (%s inode format) ", + oldinofmt ? "old" : "new"); if (header->c_firstrec) - fprintf(stderr, " begins with record %d", + fprintf(stderr, "begins with record %d", header->c_firstrec); fprintf(stderr, "\n"); previno = 0x7fffffff; @@ -1052,6 +1151,7 @@ newcalc: * Find an inode header. * Complain if had to skip, and complain is set. */ +static void findinode(header) struct s_spcl *header; { @@ -1061,73 +1161,64 @@ findinode(header) curfile.name = ""; curfile.action = UNKNOWN; - curfile.dip = (struct dinode *)NIL; + curfile.dip = NULL; curfile.ino = 0; - if (ishead(header) == FAIL) { - skipcnt++; - while (gethead(header) == FAIL || header->c_date != dumpdate) + do { + if (header->c_magic != NFS_MAGIC) { skipcnt++; - } - for (;;) { - if (checktype(header, TS_ADDR) == GOOD) { + while (gethead(header) == FAIL || + header->c_date != dumpdate) + skipcnt++; + } + switch (header->c_type) { + + case TS_ADDR: /* * Skip up to the beginning of the next record */ for (i = 0; i < header->c_count; i++) if (header->c_addr[i]) readtape(buf); - (void) gethead(header); - continue; - } - if (checktype(header, TS_INODE) == GOOD) { + while (gethead(header) == FAIL || + header->c_date != dumpdate) + skipcnt++; + break; + + case TS_INODE: curfile.dip = &header->c_dinode; curfile.ino = header->c_inumber; break; - } - if (checktype(header, TS_END) == GOOD) { + + case TS_END: curfile.ino = maxino; break; - } - if (checktype(header, TS_CLRI) == GOOD) { + + case TS_CLRI: curfile.name = ""; break; - } - if (checktype(header, TS_BITS) == GOOD) { + + case TS_BITS: curfile.name = ""; break; + + case TS_TAPE: + panic("unexpected tape header\n"); + /* NOTREACHED */ + + default: + panic("unknown tape header type %d\n", spcl.c_type); + /* NOTREACHED */ + } - while (gethead(header) == FAIL) - skipcnt++; - } + } while (header->c_type == TS_ADDR); if (skipcnt > 0) fprintf(stderr, "resync restore, skipped %d blocks\n", skipcnt); skipcnt = 0; } -/* - * return whether or not the buffer contains a header block - */ -ishead(buf) - struct s_spcl *buf; -{ - - if (buf->c_magic != NFS_MAGIC) - return(FAIL); - return(GOOD); -} - -checktype(b, t) - struct s_spcl *b; - int t; -{ - - if (b->c_type != t) - return(FAIL); - return(GOOD); -} - -checksum(b) - register int *b; +static int +checksum(buf) + register int *buf; { register int i, j; @@ -1135,13 +1226,13 @@ checksum(b) i = 0; if(!Bcvt) { do - i += *b++; + i += *buf++; while (--j); } else { /* What happens if we want to read restore tapes for a 16bit int machine??? */ do - i += swabl(*b++); + i += swabl(*buf++); while (--j); } @@ -1154,16 +1245,33 @@ checksum(b) } #ifdef RRESTORE -/* VARARGS1 */ -msg(cp, a1, a2, a3) - char *cp; -{ +#if __STDC__ +#include +#else +#include +#endif - fprintf(stderr, cp, a1, a2, a3); +void +#if __STDC__ +msg(const char *fmt, ...) +#else +msg(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)vfprintf(stderr, fmt, ap); + va_end(ap); } #endif /* RRESTORE */ -u_char * +static u_char * swabshort(sp, n) register u_char *sp; register int n; @@ -1177,7 +1285,7 @@ swabshort(sp, n) return (sp); } -u_char * +static u_char * swablong(sp, n) register u_char *sp; register int n; @@ -1192,11 +1300,11 @@ swablong(sp, n) return (sp); } +void swabst(cp, sp) register u_char *cp, *sp; { int n = 0; - u_char c; while (*cp) { switch (*cp) { @@ -1228,26 +1336,10 @@ swabst(cp, sp) } } -u_long +static u_long swabl(x) u_long x; { - swabst("l", (char *)&x); + swabst((u_char *)"l", (u_char *)&x); return (x); } - -#ifdef sunos -char * -strerror(errnum) - int errnum; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - - if (errnum < sys_nerr) { - return(sys_errlist[errnum]); - } else { - return("bogus errno in strerror"); - } -} -#endif