4.3 Tahoe rrestore bug
David P. Zimmerman
dpz at dorm.rutgers.edu
Mon Nov 21 10:26:14 AEST 1988
In article <23669 at pprg.unm.edu> cyrus at pprg.unm.edu (Tait Cyrus) writes:
> I am trying to get the 4.3 Tahoe dump/restore/rmt stuff to run
> uder SunOS 3.5. rdump seems to work fine, but rrestore does not.
Well, that doesn't make it a bug, does it? BSD4.3 and SunOS 3.x are
different beasts, right down to the opendir() library call. Here's my
fixes to the 4.3BSD [r]restore to make it work under SunOS3.x (and
also on Celerity 1200s and Pyramids). You can see what I've changed,
and a bit of examination will explain why (RTFSC :-).
David
: This is a shell archive.
: Remove everything above this line and
: run the following text with /bin/sh to create:
: README
: Makefile.diff
: dirs.c.diff
: dumprestore.h.diff
: interactive.c.diff
: main.c.diff
: restore.h.diff
: tape.c.diff
: opendir.c
: telldir.c
: This archive created: Sun Nov 20 19:24:15 1988
cat << 'SHAR_EOF' > README
dpz's changes to the standard 4.3BSD restore for compatible Sun SunOS
3.x, Sun SunOS 4.0, Pyramid OSx4.1, and Celerity 3.4 restores:
- replacing various #include files with equivalents
- adding DIRBLKSIZ #define, making it largest DEV_BSIZE of all
architectures
- copying DIR struct definition to RST_DIR, changing char
*dd_buf in it to char dd_buf[DIRBLKSIZ], changing all
routines that use DIR to use RST_DIR
- copying 4.3 opendir() to rst_4_3_opendir() and changing
appropriate routines to call that instead of opendir()
- copying 4.3 telldir() to rst_4_3_telldir(), changing
appropriate routines to call that instead of telldir()
- compile on Sun SunOS 4.0 with -DSUNOS4 in Makefile and link
statically
- generalizing "struct direct" to a typedef, since SunOS 4.0
has a field in it that doesn't exist on disk
- adding/modifying /usr/include/protocols/dumprestore.h:
- have TP_BSIZE equal the largest disk block size
across all three architectures (2048 in this case)
- adjusting NTREC and HIGHDENSITYTREC down to balance
my higher TP_BSIZE
- adjusting DUMPOUTFMT and DUMPINFMT to have the
highest number across all three architectures for %XXs
- adding CARTRIDGETREC for some reason
Frills:
- modifying Makefile so ${CFLAGS} is included in final .o combining
- adding Gary Winiger's epoch dump date mod (his comments below)
- adding Gary Winiger's interactive.c seg violation mods (cmts below)
From: gww at elxsi.UUCP (Gary Winiger)
When restore lists the dates the the dump encompases such as with the
-t option, it will list the epoch date for the from date of a level 0
dump.
From: gww at elxsi.UUCP (Gary Winiger)
When running /etc/restore in interactive mode, any attempt to
reference a subdirectory will cause a segmentation violation on
systems that do not permit dereferencing a NULL pointer.
SHAR_EOF
cat << 'SHAR_EOF' > Makefile.diff
*** Makefile.ORIG Sat Jan 9 16:27:02 1988
--- Makefile Sat Jan 9 16:26:58 1988
***************
*** 16,22 ****
cc ${LDFLAGS} ${CFLAGS} -o restore ${OBJS} tape.o
rrestore: ${OBJS} rtape.o dumprmt.o
! cc ${LDFLAGS} -o rrestore ${OBJS} rtape.o dumprmt.o
rtape.o: tape.c
cp tape.c rtape.c
--- 16,22 ----
cc ${LDFLAGS} ${CFLAGS} -o restore ${OBJS} tape.o
rrestore: ${OBJS} rtape.o dumprmt.o
! cc ${LDFLAGS} ${CFLAGS} -o rrestore ${OBJS} rtape.o dumprmt.o
rtape.o: tape.c
cp tape.c rtape.c
SHAR_EOF
cat << 'SHAR_EOF' > dirs.c.diff
*** dirs.c.ORIG Sat Jan 9 16:27:02 1988
--- dirs.c Wed Aug 17 17:39:13 1988
***************
*** 43,53 ****
*/
static daddr_t seekpt;
static FILE *df, *mf;
! static DIR *dirp;
static char dirfile[32] = "#"; /* No file */
static char modefile[32] = "#"; /* No file */
extern ino_t search();
! struct direct *rst_readdir();
extern void rst_seekdir();
/*
--- 43,54 ----
*/
static daddr_t seekpt;
static FILE *df, *mf;
! static RST_DIR *dirp;
static char dirfile[32] = "#"; /* No file */
static char modefile[32] = "#"; /* No file */
extern ino_t search();
! RST_DIR *rst_4_3_opendir();
! UNIXDIRECT *rst_readdir();
extern void rst_seekdir();
/*
***************
*** 71,77 ****
register int i;
register struct dinode *ip;
struct inotab *itp;
! struct direct nulldir;
int putdir(), null();
vprintf(stdout, "Extract directories from tape\n");
--- 72,78 ----
register int i;
register struct dinode *ip;
struct inotab *itp;
! UNIXDIRECT nulldir;
int putdir(), null();
vprintf(stdout, "Extract directories from tape\n");
***************
*** 105,111 ****
ip = curfile.dip;
if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) {
(void) fclose(df);
! dirp = opendir(dirfile);
if (dirp == NULL)
perror("opendir");
if (mf != NULL)
--- 106,112 ----
ip = curfile.dip;
if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) {
(void) fclose(df);
! dirp = rst_4_3_opendir(dirfile);
if (dirp == NULL)
perror("opendir");
if (mf != NULL)
***************
*** 144,150 ****
long (*todo)();
{
register struct inotab *itp;
! register struct direct *dp;
register struct entry *np;
int namelen;
daddr_t bpt;
--- 145,151 ----
long (*todo)();
{
register struct inotab *itp;
! register UNIXDIRECT *dp;
register struct entry *np;
int namelen;
daddr_t bpt;
***************
*** 182,188 ****
else
fprintf(stderr, "Warning: `..' missing from directory %s\n",
pname);
! bpt = telldir(dirp);
/*
* a zero inode signals end of directory
*/
--- 183,189 ----
else
fprintf(stderr, "Warning: `..' missing from directory %s\n",
pname);
! bpt = rst_4_3_telldir(dirp);
/*
* a zero inode signals end of directory
*/
***************
*** 197,203 ****
rst_seekdir(dirp, bpt, itp->t_seekpt);
}
dp = rst_readdir(dirp);
! bpt = telldir(dirp);
}
if (dp == NULL)
fprintf(stderr, "corrupted directory: %s.\n", locname);
--- 198,204 ----
rst_seekdir(dirp, bpt, itp->t_seekpt);
}
dp = rst_readdir(dirp);
! bpt = rst_4_3_telldir(dirp);
}
if (dp == NULL)
fprintf(stderr, "corrupted directory: %s.\n", locname);
***************
*** 246,252 ****
ino_t inum;
char *cp;
{
! register struct direct *dp;
register struct inotab *itp;
int len;
--- 247,253 ----
ino_t inum;
char *cp;
{
! register UNIXDIRECT *dp;
register struct inotab *itp;
int len;
***************
*** 270,279 ****
char *buf;
int size;
{
! struct direct cvtbuf;
register struct odirect *odp;
struct odirect *eodp;
! register struct direct *dp;
long loc, i;
extern int Bcvt;
--- 271,280 ----
char *buf;
int size;
{
! UNIXDIRECT cvtbuf;
register struct odirect *odp;
struct odirect *eodp;
! register UNIXDIRECT *dp;
long loc, i;
extern int Bcvt;
***************
*** 286,292 ****
}
} else {
for (loc = 0; loc < size; ) {
! dp = (struct direct *)(buf + loc);
if (Bcvt) {
swabst("l2s", (char *) dp);
}
--- 287,293 ----
}
} else {
for (loc = 0; loc < size; ) {
! dp = (UNIXDIRECT *)(buf + loc);
if (Bcvt) {
swabst("l2s", (char *) dp);
}
***************
*** 314,324 ****
* add a new directory entry to a file.
*/
putent(dp)
! struct direct *dp;
{
dp->d_reclen = DIRSIZ(dp);
if (dirloc + dp->d_reclen > DIRBLKSIZ) {
! ((struct direct *)(dirbuf + prev))->d_reclen =
DIRBLKSIZ - prev;
(void) fwrite(dirbuf, 1, DIRBLKSIZ, df);
dirloc = 0;
--- 315,325 ----
* add a new directory entry to a file.
*/
putent(dp)
! UNIXDIRECT *dp;
{
dp->d_reclen = DIRSIZ(dp);
if (dirloc + dp->d_reclen > DIRBLKSIZ) {
! ((UNIXDIRECT *)(dirbuf + prev))->d_reclen =
DIRBLKSIZ - prev;
(void) fwrite(dirbuf, 1, DIRBLKSIZ, df);
dirloc = 0;
***************
*** 334,340 ****
flushent()
{
! ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev;
(void) fwrite(dirbuf, (int)dirloc, 1, df);
seekpt = ftell(df);
dirloc = 0;
--- 335,341 ----
flushent()
{
! ((UNIXDIRECT *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev;
(void) fwrite(dirbuf, (int)dirloc, 1, df);
seekpt = ftell(df);
dirloc = 0;
***************
*** 342,348 ****
dcvt(odp, ndp)
register struct odirect *odp;
! register struct direct *ndp;
{
bzero((char *)ndp, (long)(sizeof *ndp));
--- 343,349 ----
dcvt(odp, ndp)
register struct odirect *odp;
! register UNIXDIRECT *ndp;
{
bzero((char *)ndp, (long)(sizeof *ndp));
***************
*** 354,360 ****
/*
* Seek to an entry in a directory.
! * Only values returned by ``telldir'' should be passed to rst_seekdir.
* This routine handles many directories in a single file.
* It takes the base of the directory in the file, plus
* the desired seek offset into it.
--- 355,361 ----
/*
* Seek to an entry in a directory.
! * Only values returned by ``rst_4_3_telldir'' should be passed to rst_seekdir.
* This routine handles many directories in a single file.
* It takes the base of the directory in the file, plus
* the desired seek offset into it.
***************
*** 361,371 ****
*/
void
rst_seekdir(dirp, loc, base)
! register DIR *dirp;
daddr_t loc, base;
{
! if (loc == telldir(dirp))
return;
loc -= base;
if (loc < 0)
--- 362,372 ----
*/
void
rst_seekdir(dirp, loc, base)
! register RST_DIR *dirp;
daddr_t loc, base;
{
! if (loc == rst_4_3_telldir(dirp))
return;
loc -= base;
if (loc < 0)
***************
*** 379,389 ****
/*
* get next entry in a directory.
*/
! struct direct *
rst_readdir(dirp)
! register DIR *dirp;
{
! register struct direct *dp;
for (;;) {
if (dirp->dd_loc == 0) {
--- 380,390 ----
/*
* get next entry in a directory.
*/
! UNIXDIRECT *
rst_readdir(dirp)
! register RST_DIR *dirp;
{
! register UNIXDIRECT *dp;
for (;;) {
if (dirp->dd_loc == 0) {
***************
*** 398,404 ****
dirp->dd_loc = 0;
continue;
}
! dp = (struct direct *)(dirp->dd_buf + dirp->dd_loc);
if (dp->d_reclen == 0 ||
dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) {
dprintf(stderr, "corrupted directory: bad reclen %d\n",
--- 399,405 ----
dirp->dd_loc = 0;
continue;
}
! dp = (UNIXDIRECT *)(dirp->dd_buf + dirp->dd_loc);
if (dp->d_reclen == 0 ||
dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) {
dprintf(stderr, "corrupted directory: bad reclen %d\n",
***************
*** 417,426 ****
}
}
/*
* Simulate the opening of a directory
*/
! DIR *
rst_opendir(name)
char *name;
{
--- 418,431 ----
}
}
+ #include "opendir.c"
+
+ #include "telldir.c"
+
/*
* Simulate the opening of a directory
*/
! RST_DIR *
rst_opendir(name)
char *name;
{
SHAR_EOF
cat << 'SHAR_EOF' > dumprestore.h.diff
*** dumprestore.h.ORIG Mon Apr 18 21:33:00 1988
--- dumprestore.h Tue Aug 16 17:08:45 1988
***************
*** 13,26 ****
* NTREC is the number of TP_BSIZE blocks that are written
* in each tape record. HIGHDENSITYTREC is the number of
* TP_BSIZE blocks that are written in each tape record on
! * 6250 BPI or higher density tapes.
*
* TP_NINDIR is the number of indirect pointers in a TS_INODE
* or TS_ADDR record. Note that it must be a power of two.
*/
! #define TP_BSIZE 1024
! #define NTREC 10
! #define HIGHDENSITYTREC 32
#define TP_NINDIR (TP_BSIZE/2)
#define TS_TAPE 1
--- 13,29 ----
* NTREC is the number of TP_BSIZE blocks that are written
* in each tape record. HIGHDENSITYTREC is the number of
* TP_BSIZE blocks that are written in each tape record on
! * 6250 BPI or higher density tapes. CARTRIDGETREC is the
! * number of TP_BSIZE blocks that are written in each tape
! * record on cartridge tapes.
*
* TP_NINDIR is the number of indirect pointers in a TS_INODE
* or TS_ADDR record. Note that it must be a power of two.
*/
! #define TP_BSIZE 2048
! #define NTREC 5
! #define HIGHDENSITYTREC 16
! #define CARTRIDGETREC 31
#define TP_NINDIR (TP_BSIZE/2)
#define TS_TAPE 1
***************
*** 52,57 ****
#define spcl u_spcl.s_spcl
! #define DUMPOUTFMT "%-16s %c %s" /* for printf */
/* name, incno, ctime(date) */
! #define DUMPINFMT "%16s %c %[^\n]\n" /* inverse for scanf */
--- 55,60 ----
#define spcl u_spcl.s_spcl
! #define DUMPOUTFMT "%-22s %c %s" /* for printf */
/* name, incno, ctime(date) */
! #define DUMPINFMT "%22s %c %[^\n]\n" /* inverse for scanf */
SHAR_EOF
cat << 'SHAR_EOF' > interactive.c.diff
*** interactive.c.ORIG Sat Jan 9 16:27:01 1988
--- interactive.c Tue Jul 12 17:00:11 1988
***************
*** 398,409 ****
register struct arglist *ap;
{
static struct afile single;
int size;
ap->head = ap->last = (struct afile *)0;
size = expand(arg, 0, ap);
if (size == 0) {
! single.fnum = lookupname(arg)->e_ino;
single.fname = savename(arg);
ap->head = &single;
ap->last = ap->head + 1;
--- 398,411 ----
register struct arglist *ap;
{
static struct afile single;
+ struct entry *ep;
int size;
ap->head = ap->last = (struct afile *)0;
size = expand(arg, 0, ap);
if (size == 0) {
! ep = lookupname(arg);
! single.fnum = ep != NIL ? ep->e_ino : 0;
single.fname = savename(arg);
ap->head = &single;
ap->last = ap->head + 1;
***************
*** 423,432 ****
int count, size;
char dir = 0;
char *rescan = 0;
! DIR *dirp;
register char *s, *cs;
int sindex, rindex, lindex;
! struct direct *dp;
register char slash;
register char *rs;
register char c;
--- 425,434 ----
int count, size;
char dir = 0;
char *rescan = 0;
! RST_DIR *dirp;
register char *s, *cs;
int sindex, rindex, lindex;
! UNIXDIRECT *dp;
register char slash;
register char *rs;
register char c;
***************
*** 571,577 ****
* Construct a matched name.
*/
addg(dp, as1, as3, ap)
! struct direct *dp;
char *as1, *as3;
struct arglist *ap;
{
--- 573,579 ----
* Construct a matched name.
*/
addg(dp, as1, as3, ap)
! UNIXDIRECT *dp;
char *as1, *as3;
struct arglist *ap;
{
***************
*** 609,618 ****
char *basename;
{
register struct afile *fp;
! register struct direct *dp;
static struct arglist alist = { 0, 0, 0, 0, "ls" };
struct afile single;
! DIR *dirp;
if ((dirp = rst_opendir(name)) == NULL) {
single.fnum = ino;
--- 611,620 ----
char *basename;
{
register struct afile *fp;
! register UNIXDIRECT *dp;
static struct arglist alist = { 0, 0, 0, 0, "ls" };
struct afile single;
! RST_DIR *dirp;
if ((dirp = rst_opendir(name)) == NULL) {
single.fnum = ino;
SHAR_EOF
cat << 'SHAR_EOF' > main.c.diff
*** main.c.ORIG Sat Jan 9 16:27:00 1988
--- main.c Tue Jul 12 16:39:19 1988
***************
*** 58,64 ****
--- 58,66 ----
char *inputdev = "/dev/rmt8";
char *symtbl = "./restoresymtable";
char name[MAXPATHLEN];
+ #ifndef SUNOS4
int (*signal())();
+ #endif
extern int onintr();
if (signal(SIGINT, onintr) == SIG_IGN)
SHAR_EOF
cat << 'SHAR_EOF' > restore.h.diff
*** restore.h.ORIG Sat Jan 9 16:27:01 1988
--- restore.h Tue Jul 12 17:02:25 1988
***************
*** 8,17 ****
#include <stdio.h>
#include <sys/param.h>
! #include <sys/inode.h>
! #include <sys/fs.h>
#include <sys/dir.h>
/*
* Flags
*/
--- 8,42 ----
#include <stdio.h>
#include <sys/param.h>
! #include <sys/time.h>
! #include <sys/vnode.h>
! #include <ufs/inode.h>
! #include <ufs/fs.h>
#include <sys/dir.h>
+ #ifdef SUNOS4
+ typedef struct {
+ u_long d_fileno; /* file number of entry */
+ u_short d_reclen; /* length of this record */
+ u_short d_namlen; /* length of string in d_name */
+ char d_name[MAXNAMLEN + 1]; /* name (up to MAXNAMLEN + 1) */
+ } UNIXDIRECT;
+ #else
+ typedef struct direct UNIXDIRECT;
+ #endif
+
+ #define DIRBLKSIZ 2048
+
+ typedef struct _rstdirdesc {
+ int dd_fd;
+ long dd_loc;
+ long dd_size;
+ long dd_bbase;
+ long dd_entno;
+ long dd_bsize;
+ char dd_buf[DIRBLKSIZ];
+ } RST_DIR;
+
/*
* Flags
*/
***************
*** 76,83 ****
extern char *flagvalues();
extern ino_t lowerbnd();
extern ino_t upperbnd();
! extern DIR *rst_opendir();
! extern struct direct *rst_readdir();
#define NIL ((struct entry *)(0))
/*
* Constants associated with entry structs
--- 101,108 ----
extern char *flagvalues();
extern ino_t lowerbnd();
extern ino_t upperbnd();
! extern RST_DIR *rst_opendir();
! extern UNIXDIRECT *rst_readdir();
#define NIL ((struct entry *)(0))
/*
* Constants associated with entry structs
SHAR_EOF
cat << 'SHAR_EOF' > tape.c.diff
*** tape.c.ORIG Sat Jan 9 16:27:03 1988
--- tape.c Sun May 29 19:09:30 1988
***************
*** 153,159 ****
}
if (vflag || command == 't') {
fprintf(stdout, "Dump date: %s", ctime(&spcl.c_date));
! fprintf(stdout, "Dumped from: %s", ctime(&spcl.c_ddate));
}
dumptime = spcl.c_ddate;
dumpdate = spcl.c_date;
--- 153,161 ----
}
if (vflag || command == 't') {
fprintf(stdout, "Dump date: %s", ctime(&spcl.c_date));
! fprintf(stdout, "Dumped from: %s",
! (spcl.c_ddate == (time_t)0)
! ? "the epoch\n" : ctime(&spcl.c_ddate));
}
dumptime = spcl.c_ddate;
dumpdate = spcl.c_date;
SHAR_EOF
cat << 'SHAR_EOF' > opendir.c
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* open a directory.
*/
RST_DIR *
rst_4_3_opendir(name)
char *name;
{
register RST_DIR *dirp;
register int fd;
if ((fd = open(name, 0)) == -1)
return NULL;
if ((dirp = (RST_DIR *)malloc(sizeof(RST_DIR))) == NULL) {
close (fd);
return NULL;
}
dirp->dd_fd = fd;
dirp->dd_loc = 0;
return dirp;
}
SHAR_EOF
cat << 'SHAR_EOF' > telldir.c
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* return a pointer into a directory
*/
long
rst_4_3_telldir(dirp)
RST_DIR *dirp;
{
extern long lseek();
return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
}
SHAR_EOF
: End of shell archive
exit 0
--
David P. Zimmerman, the Dorm Networking Pilot Project, the UUCP Project, etc
dpz at dorm.rutgers.edu rutgers!dpz dpzimmerman at zodiac.bitnet
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list