summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1997-07-05 05:36:01 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1997-07-05 05:36:01 +0000
commit53e2c54ed25403939273b0b08c8322910913f18e (patch)
tree2a87547334463c36a89113d3668e47660d044af3
parent8b5ae6cd40a8db5e9b98940439c80611746ea22f (diff)
Fix some incorrect strncpy usage.
From NetBSD (luke@netbsd.org) * verbosity additions displaying total & per-volume transfer times and rates * Add the ability to dump specific files & directories of a single filesystem. This uses fts(3) to access the directory structure (and not the raw device), so the standard access permissions are adhered to (unlike dumping an entire filesystem, which just requires read access to the raw disk device). * Support SIGINFO status reporting. * Remove now unused variables that previously stored the (e)uid. * Be more informative in a couple of error messages. From NetBSD (mrg) * fix NetBSD PR#3710, reported by Tatoku Ogaito <tacha@trap.fukui-med.ac.jp>. don't pass pw->pw_name into functions; make a copy.
-rw-r--r--sbin/dump/Makefile5
-rw-r--r--sbin/dump/dump.899
-rw-r--r--sbin/dump/dump.h14
-rw-r--r--sbin/dump/dumprmt.c40
-rw-r--r--sbin/dump/itime.c21
-rw-r--r--sbin/dump/main.c127
-rw-r--r--sbin/dump/optr.c20
-rw-r--r--sbin/dump/pathnames.h4
-rw-r--r--sbin/dump/tape.c130
-rw-r--r--sbin/dump/traverse.c131
-rw-r--r--sbin/dump/unctime.c6
11 files changed, 432 insertions, 165 deletions
diff --git a/sbin/dump/Makefile b/sbin/dump/Makefile
index 3b09bcd5fa4..969bb13977d 100644
--- a/sbin/dump/Makefile
+++ b/sbin/dump/Makefile
@@ -1,5 +1,6 @@
-# $OpenBSD: Makefile,v 1.6 1997/02/04 10:06:18 deraadt Exp $
-# $NetBSD: Makefile,v 1.16 1995/03/18 14:54:53 cgd Exp $
+# $OpenBSD: Makefile,v 1.7 1997/07/05 05:35:53 millert Exp $
+# $NetBSD: Makefile,v 1.17 1997/05/27 08:35:25 mrg Exp $
+# @(#)Makefile 8.1 (Berkeley) 6/5/93
# dump.h header file
# itime.c reads /etc/dumpdates
diff --git a/sbin/dump/dump.8 b/sbin/dump/dump.8
index f30ec414bbc..3d1faa363a0 100644
--- a/sbin/dump/dump.8
+++ b/sbin/dump/dump.8
@@ -1,5 +1,5 @@
-.\" $OpenBSD: dump.8,v 1.8 1997/06/02 08:48:32 deraadt Exp $
-.\" $NetBSD: dump.8,v 1.14 1996/02/05 23:59:37 mrg Exp $
+.\" $OpenBSD: dump.8,v 1.9 1997/07/05 05:35:53 millert Exp $
+.\" $NetBSD: dump.8,v 1.17 1997/06/05 11:15:06 lukem Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
.\" Regents of the University of California.
@@ -35,15 +35,15 @@
.\"
.\" @(#)dump.8 8.1 (Berkeley) 6/16/93
.\"
-.Dd June 16, 1993
+.Dd June 4, 1997
.Dt DUMP 8
.Os BSD 4
.Sh NAME
.Nm dump
.Nd filesystem backup
.Sh SYNOPSIS
-.Nm dump
-.Op Fl 0123456789cnua
+.Nm
+.Op Fl 0123456789acnu
.Op Fl B Ar records
.Op Fl b Ar blocksize
.Op Fl d Ar density
@@ -51,7 +51,7 @@
.Op Fl h Ar level
.Op Fl s Ar feet
.Op Fl T Ar date
-.Ar filesystem
+.Ar files-to-dump
.Nm dump
.Op Fl W Li \&| Fl w
.Pp
@@ -61,7 +61,7 @@
option syntax is implemented for backward compatibility, but
is not documented here.)
.Sh DESCRIPTION
-.Nm Dump
+.Nm
examines files
on a filesystem
and determines which files
@@ -86,6 +86,18 @@ block count options below.
By default, the same output file name is used for each volume
after prompting the operator to change media.
.Pp
+.Ar files-to-dump
+is either a mountpoint of a filesystem,
+or a list of files and directories on a single filesystem to be backed
+up as a subset of the filesystem.
+In the former case, either the path to a mounted filesystem,
+or the device of an unmounted filesystem can be used.
+In the latter case, certain restrictions are placed on the backup:
+.Fl u
+is ignored, the only dump level that is supported is
+.Fl 0 ,
+and all of the files must reside on the same filesystem.
+.Pp
The following options are supported by
.Nm dump :
.Bl -tag -width Ds
@@ -104,8 +116,8 @@ last dump of the same or lower level.
The default level is 9.
.It Fl a
.Dq auto-size .
-Bypass all tape length considerations, and enforce writing
-until an end-of-media indication is returned. This fits best
+Bypass all tape length considerations, and enforce writing until
+an end-of-media indication is returned. This option is recommended
for most modern tape drives. Use of this option is particularly
recommended when appending to an existing tape, or using a tape
drive with hardware compression (where you can never be sure about
@@ -113,8 +125,8 @@ the compression ratio).
.It Fl B Ar records
The number of kilobytes per volume, rounded
down to a multiple of the blocksize.
-This option overrides the calculation of tape size based on length and
-density.
+This option overrides the calculation of tape size
+based on length and density.
.It Fl b Ar blocksize
The number of kilobytes per dump record.
Since the IO system slices all requests into chunks of MAXBSIZE
@@ -154,7 +166,7 @@ If the name of the file is of the form
.Dq host:file ,
or
.Dq user@host:file ,
-.Nm dump
+.Nm
writes to the named file on the remote host using
.Xr rmt 8 .
.It Fl h Ar level
@@ -169,7 +181,7 @@ so that incremental backups omit such files
but full backups retain them.
.It Fl n
Whenever
-.Nm dump
+.Nm
requires operator attention,
notify all operators in the group
.Dq operator
@@ -179,7 +191,7 @@ by means similar to a
Attempt to calculate the amount of tape needed
at a particular density.
If this amount is exceeded,
-.Nm dump
+.Nm
prompts for a new tape.
It is recommended to be a bit conservative on this option.
The default tape length is 2300 feet.
@@ -214,8 +226,12 @@ The file
.Pa /etc/dumpdates
may be edited to change any of the fields,
if necessary.
+If a list of files or subdirectories is being dumped
+(as opposed to and entire filesystem), then
+.Fl u
+is ignored.
.It Fl W
-.Nm Dump
+.Nm
tells the operator what file systems need to be dumped.
This information is gleaned from the files
.Pa /etc/dumpdates
@@ -224,7 +240,7 @@ and
The
.Fl W
flag causes
-.Nm dump
+.Nm
to print out, for each file system in
.Pa /etc/dumpdates
the most recent dump date and level,
@@ -232,13 +248,13 @@ and highlights those file systems that should be dumped.
If the
.Fl W
flag is set, all other options are ignored, and
-.Nm dump
+.Nm
exits immediately.
.It Fl w
Is like W, but prints only those filesystems which need to be dumped.
.El
.Pp
-.Nm Dump
+.Nm
requires operator intervention on these conditions:
end of tape,
end of dump,
@@ -248,15 +264,15 @@ disk read error (if there are more than a threshold of 32).
In addition to alerting all operators implied by the
.Fl n
flag,
-.Nm dump
+.Nm
interacts with the operator on
.Nm dump Ns 's
control terminal at times when
-.Nm dump
+.Nm
can no longer proceed,
or if something is grossly wrong.
All questions
-.Nm dump
+.Nm
poses
.Em must
be answered by typing
@@ -266,17 +282,17 @@ or
appropriately.
.Pp
Since making a dump involves a lot of time and effort for full dumps,
-.Nm dump
+.Nm
checkpoints itself at the start of each tape volume.
If writing that volume fails for some reason,
-.Nm dump
+.Nm
will,
with operator permission,
restart itself from the checkpoint
after the old tape has been rewound and removed,
and a new tape has been mounted.
.Pp
-.Nm Dump
+.Nm
tells the operator what is going on at periodic intervals,
including usually low estimates of the number of blocks to write,
the number of tapes it will take, the time to completion, and
@@ -284,7 +300,7 @@ the time to the tape change.
The output is verbose,
so that others know that the terminal
controlling
-.Nm dump
+.Nm
is busy,
and will be for some time.
.Pp
@@ -321,6 +337,19 @@ used, also on a cyclical basis.
.Pp
After several months or so, the daily and weekly tapes should get
rotated out of the dump cycle and fresh tapes brought in.
+.Pp
+If
+.Nm
+receives a
+.Dv SIGINFO
+signal
+(see the
+.Dq status
+argument of
+.Xr stty 1 )
+whilst a backup is in progress, statistics on the amount completed,
+current transfer rate, and estimated finished time, will be written
+to the standard error output.
.Sh FILES
.Bl -tag -width /etc/dumpdates -compact
.It Pa /dev/rst0
@@ -336,13 +365,16 @@ to find group
.Em operator
.El
.Sh SEE ALSO
+.Xr stty 1 ,
+.Xr fts 3 ,
+.Xr fstab 5 ,
.Xr restore 8 ,
-.Xr rmt 8 ,
-.Xr fstab 5
+.Xr rmt 8
.Sh DIAGNOSTICS
Many, and verbose.
.Pp
-Dump exits with zero status on success.
+.Nm
+exits with zero status on success.
Startup errors are indicated with an exit code of 1;
abnormal termination is indicated with an exit code of 3.
.Sh BUGS
@@ -352,7 +384,7 @@ Each reel requires a new process, so parent processes for
reels already written just hang around until the entire tape
is written.
.Pp
-.Nm Dump
+.Nm
with the
.Fl W
or
@@ -363,8 +395,13 @@ in
even if listed in
.Pa /etc/fstab .
.Pp
+When dumping a list of files or subdirectories, access privileges are
+required to scan the directory (as this is done via the
+.Xr fts 3
+routines rather than directly accessing the filesystem).
+.Pp
It would be nice if
-.Nm dump
+.Nm
knew about the dump sequence,
kept track of the tapes scribbled on,
told the operator which tape to mount when,
@@ -373,5 +410,5 @@ for the operator running
.Xr restore .
.Sh HISTORY
A
-.Nm dump
+.Nm
command appeared in Version 6 AT&T UNIX.
diff --git a/sbin/dump/dump.h b/sbin/dump/dump.h
index b29ddac83af..6bb8d593e07 100644
--- a/sbin/dump/dump.h
+++ b/sbin/dump/dump.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: dump.h,v 1.4 1997/02/03 11:53:25 deraadt Exp $ */
-/* $NetBSD: dump.h,v 1.9 1995/03/18 14:54:57 cgd Exp $ */
+/* $OpenBSD: dump.h,v 1.5 1997/07/05 05:35:54 millert Exp $ */
+/* $NetBSD: dump.h,v 1.11 1997/06/05 11:13:20 lukem Exp $ */
/*-
* Copyright (c) 1980, 1993
@@ -83,6 +83,7 @@ int notify; /* notify operator flag */
int blockswritten; /* number of blocks written on current tape */
int tapeno; /* current tape number */
time_t tstart_writing; /* when started writing the first tape block */
+long xferrate; /* averaged transfer rate of all volumes */
struct fs *sblock; /* the file system super block */
char sblock_buf[MAXBSIZE];
long dev_bsize; /* block size of underlying disk device */
@@ -95,19 +96,22 @@ int tp_bshift; /* log2(TP_BSIZE) */
/* operator interface functions */
void broadcast __P((char *message));
+time_t do_stats __P((void));
void lastdump __P((int arg)); /* int should be char */
void msg __P((const char *fmt, ...));
void msgtail __P((const char *fmt, ...));
int query __P((char *question));
void quit __P((const char *fmt, ...));
-void set_operators __P((void));
+void statussig __P((int));
void timeest __P((void));
time_t unctime __P((char *str));
-/* mapping rouintes */
+/* mapping routines */
struct dinode;
long blockest __P((struct dinode *dp));
-int mapfiles __P((ino_t maxino, long *tapesize));
+void mapfileino __P((ino_t, long *, int *));
+int mapfiles __P((ino_t maxino, long *tapesize, char *disk,
+ char * const *dirv));
int mapdirs __P((ino_t maxino, long *tapesize));
/* file dumping routines */
diff --git a/sbin/dump/dumprmt.c b/sbin/dump/dumprmt.c
index c769cde2bb1..915af493132 100644
--- a/sbin/dump/dumprmt.c
+++ b/sbin/dump/dumprmt.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: dumprmt.c,v 1.7 1997/06/25 18:07:55 kstailey Exp $ */
-/* $NetBSD: dumprmt.c,v 1.10 1996/03/15 22:39:26 scottr Exp $ */
+/* $OpenBSD: dumprmt.c,v 1.8 1997/07/05 05:35:55 millert Exp $ */
+/* $NetBSD: dumprmt.c,v 1.17 1997/06/05 16:10:47 mrg Exp $ */
/*-
* Copyright (c) 1980, 1993
@@ -125,7 +125,7 @@ rmtgetconn()
#ifdef notdef
static int on = 1;
#endif
- char *tuser;
+ char *tuser, *name;
int size;
int maxseg;
@@ -137,6 +137,8 @@ rmtgetconn()
if (pwd == NULL)
errx(1, "who are you?");
}
+ if ((name = strdup(pwd->pw_name)) == NULL)
+ err(1, "malloc");
if ((cp = strchr(rmtpeer, '@')) != NULL) {
tuser = rmtpeer;
*cp = '\0';
@@ -144,10 +146,12 @@ rmtgetconn()
exit(1);
rmtpeer = ++cp;
} else
- tuser = pwd->pw_name;
+ tuser = name;
- rmtape = rcmd(&rmtpeer, (u_short)sp->s_port, pwd->pw_name, tuser,
- _PATH_RMT, NULL);
+ rmtape = rcmd(&rmtpeer, sp->s_port, name, tuser, _PATH_RMT, NULL);
+ (void)free(name);
+ if (rmtape < 0)
+ return;
size = ntrec * TP_BSIZE;
if (size > 60 * 1024) /* XXX */
@@ -155,16 +159,16 @@ rmtgetconn()
/* Leave some space for rmt request/response protocol */
size += 2 * 1024;
while (size > TP_BSIZE &&
- setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
+ setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0)
size -= TP_BSIZE;
- (void)setsockopt(rmtape, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
+ (void)setsockopt(rmtape, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
maxseg = 1024;
(void)setsockopt(rmtape, IPPROTO_TCP, TCP_MAXSEG, &maxseg,
- sizeof (maxseg));
+ sizeof(maxseg));
#ifdef notdef
- if (setsockopt(rmtape, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on)) < 0)
+ if (setsockopt(rmtape, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
perror("TCP_NODELAY setsockopt");
#endif
}
@@ -193,7 +197,7 @@ rmtopen(tape, mode)
{
char buf[256];
- (void)snprintf(buf, sizeof (buf), "O%s\n%d\n", tape, mode);
+ (void)snprintf(buf, sizeof(buf), "O%s\n%d\n", tape, mode);
rmtstate = TS_OPEN;
return (rmtcall(tape, buf));
}
@@ -217,7 +221,7 @@ rmtread(buf, count)
int n, i, cc;
extern errno;
- (void)snprintf(line, sizeof (line), "R%d\n", count);
+ (void)snprintf(line, sizeof(line), "R%d\n", count);
n = rmtcall("read", line);
if (n < 0) {
errno = n;
@@ -239,7 +243,7 @@ rmtwrite(buf, count)
{
char line[30];
- (void)snprintf(line, sizeof (line), "W%d\n", count);
+ (void)snprintf(line, sizeof(line), "W%d\n", count);
write(rmtape, line, strlen(line));
write(rmtape, buf, count);
return (rmtreply("write"));
@@ -251,7 +255,7 @@ rmtwrite0(count)
{
char line[30];
- (void)snprintf(line, sizeof (line), "W%d\n", count);
+ (void)snprintf(line, sizeof(line), "W%d\n", count);
write(rmtape, line, strlen(line));
}
@@ -277,7 +281,7 @@ rmtseek(offset, pos)
{
char line[80];
- (void)snprintf(line, sizeof (line), "L%d\n%d\n", offset, pos);
+ (void)snprintf(line, sizeof(line), "L%d\n%d\n", offset, pos);
return (rmtcall("seek", line));
}
@@ -305,7 +309,7 @@ rmtioctl(cmd, count)
if (count < 0)
return (-1);
- (void)snprintf(buf, sizeof (buf), "I%d\n%d\n", cmd, count);
+ (void)snprintf(buf, sizeof(buf), "I%d\n%d\n", cmd, count);
return (rmtcall("ioctl", buf));
}
@@ -326,9 +330,9 @@ rmtreply(cmd)
register char *cp;
char code[30], emsg[BUFSIZ];
- rmtgets(code, sizeof (code));
+ rmtgets(code, sizeof(code));
if (*code == 'E' || *code == 'F') {
- rmtgets(emsg, sizeof (emsg));
+ rmtgets(emsg, sizeof(emsg));
msg("%s: %s", cmd, emsg);
if (*code == 'F') {
rmtstate = TS_CLOSED;
diff --git a/sbin/dump/itime.c b/sbin/dump/itime.c
index 5f68b30c17f..ce80a96c20f 100644
--- a/sbin/dump/itime.c
+++ b/sbin/dump/itime.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: itime.c,v 1.2 1996/06/23 14:30:11 deraadt Exp $ */
-/* $NetBSD: itime.c,v 1.3 1995/03/18 14:55:01 cgd Exp $ */
+/* $OpenBSD: itime.c,v 1.3 1997/07/05 05:35:56 millert Exp $ */
+/* $NetBSD: itime.c,v 1.4 1997/04/15 01:09:50 lukem Exp $ */
/*-
* Copyright (c) 1980, 1993
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)itime.c 8.1 (Berkeley) 6/5/93";
#else
-static char rcsid[] = "$OpenBSD: itime.c,v 1.2 1996/06/23 14:30:11 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: itime.c,v 1.3 1997/07/05 05:35:56 millert Exp $";
#endif
#endif /* not lint */
@@ -117,7 +117,7 @@ readdumptimes(df)
register struct dumptime *dtwalk;
for (;;) {
- dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime));
+ dtwalk = (struct dumptime *)calloc(1, sizeof(struct dumptime));
if (getrecord(df, &(dtwalk->dt_value)) < 0)
break;
nddates++;
@@ -131,7 +131,7 @@ readdumptimes(df)
* record that we may have to add to the ddate structure
*/
ddatev = (struct dumpdates **)
- calloc((unsigned) (nddates + 1), sizeof (struct dumpdates *));
+ calloc((unsigned) (nddates + 1), sizeof(struct dumpdates *));
dtwalk = dthead;
for (i = nddates - 1; i >= 0; i--, dtwalk = dtwalk->dt_next)
ddatev[i] = &dtwalk->dt_value;
@@ -158,7 +158,7 @@ getdumptime()
* and older date
*/
ITITERATE(i, ddp) {
- if (strncmp(fname, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
+ if (strncmp(fname, ddp->dd_name, sizeof(ddp->dd_name)) != 0)
continue;
if (ddp->dd_level >= level)
continue;
@@ -196,7 +196,7 @@ putdumptime()
spcl.c_ddate = 0;
ITITERATE(i, dtwalk) {
if (strncmp(fname, dtwalk->dd_name,
- sizeof (dtwalk->dd_name)) != 0)
+ sizeof(dtwalk->dd_name)) != 0)
continue;
if (dtwalk->dd_level != level)
continue;
@@ -207,10 +207,11 @@ putdumptime()
* Enough room has been allocated.
*/
dtwalk = ddatev[nddates] =
- (struct dumpdates *)calloc(1, sizeof (struct dumpdates));
+ (struct dumpdates *)calloc(1, sizeof(struct dumpdates));
nddates += 1;
found:
- (void) strncpy(dtwalk->dd_name, fname, sizeof (dtwalk->dd_name));
+ (void) strncpy(dtwalk->dd_name, fname, sizeof(dtwalk->dd_name) - 1);
+ dtwalk->dd_name[sizeof(dtwalk->dd_name) - 1] = '\0';
dtwalk->dd_level = level;
dtwalk->dd_ddate = spcl.c_date;
@@ -249,7 +250,7 @@ getrecord(df, ddatep)
char tbuf[BUFSIZ];
recno = 0;
- if ( (fgets(tbuf, sizeof (tbuf), df)) != tbuf)
+ if (fgets(tbuf, sizeof(tbuf), df) == NULL)
return(-1);
recno++;
if (makedumpdate(ddatep, tbuf) < 0)
diff --git a/sbin/dump/main.c b/sbin/dump/main.c
index debad044477..01c4c55da07 100644
--- a/sbin/dump/main.c
+++ b/sbin/dump/main.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: main.c,v 1.16 1997/04/16 04:09:21 millert Exp $ */
-/* $NetBSD: main.c,v 1.8 1996/03/15 22:39:32 scottr Exp $ */
+/* $OpenBSD: main.c,v 1.17 1997/07/05 05:35:56 millert Exp $ */
+/* $NetBSD: main.c,v 1.14 1997/06/05 11:13:24 lukem Exp $ */
/*-
* Copyright (c) 1980, 1991, 1993, 1994
@@ -49,6 +49,8 @@ static char rcsid[] = "$NetBSD: main.c,v 1.8 1996/03/15 22:39:32 scottr Exp $";
#endif /* not lint */
#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
#include <sys/time.h>
#ifdef sunos
#include <sys/vnode.h>
@@ -72,6 +74,7 @@ static char rcsid[] = "$NetBSD: main.c,v 1.8 1996/03/15 22:39:32 scottr Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <unistd.h>
#include "dump.h"
@@ -96,20 +99,22 @@ static long numarg __P((char *, long, long));
static void obsolete __P((int *, char **[]));
static void usage __P((void));
-
int
main(argc, argv)
int argc;
char *argv[];
{
register ino_t ino;
- register int dirty;
+ register int dirty;
register struct dinode *dp;
register struct fstab *dt;
register char *map;
register int ch;
int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
ino_t maxino;
+ time_t tnow;
+ int dirlist;
+ char *toplevel;
spcl.c_date = 0;
(void)time((time_t *)&spcl.c_date);
@@ -209,14 +214,68 @@ main(argc, argv)
(void)fprintf(stderr, "Must specify disk or filesystem\n");
exit(X_ABORT);
}
- disk = *argv++;
- argc--;
- if (argc >= 1) {
- (void)fprintf(stderr, "Unknown arguments to dump:");
- while (argc--)
- (void)fprintf(stderr, " %s", *argv++);
- (void)fprintf(stderr, "\n");
- exit(X_ABORT);
+
+ /*
+ * determine if disk is a subdirectory, and setup appropriately
+ */
+ dirlist = 0;
+ toplevel = NULL;
+ for (i = 0; i < argc; i++) {
+ struct stat sb;
+ struct statfs fsbuf;
+
+ if (lstat(argv[i], &sb) == -1) {
+ msg("Cannot lstat %s: %s\n", argv[i], strerror(errno));
+ exit(X_ABORT);
+ }
+ if (!S_ISDIR(sb.st_mode) && !S_ISREG(sb.st_mode))
+ break;
+ if (statfs(argv[i], &fsbuf) == -1) {
+ msg("Cannot statfs %s: %s\n", argv[i], strerror(errno));
+ exit(X_ABORT);
+ }
+ if (strcmp(argv[i], fsbuf.f_mntonname) == 0) {
+ if (dirlist != 0) {
+ msg("Can't dump a mountpoint and a filelist\n");
+ exit(X_ABORT);
+ }
+ break; /* exit if sole mountpoint */
+ }
+ if (!disk) {
+ if ((toplevel = strdup(fsbuf.f_mntonname)) == NULL) {
+ msg("Cannot malloc diskname\n");
+ exit(X_ABORT);
+ }
+ disk = toplevel;
+ if (uflag) {
+ msg("Ignoring u flag for subdir dump\n");
+ uflag = 0;
+ }
+ if (level > '0') {
+ msg("Subdir dump is done at level 0\n");
+ level = '0';
+ }
+ msg("Dumping sub files/directories from %s\n", disk);
+ } else {
+ if (strcmp(disk, fsbuf.f_mntonname) != 0) {
+ msg("%s is not on %s\n", argv[i], disk);
+ exit(X_ABORT);
+ }
+ }
+ msg("Dumping file/directory %s\n", argv[i]);
+ dirlist++;
+ }
+ if (dirlist == 0) {
+ disk = *argv++;
+ if (argc != 1) {
+ (void)fputs("Excess arguments to dump:", stderr);
+ while (--argc) {
+ (void)putc(' ', stderr);
+ (void)fputs(*argv++, stderr);
+ }
+ (void)putc('\n', stderr);
+ exit(X_ABORT);
+ }
}
if (Tflag && uflag) {
(void)fprintf(stderr,
@@ -275,6 +334,7 @@ main(argc, argv)
signal(SIGINT, SIG_IGN);
getfstab(); /* /etc/fstab snarfed */
+
/*
* disk can be either the full special file name,
* the suffix of the special file name,
@@ -284,15 +344,26 @@ main(argc, argv)
dt = fstabsearch(disk);
if (dt != NULL) {
disk = rawname(dt->fs_spec);
- (void)strncpy(spcl.c_dev, dt->fs_spec, NAMELEN);
- (void)strncpy(spcl.c_filesys, dt->fs_file, NAMELEN);
+ (void)strncpy(spcl.c_dev, dt->fs_spec, sizeof(spcl.c_dev) - 1);
+ spcl.c_dev[sizeof(spcl.c_dev) - 1] = '\0';
+ if (dirlist != 0) {
+ (void)snprintf(spcl.c_filesys, sizeof(spcl.c_filesys),
+ "a subset of %s", dt->fs_file);
+ } else {
+ (void)strncpy(spcl.c_filesys, dt->fs_file,
+ sizeof(spcl.c_filesys) - 1);
+ spcl.c_filesys[sizeof(spcl.c_filesys) - 1] = '\0';
+ }
} else {
- (void)strncpy(spcl.c_dev, disk, NAMELEN);
+ (void)strncpy(spcl.c_dev, disk, sizeof(spcl.c_dev) - 1);
+ spcl.c_dev[sizeof(spcl.c_dev) - 1] = '\0';
(void)strncpy(spcl.c_filesys, "an unlisted file system",
- NAMELEN);
+ sizeof(spcl.c_filesys) - 1);
+ spcl.c_filesys[sizeof(spcl.c_filesys) - 1] = '\0';
}
- (void)strcpy(spcl.c_label, "none");
- (void)gethostname(spcl.c_host, NAMELEN);
+ (void)strncpy(spcl.c_label, "none", sizeof(spcl.c_label) - 1);
+ spcl.c_label[sizeof(spcl.c_label) - 1] = '\0';
+ (void)gethostname(spcl.c_host, sizeof(spcl.c_host));
spcl.c_level = level - '0';
spcl.c_type = TS_TAPE;
if (!Tflag)
@@ -339,8 +410,11 @@ main(argc, argv)
nonodump = spcl.c_level < honorlevel;
+ (void)signal(SIGINFO, statussig);
+
msg("mapping (Pass I) [regular files]\n");
- anydirskipped = mapfiles(maxino, &tapesize);
+ anydirskipped = mapfiles(maxino, &tapesize, toplevel,
+ (dirlist ? argv : NULL));
msg("mapping (Pass II) [directories]\n");
while (anydirskipped) {
@@ -360,7 +434,7 @@ main(argc, argv)
the end of each block written, and not in mid-block.
Assume no erroneous blocks; this can be compensated
for with an artificially low tape size. */
- fetapes =
+ fetapes =
( tapesize /* blocks */
* TP_BSIZE /* bytes/block */
* (1.0/density) /* 0.1" / byte */
@@ -401,6 +475,7 @@ main(argc, argv)
startnewtape(1);
(void)time((time_t *)&(tstart_writing));
+ xferrate = 0;
dumpmap(usedinomap, TS_CLRI, maxino - 1);
msg("dumping (Pass III) [directories]\n");
@@ -449,7 +524,12 @@ main(argc, argv)
else
msg("%ld tape blocks on %d volume%s\n",
spcl.c_tapea, spcl.c_volume,
- spcl.c_volume > 1 ? "s" : "");
+ (spcl.c_volume == 1) ? "" : "s");
+ tnow = do_stats();
+ msg("Date of this level %c dump: %s", level,
+ spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
+ msg("Date this dump completed: %s", ctime(&tnow));
+ msg("Average transfer rate: %ld KB/s\n", xferrate / tapeno);
putdumptime();
trewind();
broadcast("DUMP IS DONE!\7\7\n");
@@ -524,11 +604,8 @@ rawname(cp)
if (dp == NULL)
return (NULL);
*dp = '\0';
- (void)strncpy(rawbuf, cp, MAXPATHLEN-1);
- rawbuf[MAXPATHLEN-1] = '\0';
+ (void)snprintf(rawbuf, sizeof(rawbuf), "%s/r%s", cp, dp + 1);
*dp = '/';
- (void)strncat(rawbuf, "/r", MAXPATHLEN - strlen(rawbuf));
- (void)strncat(rawbuf, dp + 1, MAXPATHLEN - strlen(rawbuf));
return (rawbuf);
}
diff --git a/sbin/dump/optr.c b/sbin/dump/optr.c
index 2c63f065d33..9e4d14373d0 100644
--- a/sbin/dump/optr.c
+++ b/sbin/dump/optr.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: optr.c,v 1.13 1997/06/25 18:07:57 kstailey Exp $ */
-/* $NetBSD: optr.c,v 1.4 1996/05/18 16:16:17 jtk Exp $ */
+/* $OpenBSD: optr.c,v 1.14 1997/07/05 05:35:57 millert Exp $ */
+/* $NetBSD: optr.c,v 1.11 1997/05/27 08:34:36 mrg Exp $ */
/*-
* Copyright (c) 1980, 1988, 1993
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)optr.c 8.2 (Berkeley) 1/6/94";
#else
-static char rcsid[] = "$OpenBSD: optr.c,v 1.13 1997/06/25 18:07:57 kstailey Exp $";
+static char rcsid[] = "$OpenBSD: optr.c,v 1.14 1997/07/05 05:35:57 millert Exp $";
#endif
#endif /* not lint */
@@ -70,7 +70,6 @@ static char rcsid[] = "$OpenBSD: optr.c,v 1.13 1997/06/25 18:07:57 kstailey Exp
void alarmcatch __P((/* int, int */));
int datesort __P((const void *, const void *));
-static void sendmes __P((char *, char *));
/*
* Query the operator; This previously-fascist piece of code
@@ -179,21 +178,20 @@ interrupt(signo)
dumpabort(0);
}
-/*
+/*
* We now use wall(1) to do the actual broadcasting.
- */
+ */
void
broadcast(message)
char *message;
{
FILE *fp;
- char buf[sizeof(_PATH_WALL) + 12];
+ char buf[sizeof(_PATH_WALL) + sizeof(OPGRENT) + 3];
if (!notify)
return;
- (void) strcpy(buf, _PATH_WALL);
- (void) strcpy(buf + sizeof(_PATH_WALL) - 1, " -g operator");
+ (void)snprintf(buf, sizeof(buf), "%s -g %s", _PATH_WALL, OPGRENT);
if ((fp = popen(buf, "w")) == NULL)
return;
@@ -315,7 +313,7 @@ allocfsent(fs)
{
register struct fstab *new;
- new = (struct fstab *)malloc(sizeof (*fs));
+ new = (struct fstab *)malloc(sizeof(*fs));
if (new == NULL ||
(new->fs_file = strdup(fs->fs_file)) == NULL ||
(new->fs_type = strdup(fs->fs_type)) == NULL ||
@@ -353,7 +351,7 @@ getfstab()
strcmp(fs->fs_type, FSTAB_RQ))
continue;
fs = allocfsent(fs);
- if ((pf = (struct pfstab *)malloc(sizeof (*pf))) == NULL)
+ if ((pf = (struct pfstab *)malloc(sizeof(*pf))) == NULL)
quit("%s\n", strerror(errno));
pf->pf_fstab = fs;
pf->pf_next = table;
diff --git a/sbin/dump/pathnames.h b/sbin/dump/pathnames.h
index b6ee24c553e..4718225b941 100644
--- a/sbin/dump/pathnames.h
+++ b/sbin/dump/pathnames.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: pathnames.h,v 1.4 1997/04/16 04:09:22 millert Exp $ */
-/* $NetBSD: pathnames.h,v 1.8 1995/03/18 14:55:06 cgd Exp $ */
+/* $OpenBSD: pathnames.h,v 1.5 1997/07/05 05:35:57 millert Exp $ */
+/* $NetBSD: pathnames.h,v 1.9 1997/04/15 07:00:47 lukem Exp $ */
/*
* Copyright (c) 1989, 1993
diff --git a/sbin/dump/tape.c b/sbin/dump/tape.c
index 052b679cb10..a722c410e03 100644
--- a/sbin/dump/tape.c
+++ b/sbin/dump/tape.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tape.c,v 1.3 1997/02/03 11:53:27 deraadt Exp $ */
-/* $NetBSD: tape.c,v 1.7 1995/03/21 18:48:47 mycroft Exp $ */
+/* $OpenBSD: tape.c,v 1.4 1997/07/05 05:35:58 millert Exp $ */
+/* $NetBSD: tape.c,v 1.11 1997/06/05 11:13:26 lukem Exp $ */
/*-
* Copyright (c) 1980, 1991, 1993
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)tape.c 8.2 (Berkeley) 3/17/94";
#else
-static char rcsid[] = "$OpenBSD: tape.c,v 1.3 1997/02/03 11:53:27 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: tape.c,v 1.4 1997/07/05 05:35:58 millert Exp $";
#endif
#endif /* not lint */
@@ -66,6 +66,7 @@ static char rcsid[] = "$OpenBSD: tape.c,v 1.3 1997/02/03 11:53:27 deraadt Exp $"
#ifdef __STDC__
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <unistd.h>
#else
int write(), read();
@@ -122,6 +123,9 @@ struct slave *slp;
char (*nextblock)[TP_BSIZE];
+static time_t tstart_volume; /* time of volume start */
+static int tapea_volume; /* value of spcl.c_tapea at volume start */
+
int master; /* pid of master, for sending error signals */
int tenths; /* length of tape used per block written */
static int caught; /* have we caught the signal to proceed? */
@@ -240,6 +244,55 @@ sigpipe(signo)
quit("Broken pipe\n");
}
+/*
+ * do_stats --
+ * Update xferrate stats
+ */
+time_t
+do_stats()
+{
+ time_t tnow, ttaken;
+ int blocks;
+
+ (void)time(&tnow);
+ ttaken = tnow - tstart_volume;
+ blocks = spcl.c_tapea - tapea_volume;
+ msg("Volume %d completed at: %s", tapeno, ctime(&tnow));
+ if (ttaken > 0) {
+ msg("Volume %d took %d:%02d:%02d\n", tapeno,
+ ttaken / 3600, (ttaken % 3600) / 60, ttaken % 60);
+ msg("Volume %d transfer rate: %ld KB/s\n", tapeno,
+ blocks / ttaken);
+ xferrate += blocks / ttaken;
+ }
+ return(tnow);
+}
+
+/*
+ * statussig --
+ * information message upon receipt of SIGINFO
+ * (derived from optr.c::timeest())
+ */
+void
+statussig(notused)
+ int notused;
+{
+ time_t tnow, deltat;
+ char msgbuf[128];
+
+ if (blockswritten < 500)
+ return;
+ (void) time((time_t *) &tnow);
+ deltat = tstart_writing - tnow + (1.0 * (tnow - tstart_writing))
+ / blockswritten * tapesize;
+ (void)snprintf(msgbuf, sizeof(msgbuf),
+ "%3.2f%% done at %ld KB/s, finished in %d:%02d\n",
+ (blockswritten * 100.0) / tapesize,
+ (spcl.c_tapea - tapea_volume) / (tnow - tstart_volume),
+ (int)(deltat / 3600), (int)((deltat % 3600) / 60));
+ write(STDERR_FILENO, msgbuf, strlen(msgbuf));
+}
+
static void
flushtape()
{
@@ -261,8 +314,8 @@ flushtape()
/* Read results back from next slave */
if (slp->sent) {
- if (atomic(read, slp->fd, (char *)&got, sizeof got)
- != sizeof got) {
+ if (atomic(read, slp->fd, (char *)&got, sizeof(got))
+ != sizeof(got)) {
perror(" DUMP: error reading command pipe in master");
dumpabort(0);
}
@@ -279,8 +332,8 @@ flushtape()
for (i = 0; i < SLAVES; i++) {
if (slaves[i].sent) {
if (atomic(read, slaves[i].fd,
- (char *)&got, sizeof got)
- != sizeof got) {
+ (char *)&got, sizeof(got))
+ != sizeof(got)) {
perror(" DUMP: error reading command pipe in master");
dumpabort(0);
}
@@ -325,16 +378,16 @@ trewind()
for (f = 0; f < SLAVES; f++) {
/*
- * Drain the results, but unlike EOT we DO (or should) care
- * what the return values were, since if we detect EOT after
- * we think we've written the last blocks to the tape anyway,
+ * Drain the results, but unlike EOT we DO (or should) care
+ * what the return values were, since if we detect EOT after
+ * we think we've written the last blocks to the tape anyway,
* we have to replay those blocks with rollforward.
*
- * fixme: punt for now.
+ * fixme: punt for now.
*/
if (slaves[f].sent) {
- if (atomic(read, slaves[f].fd, (char *)&got, sizeof got)
- != sizeof got) {
+ if (atomic(read, slaves[f].fd, (char *)&got, sizeof(got))
+ != sizeof(got)) {
perror(" DUMP: error reading command pipe in master");
dumpabort(0);
}
@@ -374,6 +427,7 @@ void
close_rewind()
{
trewind();
+ (void)do_stats();
if (nexttape)
return;
if (!nogripe) {
@@ -398,9 +452,9 @@ rollforward()
ntb = (union u_spcl *)tslp->tblock[1];
/*
- * Each of the N slaves should have requests that need to
- * be replayed on the next tape. Use the extra slave buffers
- * (slaves[SLAVES]) to construct request lists to be sent to
+ * Each of the N slaves should have requests that need to
+ * be replayed on the next tape. Use the extra slave buffers
+ * (slaves[SLAVES]) to construct request lists to be sent to
* each slave in turn.
*/
for (i = 0; i < SLAVES; i++) {
@@ -408,7 +462,7 @@ rollforward()
otb = (union u_spcl *)slp->tblock;
/*
- * For each request in the current slave, copy it to tslp.
+ * For each request in the current slave, copy it to tslp.
*/
prev = NULL;
@@ -452,8 +506,8 @@ rollforward()
if (prev->dblk != 0) {
/*
- * If the last one was a disk block, make the
- * first of this one be the last bit of that disk
+ * If the last one was a disk block, make the
+ * first of this one be the last bit of that disk
* block...
*/
q->dblk = prev->dblk +
@@ -461,7 +515,7 @@ rollforward()
ntb = (union u_spcl *)tslp->tblock;
} else {
/*
- * It wasn't a disk block. Copy the data to its
+ * It wasn't a disk block. Copy the data to its
* new location in the buffer.
*/
q->dblk = 0;
@@ -480,8 +534,8 @@ rollforward()
* worked ok, otherwise the tape is much too short!
*/
if (slp->sent) {
- if (atomic(read, slp->fd, (char *)&got, sizeof got)
- != sizeof got) {
+ if (atomic(read, slp->fd, (char *)&got, sizeof(got))
+ != sizeof(got)) {
perror(" DUMP: error reading command pipe in master");
dumpabort(0);
}
@@ -519,6 +573,8 @@ startnewtape(top)
interrupt_save = signal(SIGINT, SIG_IGN);
parentpid = getpid();
+ tapea_volume = spcl.c_tapea;
+ (void)time(&tstart_volume);
restore_check_point:
(void)signal(SIGINT, interrupt_save);
@@ -586,7 +642,7 @@ restore_check_point:
tapeno+1, parentpid, getpid());
#endif /* TDEBUG */
/*
- * If we have a name like "/dev/rmt0,/dev/rmt1",
+ * If we have a name like "/dev/rst0,/dev/rst1",
* use the name before the comma first, and save
* the remaining names for subsequent volumes.
*/
@@ -605,7 +661,7 @@ restore_check_point:
while ((tapefd = (host ? rmtopen(tape, 2) :
pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
#else
- while ((tapefd = (pipeout ? 1 :
+ while ((tapefd = (pipeout ? 1 :
open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
#endif
{
@@ -620,7 +676,7 @@ restore_check_point:
blocksthisvol = 0;
if (top)
newtape++; /* new tape signal */
- spcl.c_count = slp->count;
+ spcl.c_count = slp->count;
/*
* measure firstrec in TP_BSIZE units since restore doesn't
* know the correct ntrec value...
@@ -631,6 +687,7 @@ restore_check_point:
spcl.c_flags |= DR_NEWHEADER;
writeheader((ino_t)slp->inode);
spcl.c_flags &=~ DR_NEWHEADER;
+ msg("Volume %d started at: %s", tapeno, ctime(&tstart_volume));
if (tapeno > 1)
msg("Volume %d begins with blocks from inode %d\n",
tapeno, slp->inode);
@@ -710,17 +767,18 @@ enslave()
for (j = 0; j <= i; j++)
(void) close(slaves[j].fd);
signal(SIGINT, SIG_IGN); /* Master handles this */
+ signal(SIGINFO, SIG_IGN);
doslave(cmd[0], i);
Exit(X_FINOK);
}
}
for (i = 0; i < SLAVES; i++)
- (void) atomic(write, slaves[i].fd,
- (char *) &slaves[(i + 1) % SLAVES].pid,
- sizeof slaves[0].pid);
+ (void) atomic(write, slaves[i].fd,
+ (char *) &slaves[(i + 1) % SLAVES].pid,
+ sizeof(slaves[0].pid));
- master = 0;
+ master = 0;
}
void
@@ -759,8 +817,8 @@ doslave(cmd, slave_number)
/*
* Need the pid of the next slave in the loop...
*/
- if ((nread = atomic(read, cmd, (char *)&nextslave, sizeof nextslave))
- != sizeof nextslave) {
+ if ((nread = atomic(read, cmd, (char *)&nextslave, sizeof(nextslave)))
+ != sizeof(nextslave)) {
quit("master/slave protocol botched - didn't get pid of next slave.\n");
}
@@ -777,7 +835,7 @@ doslave(cmd, slave_number)
p->count * TP_BSIZE);
} else {
if (p->count != 1 || atomic(read, cmd,
- (char *)slp->tblock[trecno],
+ (char *)slp->tblock[trecno],
TP_BSIZE) != TP_BSIZE)
quit("master/slave protocol botched.\n");
}
@@ -806,7 +864,7 @@ doslave(cmd, slave_number)
#ifdef WRITEDEBUG
printf("slave %d wrote %d\n", slave_number, wrote);
#endif
- if (wrote < 0)
+ if (wrote < 0)
break;
if (wrote == 0)
eot_count++;
@@ -814,7 +872,7 @@ doslave(cmd, slave_number)
}
#ifdef WRITEDEBUG
- if (size != writesize)
+ if (size != writesize)
printf("slave %d only wrote %d out of %d bytes and gave up.\n",
slave_number, size, writesize);
#endif
@@ -836,8 +894,8 @@ doslave(cmd, slave_number)
* pass size of write back to master
* (for EOT handling)
*/
- (void) atomic(write, cmd, (char *)&size, sizeof size);
- }
+ (void) atomic(write, cmd, (char *)&size, sizeof(size));
+ }
/*
* If partial write, don't want next slave to go.
diff --git a/sbin/dump/traverse.c b/sbin/dump/traverse.c
index 185417bdf99..b12df71ff79 100644
--- a/sbin/dump/traverse.c
+++ b/sbin/dump/traverse.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: traverse.c,v 1.3 1996/12/04 01:41:52 deraadt Exp $ */
-/* $NetBSD: traverse.c,v 1.15 1996/11/30 18:03:27 cgd Exp $ */
+/* $OpenBSD: traverse.c,v 1.4 1997/07/05 05:35:59 millert Exp $ */
+/* $NetBSD: traverse.c,v 1.17 1997/06/05 11:13:27 lukem Exp $ */
/*-
* Copyright (c) 1980, 1988, 1991, 1993
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)traverse.c 8.2 (Berkeley) 9/23/93";
#else
-static char rcsid[] = "$OpenBSD: traverse.c,v 1.3 1996/12/04 01:41:52 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: traverse.c,v 1.4 1997/07/05 05:35:59 millert Exp $";
#endif
#endif /* not lint */
@@ -60,6 +60,8 @@ static char rcsid[] = "$OpenBSD: traverse.c,v 1.3 1996/12/04 01:41:52 deraadt Ex
#include <protocols/dumprestore.h>
#include <ctype.h>
+#include <errno.h>
+#include <fts.h>
#include <stdio.h>
#ifdef __STDC__
#include <string.h>
@@ -135,6 +137,36 @@ blockest(dp)
#endif
/*
+ * Determine if given inode should be dumped
+ */
+void
+mapfileino(ino, tapesize, dirskipped)
+ ino_t ino;
+ long *tapesize;
+ int *dirskipped;
+{
+ int mode;
+ struct dinode *dp;
+
+ dp = getino(ino);
+ if ((mode = (dp->di_mode & IFMT)) == 0)
+ return;
+ SETINO(ino, usedinomap);
+ if (mode == IFDIR)
+ SETINO(ino, dumpdirmap);
+ if (WANTTODUMP(dp)) {
+ SETINO(ino, dumpinomap);
+ if (mode != IFREG && mode != IFDIR && mode != IFLNK)
+ *tapesize += 1;
+ else
+ *tapesize += blockest(dp);
+ return;
+ }
+ if (mode == IFDIR)
+ *dirskipped = 1;
+}
+
+/*
* Dump pass 1.
*
* Walk the inode list for a filesystem to find all allocated inodes
@@ -142,32 +174,87 @@ blockest(dp)
* the directories in the filesystem.
*/
int
-mapfiles(maxino, tapesize)
+mapfiles(maxino, tapesize, disk, dirv)
ino_t maxino;
long *tapesize;
+ char *disk;
+ char * const *dirv;
{
- register int mode;
- register ino_t ino;
- register struct dinode *dp;
int anydirskipped = 0;
- for (ino = ROOTINO; ino < maxino; ino++) {
- dp = getino(ino);
- if ((mode = (dp->di_mode & IFMT)) == 0)
- continue;
- SETINO(ino, usedinomap);
- if (mode == IFDIR)
- SETINO(ino, dumpdirmap);
- if (WANTTODUMP(dp)) {
- SETINO(ino, dumpinomap);
- if (mode != IFREG && mode != IFDIR && mode != IFLNK)
- *tapesize += 1;
+ if (dirv != NULL) {
+ char curdir[MAXPATHLEN];
+ FTS *dirh;
+ FTSENT *entry;
+ int d;
+
+ if (getcwd(curdir, sizeof(curdir)) == NULL) {
+ msg("Can't determine cwd: %s\n", strerror(errno));
+ dumpabort(0);
+ }
+ if ((dirh = fts_open(dirv, FTS_PHYSICAL|FTS_SEEDOT|FTS_XDEV,
+ (int (*)())NULL)) == NULL) {
+ msg("fts_open failed: %s\n", strerror(errno));
+ dumpabort(0);
+ }
+ while ((entry = fts_read(dirh)) != NULL) {
+ switch (entry->fts_info) {
+ case FTS_DNR: /* an error */
+ case FTS_ERR:
+ case FTS_NS:
+ msg("Can't fts_read %s: %s\n", entry->fts_path,
+ strerror(errno));
+ case FTS_DP: /* already seen dir */
+ continue;
+ }
+ mapfileino(entry->fts_statp->st_ino, tapesize,
+ &anydirskipped);
+ }
+ (void)fts_close(dirh);
+
+ /*
+ * Add any parent directories
+ */
+ for (d = 0 ; dirv[d] != NULL ; d++) {
+ char path[MAXPATHLEN];
+
+ if (dirv[d][0] != '/')
+ (void)snprintf(path, sizeof(path), "%s/%s",
+ curdir, dirv[d]);
else
- *tapesize += blockest(dp);
- continue;
+ (void)snprintf(path, sizeof(path), "%s",
+ dirv[d]);
+ while (strcmp(path, disk) != 0) {
+ char *p;
+ struct stat sb;
+
+ if (*path == '\0')
+ break;
+ if ((p = strrchr(path, '/')) == NULL)
+ break;
+ if (p == path)
+ break;
+ *p = '\0';
+ if (stat(path, &sb) == -1) {
+ msg("Can't stat %s: %s\n", path,
+ strerror(errno));
+ break;
+ }
+ mapfileino(sb.st_ino, tapesize, &anydirskipped);
+ }
+ }
+
+ /*
+ * Ensure that the root inode actually appears in the
+ * file list for a subdir
+ */
+ mapfileino(ROOTINO, tapesize, &anydirskipped);
+ } else {
+ ino_t ino;
+
+ for (ino = ROOTINO; ino < maxino; ino++) {
+ mapfileino(ino, tapesize, &anydirskipped);
}
- if (mode == IFDIR)
- anydirskipped = 1;
}
/*
* Restore gets very upset if the root is not dumped,
diff --git a/sbin/dump/unctime.c b/sbin/dump/unctime.c
index cca93eee63b..d1dc519253f 100644
--- a/sbin/dump/unctime.c
+++ b/sbin/dump/unctime.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: unctime.c,v 1.2 1996/06/23 14:30:14 deraadt Exp $ */
-/* $NetBSD: unctime.c,v 1.9 1995/03/18 14:55:11 cgd Exp $ */
+/* $OpenBSD: unctime.c,v 1.3 1997/07/05 05:36:00 millert Exp $ */
+/* $NetBSD: unctime.c,v 1.10 1997/04/15 01:09:55 lukem Exp $ */
/*-
* Copyright (c) 1980, 1993
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)unctime.c 8.2 (Berkeley) 6/14/94";
#else
-static char rcsid[] = "$OpenBSD: unctime.c,v 1.2 1996/06/23 14:30:14 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: unctime.c,v 1.3 1997/07/05 05:36:00 millert Exp $";
#endif
#endif /* not lint */