Subject: bin/4118: restoring a root partition is a pain
To: None <gnats-bugs@gnats.netbsd.org>
From: Michael C. Richardson <mcr@sandelman.ottawa.on.ca>
List: netbsd-bugs
Date: 09/17/1997 14:17:04
>Number: 4118
>Category: bin
>Synopsis: restore doesn't pay attention to $TMPDIR, no unlink option.
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Wed Sep 17 11:20:01 1997
>Last-Modified:
>Originator: Michael C. Richardson
>Organization:
Sandelman Software Works
>Release: 1.2
>Environment:
System: NetBSD istari.sandelman.ottawa.on.ca 1.2D NetBSD 1.2D (SSW) #10: Wed Jun 11 00:01:01 EDT 1997 mcr@istari.sandelman.ottawa.on.ca:/j/netbsd/src/sys/arch/i386/compile/SSW i386
Architecture: i386
>Description:
I was moving my root disk to a faster drive, and decided to test
my backup system (the tape gave me problems half way, so it failed,
by the way). I did learn two things about restore.
1. restore wants to write to /tmp. But that is the SSTO ramdisk.
2. if I copy the SSTO ramdisk to my /mnt'ed root (which is otherwise
empty), chroot and restore, then I get a hosed system.
[I put restore on a floppy since it and MT aren't on the SSTO disk]
{BTW: pathnames.h in restore and dump redefines _PATH_DEFTAPE. That fix
not included}
>How-To-Repeat:
backup and restore a root system on an i386.
>Fix:
Taught restore about $TMPDIR and added -u option. Tested.
*** /w/netbsd/src/sbin/restore/tape.c Mon Sep 15 07:17:04 1997
--- tape.c Wed Sep 17 13:45:19 1997
***************
*** 1,4 ****
! /* $NetBSD: tape.c,v 1.28 1997/09/15 08:04:40 lukem Exp $ */
/*
* Copyright (c) 1983, 1993
--- 1,4 ----
! /* $NetBSD: tape.c,v 1.25 1997/03/19 08:42:55 lukem Exp $ */
/*
* Copyright (c) 1983, 1993
***************
*** 38,49 ****
* SUCH DAMAGE.
*/
- #include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)tape.c 8.6 (Berkeley) 9/13/94";
#else
! __RCSID("$NetBSD: tape.c,v 1.28 1997/09/15 08:04:40 lukem Exp $");
#endif
#endif /* not lint */
--- 38,48 ----
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)tape.c 8.6 (Berkeley) 9/13/94";
#else
! static char rcsid[] = "$NetBSD: tape.c,v 1.25 1997/03/19 08:42:55 lukem Exp $";
#endif
#endif /* not lint */
***************
*** 57,63 ****
#include <protocols/dumprestore.h>
#include <errno.h>
- #include <paths.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
--- 56,61 ----
***************
*** 66,73 ****
#include "restore.h"
#include "extern.h"
! static u_int32_t fssize = MAXBSIZE;
static int mt = -1;
static int pipein = 0;
static char magtape[BUFSIZ];
--- 64,72 ----
#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];
***************
*** 75,83 ****
static int numtrec;
static char *tapebuf;
static union u_spcl endoftapemark;
! static int blksread; /* blocks read since last header */
! static int tpblksread = 0; /* TP_BSIZE blocks read */
! static int tapesread;
static jmp_buf restart;
static int gettingfile = 0; /* restart has a valid frame */
static char *host = NULL;
--- 74,82 ----
static int numtrec;
static char *tapebuf;
static union u_spcl endoftapemark;
! static long blksread; /* blocks read since last header */
! static long tpblksread = 0; /* TP_BSIZE blocks read */
! static long tapesread;
static jmp_buf restart;
static int gettingfile = 0; /* restart has a valid frame */
static char *host = NULL;
***************
*** 91,96 ****
--- 90,98 ----
int Bcvt; /* Swap Bytes (for CCI or sun) */
static int Qcvt; /* Swap quads (for sun) */
+ extern uid_t uid; /* real uid */
+ extern uid_t euid; /* effective uid */
+
#define FLUSHTAPEBUF() blkcnt = ntrec + 1
static void accthdr __P((struct s_spcl *));
***************
*** 152,157 ****
--- 154,160 ----
}
pipein++;
}
+ (void) setuid(uid); /* rmthost() is the only reason to be setuid */
(void) strcpy(magtape, source);
}
***************
*** 288,301 ****
*/
void
getvol(nextvol)
! int nextvol;
{
! int newvol, savecnt, wantnext, i;
union u_spcl tmpspcl;
# define tmpbuf tmpspcl.s_spcl
char buf[TP_BSIZE];
- newvol = savecnt = wantnext = 0;
if (nextvol == 1) {
tapesread = 0;
gettingfile = 0;
--- 291,303 ----
*/
void
getvol(nextvol)
! long nextvol;
{
! long newvol, savecnt, wantnext, i;
union u_spcl tmpspcl;
# define tmpbuf tmpspcl.s_spcl
char buf[TP_BSIZE];
if (nextvol == 1) {
tapesread = 0;
gettingfile = 0;
***************
*** 413,419 ****
* of the next record.
*/
dprintf(stdout, "read %ld recs, tape starts with %ld\n",
! (long)tpblksread, (long)tmpbuf.c_firstrec);
if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
if (!wantnext) {
tpblksread = tmpbuf.c_firstrec;
--- 415,421 ----
* of the next record.
*/
dprintf(stdout, "read %ld recs, tape starts with %ld\n",
! tpblksread, tmpbuf.c_firstrec);
if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
if (!wantnext) {
tpblksread = tmpbuf.c_firstrec;
***************
*** 514,519 ****
--- 516,523 ----
extractfile(name)
char *name;
{
+ extern int unlinkflag;
+
int flags;
mode_t mode;
struct timeval timep[2];
***************
*** 559,564 ****
--- 563,569 ----
"%s: zero length symbolic link (ignored)\n", name);
return (GOOD);
}
+ if(unlinkflag) unlink(name);
return (linkit(lnkbuf, name, SYMLINK));
case IFCHR:
***************
*** 568,573 ****
--- 573,579 ----
skipfile();
return (GOOD);
}
+ if(unlinkflag) unlink(name);
if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) {
fprintf(stderr, "%s: cannot create special file: %s\n",
name, strerror(errno));
***************
*** 587,592 ****
--- 593,599 ----
skipfile();
return (GOOD);
}
+ if(unlinkflag) unlink(name);
if (mkfifo(name, mode) < 0) {
fprintf(stderr, "%s: cannot create fifo: %s\n",
name, strerror(errno));
***************
*** 606,611 ****
--- 613,619 ----
skipfile();
return (GOOD);
}
+ if(unlinkflag) unlink(name);
if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC,
0666)) < 0) {
fprintf(stderr, "%s: cannot create file: %s\n",
***************
*** 664,674 ****
char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
char junk[TP_BSIZE];
- #ifdef __GNUC__ /* XXX: to shut up gcc warnings */
- (void)&curblk;
- (void)&size;
- #endif
-
if (spcl.c_type == TS_END)
panic("ran off end of tape\n");
if (spcl.c_magic != NFS_MAGIC)
--- 672,677 ----
***************
*** 834,840 ****
readtape(buf)
char *buf;
{
! int rd, newvol, i;
int cnt, seek_failed;
if (blkcnt < numtrec) {
--- 837,843 ----
readtape(buf)
char *buf;
{
! long rd, newvol, i;
int cnt, seek_failed;
if (blkcnt < numtrec) {
***************
*** 969,977 ****
exit(1);
}
if (i % TP_BSIZE != 0) {
! fprintf(stderr, "Tape block size (%ld) %s (%ld)\n",
! (long)i, "is not a multiple of dump block size",
! (long)TP_BSIZE);
exit(1);
}
ntrec = i / TP_BSIZE;
--- 972,979 ----
exit(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);
exit(1);
}
ntrec = i / TP_BSIZE;
***************
*** 1179,1186 ****
break;
}
if (predict != blksread - 1)
! fprintf(stderr, "; predicted %ld blocks, got %ld blocks",
! (long)predict, (long)(blksread - 1));
fprintf(stderr, "\n");
newcalc:
blks = 0;
--- 1181,1188 ----
break;
}
if (predict != blksread - 1)
! fprintf(stderr, "; predicted %d blocks, got %d blocks",
! predict, blksread - 1);
fprintf(stderr, "\n");
newcalc:
blks = 0;
***************
*** 1259,1266 ****
}
} while (header->c_type == TS_ADDR);
if (skipcnt > 0)
! fprintf(stderr, "resync restore, skipped %ld blocks\n",
! (long)skipcnt);
skipcnt = 0;
}
--- 1261,1267 ----
}
} while (header->c_type == TS_ADDR);
if (skipcnt > 0)
! fprintf(stderr, "resync restore, skipped %d blocks\n", skipcnt);
skipcnt = 0;
}
*** /w/netbsd/src/sbin/restore/pathnames.h Fri Oct 13 21:13:31 1995
--- pathnames.h Wed Sep 17 13:37:53 1997
***************
*** 43,45 ****
--- 43,47 ----
#include <paths.h>
#define _PATH_DEFTAPE "/dev/rmt8"
+
+ extern char *tmpdir;
*** /w/netbsd/src/sbin/restore/dirs.c Mon Sep 15 07:16:48 1997
--- dirs.c Wed Sep 17 13:38:40 1997
***************
*** 1,4 ****
! /* $NetBSD: dirs.c,v 1.28 1997/09/15 08:04:28 lukem Exp $ */
/*
* Copyright (c) 1983, 1993
--- 1,4 ----
! /* $NetBSD: dirs.c,v 1.22 1997/03/19 08:42:51 lukem Exp $ */
/*
* Copyright (c) 1983, 1993
***************
*** 38,49 ****
* SUCH DAMAGE.
*/
- #include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)dirs.c 8.5 (Berkeley) 8/31/94";
#else
! __RCSID("$NetBSD: dirs.c,v 1.28 1997/09/15 08:04:28 lukem Exp $");
#endif
#endif /* not lint */
--- 38,48 ----
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)dirs.c 8.5 (Berkeley) 8/31/94";
#else
! static char rcsid[] = "$NetBSD: dirs.c,v 1.22 1997/03/19 08:42:51 lukem Exp $";
#endif
#endif /* not lint */
***************
*** 57,65 ****
#include <ufs/ufs/dir.h>
#include <protocols/dumprestore.h>
- #include <err.h>
#include <errno.h>
- #include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
--- 56,62 ----
***************
*** 67,72 ****
--- 64,70 ----
#include <machine/endian.h>
+ #include "pathnames.h"
#include "restore.h"
#include "extern.h"
***************
*** 154,163 ****
vprintf(stdout, "Extract directories from tape\n");
(void) snprintf(dirfile, sizeof(dirfile), "%s/rstdir%d",
! tmpdir, (int)dumpdate);
if (command != 'r' && command != 'R') {
(void) snprintf(dirfile, sizeof(dirfile), "%s/rstdir%d-XXXXXX",
! tmpdir, (int)dumpdate);
if ((dfd = mkstemp(dirfile)) == -1)
err(1, "cannot mkstemp temporary file %s", dirfile);
df = fdopen(dfd, "w");
--- 152,161 ----
vprintf(stdout, "Extract directories from tape\n");
(void) snprintf(dirfile, sizeof(dirfile), "%s/rstdir%d",
! tmpdir, dumpdate);
if (command != 'r' && command != 'R') {
(void) snprintf(dirfile, sizeof(dirfile), "%s/rstdir%d-XXXXXX",
! tmpdir, dumpdate);
if ((dfd = mkstemp(dirfile)) == -1)
err(1, "cannot mkstemp temporary file %s", dirfile);
df = fdopen(dfd, "w");
***************
*** 169,178 ****
if (genmode != 0) {
(void) snprintf(modefile, sizeof(modefile), "%s/rstmode%d",
! tmpdir, (int)dumpdate);
if (command != 'r' && command != 'R') {
(void) snprintf(modefile, sizeof(modefile),
! "%s/rstmode%d-XXXXXX", tmpdir, (int)dumpdate);
if ((mfd = mkstemp(modefile)) == -1)
err(1, "cannot mkstemp temporary file %s",
modefile);
--- 167,176 ----
if (genmode != 0) {
(void) snprintf(modefile, sizeof(modefile), "%s/rstmode%d",
! tmpdir, dumpdate);
if (command != 'r' && command != 'R') {
(void) snprintf(modefile, sizeof(modefile),
! "%s/rstmode%d-XXXXXX", tmpdir, dumpdate);
if ((mfd = mkstemp(modefile)) == -1)
err(1, "cannot mkstemp temporary file %s",
modefile);
***************
*** 226,232 ****
}
/*
! * Recursively find names and inumbers of all files in subtree
* pname and pass them off to be processed.
*/
void
--- 224,230 ----
}
/*
! * Recursively find names and inumbers of all files in subtree
* pname and pass them off to be processed.
*/
void
***************
*** 283,289 ****
locname, dp->d_name, sizeof(locname) - 1);
} else {
(void) strncat(locname, dp->d_name, (int)dp->d_namlen);
- locname[namelen + dp->d_namlen] = '\0';
treescan(locname, dp->d_ino, todo);
rst_seekdir(dirp, bpt, itp->t_seekpt);
}
--- 281,286 ----
***************
*** 309,315 ****
while (*path == '/')
path++;
dp = NULL;
! while ((name = strsep(&path, "/")) != NULL && *name != '\0') {
if ((dp = searchdir(ino, name)) == NULL)
return (NULL);
ino = dp->d_ino;
--- 306,312 ----
while (*path == '/')
path++;
dp = NULL;
! while ((name = strsep(&path, "/")) != NULL && *name != NULL) {
if ((dp = searchdir(ino, name)) == NULL)
return (NULL);
ino = dp->d_ino;
***************
*** 477,484 ****
return;
loc -= base;
if (loc < 0)
! fprintf(stderr, "bad seek pointer to rst_seekdir %d\n",
! (int)loc);
(void) lseek(dirp->dd_fd, base + (loc & ~(DIRBLKSIZ - 1)), SEEK_SET);
dirp->dd_loc = loc & (DIRBLKSIZ - 1);
if (dirp->dd_loc != 0)
--- 474,480 ----
return;
loc -= base;
if (loc < 0)
! fprintf(stderr, "bad seek pointer to rst_seekdir %d\n", loc);
(void) lseek(dirp->dd_fd, base + (loc & ~(DIRBLKSIZ - 1)), SEEK_SET);
dirp->dd_loc = loc & (DIRBLKSIZ - 1);
if (dirp->dd_loc != 0)
***************
*** 496,502 ****
for (;;) {
if (dirp->dd_loc == 0) {
! dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
DIRBLKSIZ);
if (dirp->dd_size <= 0) {
dprintf(stderr, "error reading directory\n");
--- 492,498 ----
for (;;) {
if (dirp->dd_loc == 0) {
! dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
DIRBLKSIZ);
if (dirp->dd_size <= 0) {
dprintf(stderr, "error reading directory\n");
***************
*** 602,612 ****
struct modeinfo node;
struct entry *ep;
char *cp;
!
vprintf(stdout, "Set directory mode, owner, and times.\n");
if (command == 'r' || command == 'R')
(void) snprintf(modefile, sizeof(modefile), "%s/rstmode%d",
! tmpdir, (int)dumpdate);
if (modefile[0] == '#') {
panic("modefile not defined\n");
fprintf(stderr, "directory mode, owner, and times not set\n");
--- 598,608 ----
struct modeinfo node;
struct entry *ep;
char *cp;
!
vprintf(stdout, "Set directory mode, owner, and times.\n");
if (command == 'r' || command == 'R')
(void) snprintf(modefile, sizeof(modefile), "%s/rstmode%d",
! tmpdir, dumpdate);
if (modefile[0] == '#') {
panic("modefile not defined\n");
fprintf(stderr, "directory mode, owner, and times not set\n");
*** /w/netbsd/src/sbin/restore/main.c Mon Sep 15 07:16:52 1997
--- main.c Wed Sep 17 13:37:30 1997
***************
*** 1,4 ****
! /* $NetBSD: main.c,v 1.15 1997/09/15 08:04:33 lukem Exp $ */
/*
* Copyright (c) 1983, 1993
--- 1,4 ----
! /* $NetBSD: main.c,v 1.11 1996/03/15 22:39:39 scottr Exp $ */
/*
* Copyright (c) 1983, 1993
***************
*** 33,49 ****
* SUCH DAMAGE.
*/
- #include <sys/cdefs.h>
#ifndef lint
! __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
! The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 9/13/94";
#else
! __RCSID("$NetBSD: main.c,v 1.15 1997/09/15 08:04:33 lukem Exp $");
#endif
#endif /* not lint */
--- 33,49 ----
* SUCH DAMAGE.
*/
#ifndef lint
! static char copyright[] =
! "@(#) Copyright (c) 1983, 1993\n\
! The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 9/13/94";
#else
! static char rcsid[] = "$NetBSD: main.c,v 1.11 1996/03/15 22:39:39 scottr Exp $";
#endif
#endif /* not lint */
***************
*** 56,89 ****
#include <err.h>
#include <errno.h>
- #include <paths.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "restore.h"
#include "extern.h"
- extern char *__progname; /* from crt0.o */
-
int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
! int hflag = 1, mflag = 1, Nflag = 0;
char command = '\0';
! int32_t dumpnum = 1;
! int32_t volno = 0;
! int32_t ntrec;
char *dumpmap;
char *usedinomap;
ino_t maxino;
time_t dumptime;
time_t dumpdate;
FILE *terminal;
! char *tmpdir;
! int main __P((int, char *[]));
! static void obsolete __P((int *, char **[]));
! static void usage __P((void));
int
main(argc, argv)
--- 56,88 ----
#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+ #include "pathnames.h"
#include "restore.h"
#include "extern.h"
int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
! int hflag = 1, mflag = 1, Nflag = 0, unlinkflag = 0;
char command = '\0';
! long dumpnum = 1;
! long volno = 0;
! long ntrec;
char *dumpmap;
char *usedinomap;
ino_t maxino;
time_t dumptime;
time_t dumpdate;
FILE *terminal;
! uid_t uid; /* real uid */
! uid_t euid; /* effective uid */
! char *tmpdir;
! static void obsolete __P((int *, char **[]));
! static void usage __P((void));
int
main(argc, argv)
***************
*** 96,110 ****
char *symtbl = "./restoresymtable";
char *p, name[MAXPATHLEN];
if (argc < 2)
usage();
if ((inputdev = getenv("TAPE")) == NULL)
inputdev = _PATH_DEFTAPE;
! if ((tmpdir = getenv("TMPDIR")) == NULL)
! tmpdir = _PATH_TMP;
obsolete(&argc, &argv);
! while ((ch = getopt(argc, argv, "b:cdf:himNRrs:tvxy")) != -1)
switch(ch) {
case 'b':
/* Change default tape blocksize. */
--- 95,116 ----
char *symtbl = "./restoresymtable";
char *p, name[MAXPATHLEN];
+ uid = getuid();
+ euid = geteuid();
+ (void) seteuid(uid);
+
if (argc < 2)
usage();
if ((inputdev = getenv("TAPE")) == NULL)
inputdev = _PATH_DEFTAPE;
!
! if ((tmpdir = getenv("TMPDIR")) == NULL) {
! tmpdir = _PATH_TMP;
! }
!
obsolete(&argc, &argv);
! while ((ch = getopt(argc, argv, "b:cdf:himNRrs:tuvxy")) != EOF)
switch(ch) {
case 'b':
/* Change default tape blocksize. */
***************
*** 155,160 ****
--- 161,169 ----
case 'v':
vflag = 1;
break;
+ case 'u':
+ unlinkflag = 1;
+ break;
case 'y':
yflag = 1;
break;
***************
*** 288,308 ****
usage()
{
! (void)fprintf(stderr,
! "usage: %s -i [-chmvy] [-b blocksize] [-f file] [-s fileno]\n",
! __progname);
! (void)fprintf(stderr,
! "\t%s -R [-cvy] [-b blocksize] [-f file] [-s fileno]\n",
! __progname);
! (void)fprintf(stderr,
! "\t%s -r [-cvy] [-b blocksize] [-f file] [-s fileno]\n",
! __progname);
! (void)fprintf(stderr,
! "\t%s -t [-chvy] [-b blocksize] [-f file] [-s fileno] [file ...]\n",
! __progname);
! (void)fprintf(stderr,
! "\t%s -x [-chmvy] [-b blocksize] [-f file] [-s fileno] [file ...]\n",
! __progname);
exit(1);
}
--- 297,307 ----
usage()
{
! (void)fprintf(stderr, "usage: restore -i [-chmvy] [-b blocksize] [-f file] [-s fileno]\n");
! (void)fprintf(stderr, " restore -R [-cvy] [-b blocksize] [-f file] [-s fileno]\n");
! (void)fprintf(stderr, " restore -r [-cvy] [-b blocksize] [-f file] [-s fileno]\n");
! (void)fprintf(stderr, " restore -t [-chvy] [-b blocksize] [-f file] [-s fileno] [file ...]\n");
! (void)fprintf(stderr, " restore -x [-chmvy] [-b blocksize] [-f file] [-s fileno] [file ...]\n");
exit(1);
}
***************
*** 331,337 ****
/* Allocate space for new arguments. */
if ((*argvp = nargv = malloc((argc + 1) * sizeof(char *))) == NULL ||
(p = flagsp = malloc(strlen(ap) + 2)) == NULL)
! err(1, "%s", "");
*nargv++ = *argv;
argv += 2;
--- 330,336 ----
/* Allocate space for new arguments. */
if ((*argvp = nargv = malloc((argc + 1) * sizeof(char *))) == NULL ||
(p = flagsp = malloc(strlen(ap) + 2)) == NULL)
! err(1, NULL);
*nargv++ = *argv;
argv += 2;
***************
*** 346,352 ****
usage();
}
if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL)
! err(1, "%s", "");
nargv[0][0] = '-';
nargv[0][1] = *ap;
(void)strcpy(&nargv[0][2], *argv);
--- 345,351 ----
usage();
}
if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL)
! err(1, NULL);
nargv[0][0] = '-';
nargv[0][1] = *ap;
(void)strcpy(&nargv[0][2], *argv);
***************
*** 370,377 ****
}
/* Copy remaining arguments. */
! while ((*nargv++ = *argv++) != NULL)
! ;
/* Update argument count. */
*argcp = nargv - *argvp - 1;
--- 369,375 ----
}
/* Copy remaining arguments. */
! while (*nargv++ = *argv++);
/* Update argument count. */
*argcp = nargv - *argvp - 1;
*** /w/netbsd/src/sbin/restore/restore.8 Mon Sep 15 07:16:54 1997
--- restore.8 Wed Sep 17 13:59:43 1997
***************
*** 1,4 ****
! .\" $NetBSD: restore.8,v 1.16 1997/09/15 08:04:34 lukem Exp $
.\"
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
--- 1,4 ----
! .\" $NetBSD: restore.8,v 1.13 1996/12/24 02:32:25 mikel Exp $
.\"
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
***************
*** 33,46 ****
.\"
.\" @(#)restore.8 8.3 (Berkeley) 6/1/94
.\"
! .Dd July 1, 1997
.Dt RESTORE 8
.Os BSD 4
.Sh NAME
.Nm restore
.Nd "restore files or file systems from backups made with dump"
.Sh SYNOPSIS
! .Nm
.Fl i
.Op Fl chmvy
.Op Fl b Ar blocksize
--- 33,46 ----
.\"
.\" @(#)restore.8 8.3 (Berkeley) 6/1/94
.\"
! .Dd June 1, 1994
.Dt RESTORE 8
.Os BSD 4
.Sh NAME
.Nm restore
.Nd "restore files or file systems from backups made with dump"
.Sh SYNOPSIS
! .Nm restore
.Fl i
.Op Fl chmvy
.Op Fl b Ar blocksize
***************
*** 80,86 ****
is not documented here.)
.Sh DESCRIPTION
The
! .Nm
command performs the inverse function of
.Xr dump 8 .
A full backup of a file system may be restored and
--- 80,86 ----
is not documented here.)
.Sh DESCRIPTION
The
! .Nm restore
command performs the inverse function of
.Xr dump 8 .
A full backup of a file system may be restored and
***************
*** 88,94 ****
Single files and
directory subtrees may be restored from full or partial
backups.
! .Nm
works across a network;
to do this see the
.Fl f
--- 88,94 ----
Single files and
directory subtrees may be restored from full or partial
backups.
! .Nm Restore
works across a network;
to do this see the
.Fl f
***************
*** 106,112 ****
.It Fl i
This mode allows interactive restoration of files from a dump.
After reading in the directory information from the dump,
! .Nm
provides a shell like interface that allows the user to move
around the directory tree selecting files to be extracted.
The available commands are given below;
--- 106,112 ----
.It Fl i
This mode allows interactive restoration of files from a dump.
After reading in the directory information from the dump,
! .Nm restore
provides a shell like interface that allows the user to move
around the directory tree selecting files to be extracted.
The available commands are given below;
***************
*** 140,146 ****
.It Ic extract
All the files that are on the extraction list are extracted
from the dump.
! .Nm
will ask which volume the user wishes to mount.
The fastest way to extract a few files is to
start with the last volume, and work towards the first volume.
--- 140,146 ----
.It Ic extract
All the files that are on the extraction list are extracted
from the dump.
! .Nm Restore
will ask which volume the user wishes to mount.
The fastest way to extract a few files is to
start with the last volume, and work towards the first volume.
***************
*** 170,180 ****
.Ic ls
command to list the inode numbers of all entries.
It also causes
! .Nm
to print out information about each file as it is extracted.
.El
.It Fl R
! .Nm
requests a particular tape of a multi volume set on which to restart
a full restore
(see the
--- 170,180 ----
.Ic ls
command to list the inode numbers of all entries.
It also causes
! .Nm restore
to print out information about each file as it is extracted.
.El
.It Fl R
! .Nm Restore
requests a particular tape of a multi volume set on which to restart
a full restore
(see the
***************
*** 207,213 ****
.Ed
.Pp
Note that
! .Nm
leaves a file
.Pa restoresymtable
in the root directory to pass information between incremental
--- 207,213 ----
.Ed
.Pp
Note that
! .Nm restore
leaves a file
.Pa restoresymtable
in the root directory to pass information between incremental
***************
*** 215,221 ****
This file should be removed when the last incremental has been
restored.
.Pp
! .Nm "" ,
in conjunction with
.Xr newfs 8
and
--- 215,221 ----
This file should be removed when the last incremental has been
restored.
.Pp
! .Nm Restore ,
in conjunction with
.Xr newfs 8
and
***************
*** 264,274 ****
If the
.Fl b
option is not specified,
! .Nm
tries to determine the block size dynamically.
.It Fl c
Normally,
! .Nm
will try to determine dynamically whether the dump was made from an
old (pre-4.4) or new format file sytem. The
.Fl c
--- 264,274 ----
If the
.Fl b
option is not specified,
! .Nm restore
tries to determine the block size dynamically.
.It Fl c
Normally,
! .Nm restore
will try to determine dynamically whether the dump was made from an
old (pre-4.4) or new format file sytem. The
.Fl c
***************
*** 280,286 ****
.Ar file
may be a special device file
like
! .Pa /dev/rst0
(a tape drive),
.Pa /dev/rsd1c
(a disk drive),
--- 280,286 ----
.Ar file
may be a special device file
like
! .Pa /dev/rmt12
(a tape drive),
.Pa /dev/rsd1c
(a disk drive),
***************
*** 292,298 ****
.Dq host:file ,
or
.Dq user@host:file ,
! .Nm
reads from the named file on the remote host using
.Xr rmt 8 .
.Pp
--- 292,298 ----
.Dq host:file ,
or
.Dq user@host:file ,
! .Nm restore
reads from the named file on the remote host using
.Xr rmt 8 .
.Pp
***************
*** 311,319 ****
.Ar fileno
on a multi-file tape.
File numbering starts at 1.
.It Fl v
Normally
! .Nm
does its work silently.
The
.Fl v
--- 311,323 ----
.Ar fileno
on a multi-file tape.
File numbering starts at 1.
+ .It Fl u
+ Normally restore complains if a file already exists and does not
+ replace it. This option causes restore to unlink the file before
+ replace it.
.It Fl v
Normally
! .Nm restore
does its work silently.
The
.Fl v
***************
*** 330,353 ****
.Fl y
has been specified, or the user responds
.Ql y ,
! .Nm
will attempt to continue the restore.
.Pp
If a backup was made using more than one tape volume,
! .Nm
will notify the user when it is time to mount the next volume.
If the
.Fl x
or
.Fl i
flag has been specified,
! .Nm
will also ask which volume the user wishes to mount.
The fastest way to extract a few files is to
start with the last volume, and work towards the first volume.
.Pp
There are numerous consistency checks that can be listed by
! .Nm "" .
Most checks are self-explanatory or can ``never happen''.
Common errors are given below.
.Pp
--- 334,357 ----
.Fl y
has been specified, or the user responds
.Ql y ,
! .Nm restore
will attempt to continue the restore.
.Pp
If a backup was made using more than one tape volume,
! .Nm restore
will notify the user when it is time to mount the next volume.
If the
.Fl x
or
.Fl i
flag has been specified,
! .Nm restore
will also ask which volume the user wishes to mount.
The fastest way to extract a few files is to
start with the last volume, and work towards the first volume.
.Pp
There are numerous consistency checks that can be listed by
! .Nm restore .
Most checks are self-explanatory or can ``never happen''.
Common errors are given below.
.Pp
***************
*** 389,414 ****
.Pp
.It resync restore, skipped <num> blocks
After a dump read error,
! .Nm
may have to resynchronize itself.
This message lists the number of blocks that were skipped over.
.El
- .Sh ENVIRONMENT
- If the following environment variable exists it will be utilized by
- .Nm "" :
- .Bl -tag -width "TMPDIR" -compact
- .It TMPDIR
- The directory given in TMPDIR will be used
- instead of
- .Pa /tmp
- to store temporary files.
- Refer to
- .Xr environ 7
- for more information.
- .El
.Sh FILES
.Bl -tag -width "./restoresymtable" -compact
! .It Pa /dev/rst0
the default tape drive
.It Pa /dev/rst*
Raw SCSI tape interface
--- 393,405 ----
.Pp
.It resync restore, skipped <num> blocks
After a dump read error,
! .Nm restore
may have to resynchronize itself.
This message lists the number of blocks that were skipped over.
.El
.Sh FILES
.Bl -tag -width "./restoresymtable" -compact
! .It Pa /dev/rmt8
the default tape drive
.It Pa /dev/rst*
Raw SCSI tape interface
***************
*** 420,439 ****
information passed between incremental restores.
.El
.Sh SEE ALSO
- .Xr environ 7 ,
.Xr dump 8 ,
.Xr newfs 8 ,
.Xr mount 8 ,
.Xr rmt 8
.Sh BUGS
! .Nm
can get confused when doing incremental restores from
dumps that were made on active file systems.
.Pp
A level zero dump must be done after a full restore.
! Because
! .Nm
! runs in user code,
it has no control over inode allocation;
thus a full dump must be done to get a new set of directories
reflecting the new inode numbering,
--- 411,427 ----
information passed between incremental restores.
.El
.Sh SEE ALSO
.Xr dump 8 ,
.Xr newfs 8 ,
.Xr mount 8 ,
.Xr rmt 8
.Sh BUGS
! .Nm Restore
can get confused when doing incremental restores from
dumps that were made on active file systems.
.Pp
A level zero dump must be done after a full restore.
! Because restore runs in user code,
it has no control over inode allocation;
thus a full dump must be done to get a new set of directories
reflecting the new inode numbering,
***************
*** 459,467 ****
be the same across different processes.
In all other cases, the files are unique because it is possible to
have two different dumps started at the same time, and separate
! operations shouldn't conflict with each other.
.Sh HISTORY
The
! .Nm
command appeared in
.Bx 4.2 .
--- 447,456 ----
be the same across different processes.
In all other cases, the files are unique because it is possible to
have two different dumps started at the same time, and separate
! operations shouldn't conflict with each other. The environment
! variable TMPDIR may be set to change the location of these files.
.Sh HISTORY
The
! .Nm restore
command appeared in
.Bx 4.2 .
>Audit-Trail:
>Unformatted: