summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1997-03-11 11:59:39 +0000
committerpeter <peter@FreeBSD.org>1997-03-11 11:59:39 +0000
commit5e2372f7211e467141b4939f21d1f81da257c059 (patch)
treee8158ebc8b78a9fecf4669c3f4f70905fd33f736
parente0e06d68d52707cbac25844a417ab6919613e9eb (diff)
downloadFreeBSD-src-5e2372f7211e467141b4939f21d1f81da257c059.zip
FreeBSD-src-5e2372f7211e467141b4939f21d1f81da257c059.tar.gz
Import some CSRG 4.4BSD-Lite2 components for sbin onto vendor branch.
(note that some of these have already been imported, this is a no-op)
-rw-r--r--sbin/dump/dump.8125
-rw-r--r--sbin/dump/dump.h7
-rw-r--r--sbin/dump/dumprmt.c24
-rw-r--r--sbin/dump/main.c254
-rw-r--r--sbin/dump/tape.c8
-rw-r--r--sbin/dump/traverse.c20
-rw-r--r--sbin/dump/unctime.c57
-rw-r--r--sbin/dumpfs/dumpfs.c25
-rw-r--r--sbin/fsck/Makefile3
-rw-r--r--sbin/fsck/dir.c128
-rw-r--r--sbin/fsck/fsck.816
-rw-r--r--sbin/fsck/fsck.h119
-rw-r--r--sbin/fsck/inode.c73
-rw-r--r--sbin/fsck/main.c80
-rw-r--r--sbin/fsck/pass1.c52
-rw-r--r--sbin/fsck/pass1b.c13
-rw-r--r--sbin/fsck/pass2.c83
-rw-r--r--sbin/fsck/pass3.c5
-rw-r--r--sbin/fsck/pass4.c17
-rw-r--r--sbin/fsck/pass5.c73
-rw-r--r--sbin/fsck/preen.c90
-rw-r--r--sbin/fsck/setup.c96
-rw-r--r--sbin/fsck/utilities.c178
-rw-r--r--sbin/mount_cd9660/mount_cd9660.c23
-rw-r--r--sbin/mount_fdesc/mount_fdesc.c6
-rw-r--r--sbin/mount_kernfs/mount_kernfs.c6
-rw-r--r--sbin/mount_lfs/mount_lfs.c7
-rw-r--r--sbin/mount_nfs/mount_nfs.879
-rw-r--r--sbin/mount_nfs/mount_nfs.c318
-rw-r--r--sbin/mount_null/mount_null.828
-rw-r--r--sbin/mount_null/mount_null.c6
-rw-r--r--sbin/mount_portal/activate.c6
-rw-r--r--sbin/mount_portal/mount_portal.c12
-rw-r--r--sbin/mount_portal/pt_file.c4
-rw-r--r--sbin/mount_portal/pt_tcp.c21
-rw-r--r--sbin/mount_procfs/mount_procfs.85
-rw-r--r--sbin/mount_procfs/mount_procfs.c6
-rw-r--r--sbin/mount_umap/mount_umap.87
-rw-r--r--sbin/mount_umap/mount_umap.c14
-rw-r--r--sbin/mount_union/Makefile5
-rw-r--r--sbin/mount_union/mount_union.87
-rw-r--r--sbin/mount_union/mount_union.c6
-rw-r--r--sbin/mountd/exports.516
-rw-r--r--sbin/mountd/mountd.825
-rw-r--r--sbin/mountd/mountd.c305
-rw-r--r--sbin/newlfs/config.h8
-rw-r--r--sbin/newlfs/extern.h6
-rw-r--r--sbin/newlfs/lfs.c66
-rw-r--r--sbin/newlfs/newfs.c12
-rw-r--r--sbin/nfsd/nfsd.87
-rw-r--r--sbin/nfsd/nfsd.c108
-rw-r--r--sbin/nfsiod/nfsiod.c7
-rw-r--r--sbin/quotacheck/quotacheck.c53
-rw-r--r--sbin/restore/dirs.c58
-rw-r--r--sbin/restore/interactive.c51
-rw-r--r--sbin/restore/main.c31
-rw-r--r--sbin/restore/restore.8343
-rw-r--r--sbin/restore/restore.c46
-rw-r--r--sbin/restore/restore.h6
-rw-r--r--sbin/restore/symtab.c25
-rw-r--r--sbin/restore/tape.c96
-rw-r--r--sbin/restore/utilities.c43
-rw-r--r--sbin/umount/Makefile8
-rw-r--r--sbin/umount/umount.829
-rw-r--r--sbin/umount/umount.c196
65 files changed, 2226 insertions, 1431 deletions
diff --git a/sbin/dump/dump.8 b/sbin/dump/dump.8
index 2cd9335..1f06bcb 100644
--- a/sbin/dump/dump.8
+++ b/sbin/dump/dump.8
@@ -30,9 +30,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)dump.8 8.1 (Berkeley) 6/16/93
+.\" @(#)dump.8 8.3 (Berkeley) 5/1/95
.\"
-.Dd June 16, 1993
+.Dd May 1, 1995
.Dt DUMP 8
.Os BSD 4
.Sh NAME
@@ -40,8 +40,23 @@
.Nd filesystem backup
.Sh SYNOPSIS
.Nm dump
-.Op Cm 0123456789BbhfusTdWn Op Ar argument ...
-.Op Ar filesystem
+.Op Fl 0123456789cnu
+.Op Fl B Ar records
+.Op Fl b Ar blocksize
+.Op Fl d Ar density
+.Op Fl f Ar file
+.Op Fl h Ar level
+.Op Fl s Ar feet
+.Op Fl T Ar date
+.Ar filesystem
+.Nm dump
+.Op Fl W Li \&| Fl w
+.Pp
+.in -\\n(iSu
+(The
+.Bx 4.3
+option syntax is implemented for backward compatibility, but
+is not documented here.)
.Sh DESCRIPTION
.Nm Dump
examines files
@@ -50,7 +65,7 @@ and determines which files
need to be backed up. These files
are copied to the given disk, tape or other
storage medium for safe keeping (see the
-.Cm f
+.Fl f
option below for doing remote backups).
A dump that is larger than the output medium is broken into
multiple volumes.
@@ -65,38 +80,35 @@ By default, the same output file name is used for each volume
after prompting the operator to change media.
.Pp
The following options are supported by
-.Nm dump:
-.Bl -tag -width 4n
-.It Cm 0\-9
+.Nm dump :
+.Bl -tag -width Ds
+.It Fl 0\-9
Dump levels.
A level 0, full backup,
guarantees the entire file system is copied
(but see also the
-.Cm h
+.Fl h
option below).
A level number above 0,
incremental backup,
tells dump to
copy all files new or modified since the
-last dump of the same or lower level. The default
-level is 9.
-.It Cm B Ar records
+last dump of the same or lower level.
+The default level is 9.
+.It Fl B Ar records
The number of dump records per volume.
This option overrides the calculation of tape size
based on length and density.
-.It Cm b Ar blocksize
+.It Fl b Ar blocksize
The number of kilobytes per dump record.
-.It Cm h Ar level
-Honor the user
-.Dq nodump
-flag
-.Dp Dv UF_NODUMP
-only for dumps at or above the given
-.Ar level .
-The default honor level is 1,
-so that incremental backups omit such files
-but full backups retain them.
-.It Cm f Ar file
+.It Fl c
+Modify the calculation of the default density and tape size to be more
+appropriate for cartridge tapes.
+.It Fl d Ar density
+Set tape density to
+.Ar density .
+The default is 1600BPI.
+.It Fl f Ar file
Write the backup to
.Ar file ;
.Ar file
@@ -122,11 +134,17 @@ or
.Nm dump
writes to the named file on the remote host using
.Xr rmt 8 .
-.It Cm d Ar density
-Set tape density to
-.Ar density .
-The default is 1600BPI.
-.It Cm n
+.It Fl h Ar level
+Honor the user
+.Dq nodump
+flag
+.Dp Dv UF_NODUMP
+only for dumps at or above the given
+.Ar level .
+The default honor level is 1,
+so that incremental backups omit such files
+but full backups retain them.
+.It Fl n
Whenever
.Nm dump
requires operator attention,
@@ -134,7 +152,7 @@ notify all operators in the group
.Dq operator
by means similar to a
.Xr wall 1 .
-.It Cm s Ar feet
+.It Fl s Ar feet
Attempt to calculate the amount of tape needed
at a particular density.
If this amount is exceeded,
@@ -142,7 +160,21 @@ If this amount is exceeded,
prompts for a new tape.
It is recommended to be a bit conservative on this option.
The default tape length is 2300 feet.
-.It Cm u
+.ne 1i
+.It Fl T Ar date
+Use the specified date as the starting time for the dump
+instead of the time determined from looking in
+.Pa /etc/dumpdates .
+The format of date is the same as that of
+.Xr ctime 3 .
+This option is useful for automated dump scripts that wish to
+dump over a specific period of time.
+The
+.Fl T
+option is mutually exclusive from the
+.Fl u
+option.
+.It Fl u
Update the file
.Pa /etc/dumpdates
after a successful dump.
@@ -160,20 +192,7 @@ The file
.Pa /etc/dumpdates
may be edited to change any of the fields,
if necessary.
-.It Cm T Ar date
-Use the specified date as the starting time for the dump
-instead of the time determined from looking in
-.Pa /etc/dumpdates .
-The format of date is the same as that of
-.Xr ctime 3 .
-This option is useful for automated dump scripts that wish to
-dump over a specific period of time.
-The
-.Cm T
-option is mutually exclusive from the
-.Cm u
-option.
-.It Cm W
+.It Fl W
.Nm Dump
tells the operator what file systems need to be dumped.
This information is gleaned from the files
@@ -181,7 +200,7 @@ This information is gleaned from the files
and
.Pa /etc/fstab .
The
-.Cm W
+.Fl W
option causes
.Nm dump
to print out, for each file system in
@@ -189,11 +208,11 @@ to print out, for each file system in
the most recent dump date and level,
and highlights those file systems that should be dumped.
If the
-.Cm W
+.Fl W
option is set, all other options are ignored, and
.Nm dump
exits immediately.
-.It Cm w
+.It Fl w
Is like W, but prints only those filesystems which need to be dumped.
.El
.Pp
@@ -205,7 +224,7 @@ tape write error,
tape open error or
disk read error (if there are more than a threshold of 32).
In addition to alerting all operators implied by the
-.Cm n
+.Fl n
key,
.Nm dump
interacts with the operator on
@@ -256,7 +275,7 @@ to minimize the number of tapes follows:
.It
Always start with a level 0 backup, for example:
.Bd -literal -offset indent
-/etc/dump 0uf /dev/nrst1 /usr/src
+/sbin/dump -0u -f /dev/nrst1 /usr/src
.Ed
.Pp
This should be done at set intervals, say once a month or once every two months,
@@ -304,17 +323,17 @@ Dump 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
-.Pp
Fewer than 32 read errors on the filesystem are ignored.
+.Pp
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
with the
-.Cm W
+.Fl W
or
-.Cm w
+.Fl w
options does not report filesystems that have never been recorded
in
.Pa /etc/dumpdates ,
diff --git a/sbin/dump/dump.h b/sbin/dump/dump.h
index 9060b00..842c45f 100644
--- a/sbin/dump/dump.h
+++ b/sbin/dump/dump.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)dump.h 8.1 (Berkeley) 6/5/93
+ * @(#)dump.h 8.2 (Berkeley) 4/28/95
*/
#define MAXINOPB (MAXBSIZE / sizeof(struct dinode))
@@ -184,8 +184,9 @@ void sig __P((int signo));
*/
#ifdef COMPAT
#include <sys/file.h>
-extern char *index(), *rindex(), *strdup();
-extern char *ctime();
+#define strchr(a,b) index(a,b)
+#define strrchr(a,b) rindex(a,b)
+extern char *strdup(), *ctime();
extern int read(), write();
extern int errno;
#endif
diff --git a/sbin/dump/dumprmt.c b/sbin/dump/dumprmt.c
index 22acbfd..9c5273e 100644
--- a/sbin/dump/dumprmt.c
+++ b/sbin/dump/dumprmt.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)dumprmt.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)dumprmt.c 8.3 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
@@ -54,6 +54,7 @@ static char sccsid[] = "@(#)dumprmt.c 8.1 (Berkeley) 6/5/93";
#include <protocols/dumprestore.h>
#include <ctype.h>
+#include <err.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
@@ -105,8 +106,7 @@ static void
rmtconnaborted()
{
- (void) fprintf(stderr, "rdump: Lost connection to remote host.\n");
- exit(1);
+ errx(1, "Lost connection to remote host.");
}
void
@@ -124,18 +124,13 @@ rmtgetconn()
if (sp == NULL) {
sp = getservbyname("shell", "tcp");
- if (sp == NULL) {
- (void) fprintf(stderr,
- "rdump: shell/tcp: unknown service\n");
- exit(1);
- }
+ if (sp == NULL)
+ errx(1, "shell/tcp: unknown service");
pwd = getpwuid(getuid());
- if (pwd == NULL) {
- (void) fprintf(stderr, "rdump: who are you?\n");
- exit(1);
- }
+ if (pwd == NULL)
+ errx(1, "who are you?");
}
- if ((cp = index(rmtpeer, '@')) != NULL) {
+ if ((cp = strchr(rmtpeer, '@')) != NULL) {
tuser = rmtpeer;
*cp = '\0';
if (!okname(tuser))
@@ -175,8 +170,7 @@ okname(cp0)
for (cp = cp0; *cp; cp++) {
c = *cp;
if (!isascii(c) || !(isalnum(c) || c == '_' || c == '-')) {
- (void) fprintf(stderr, "rdump: invalid user name %s\n",
- cp0);
+ warnx("invalid user name: %s", cp0);
return (0);
}
}
diff --git a/sbin/dump/main.c b/sbin/dump/main.c
index 40d668e..7b3e139 100644
--- a/sbin/dump/main.c
+++ b/sbin/dump/main.c
@@ -38,7 +38,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 4/15/94";
+static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/1/95";
#endif /* not lint */
#include <sys/param.h>
@@ -49,23 +49,22 @@ static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 4/15/94";
#include <ufs/inode.h>
#include <ufs/fs.h>
#else
-#include <ufs/ffs/fs.h>
#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
#endif
#include <protocols/dumprestore.h>
#include <ctype.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fstab.h>
#include <signal.h>
#include <stdio.h>
-#ifdef __STDC__
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#endif
#include "dump.h"
#include "pathnames.h"
@@ -84,20 +83,21 @@ long dev_bsize = 1; /* recalculated below */
long blocksperfile; /* output blocks per file */
char *host = NULL; /* remote host (if any) */
-static long numarg __P((int, char *, long, long, int *, char ***));
-static __dead void missingarg __P((int, char *));
+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;
+ char *argv[];
{
register ino_t ino;
register int dirty;
register struct dinode *dp;
register struct fstab *dt;
register char *map;
- register char *cp;
+ register int ch;
int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
ino_t maxino;
@@ -111,97 +111,79 @@ main(argc, argv)
if (TP_BSIZE / DEV_BSIZE == 0 || TP_BSIZE % DEV_BSIZE != 0)
quit("TP_BSIZE must be a multiple of DEV_BSIZE\n");
level = '0';
- if (argc == 1) {
- (void) fprintf(stderr, "Must specify a key.\n");
- Exit(X_ABORT);
- }
- argv++;
- argc -= 2;
- for (cp = *argv++; cp != NULL && *cp != '\0'; cp++) {
- switch (*cp) {
- case '-':
+
+ if (argc < 2)
+ usage();
+
+ obsolete(&argc, &argv);
+ while ((ch = getopt(argc, argv, "0123456789B:b:cd:f:h:ns:T:uWw")) != -1)
+ switch (ch) {
+ /* dump level */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ level = ch;
break;
- case 'w':
- lastdump('w'); /* tell us only what has to be done */
- exit(0);
+ case 'B': /* blocks per output file */
+ blocksperfile = numarg("blocks per file", 1L, 0L);
+ break;
- case 'W': /* what to do */
- lastdump('W'); /* tell us state of what is done */
- exit(0); /* do nothing else */
+ case 'b': /* blocks per tape write */
+ ntrec = numarg("blocks per write", 1L, 1000L);
+ break;
- case 'f': /* output file */
- if (argc < 1)
- missingarg('f', "output file");
- tape = *argv++;
- argc--;
+ case 'c': /* Tape is cart. not 9-track */
+ cartridge = 1;
break;
case 'd': /* density, in bits per inch */
- density = numarg('d', "density",
- 10L, 327670L, &argc, &argv) / 10;
+ density = numarg("density", 10L, 327670L) / 10;
if (density >= 625 && !bflag)
ntrec = HIGHDENSITYTREC;
break;
+ case 'f': /* output file */
+ tape = optarg;
+ break;
+
+ case 'h':
+ honorlevel = numarg("honor level", 0L, 10L);
+ break;
+
+ case 'n': /* notify operators */
+ notify = 1;
+ break;
+
case 's': /* tape size, feet */
- tsize = numarg('s', "size",
- 1L, 0L, &argc, &argv) * 12 * 10;
+ tsize = numarg("tape size", 1L, 0L) * 12 * 10;
break;
case 'T': /* time of last dump */
- if (argc < 1)
- missingarg('T', "time of last dump");
- spcl.c_ddate = unctime(*argv);
+ spcl.c_ddate = unctime(optarg);
if (spcl.c_ddate < 0) {
(void)fprintf(stderr, "bad time \"%s\"\n",
- *argv);
+ optarg);
exit(X_ABORT);
}
Tflag = 1;
lastlevel = '?';
- argc--;
- argv++;
- break;
-
- case 'b': /* blocks per tape write */
- ntrec = numarg('b', "number of blocks per write",
- 1L, 1000L, &argc, &argv);
- break;
-
- case 'B': /* blocks per output file */
- blocksperfile = numarg('B', "number of blocks per file",
- 1L, 0L, &argc, &argv);
- break;
-
- case 'c': /* Tape is cart. not 9-track */
- cartridge = 1;
- break;
-
- /* dump level */
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- level = *cp;
break;
case 'u': /* update /etc/dumpdates */
uflag = 1;
break;
- case 'n': /* notify operators */
- notify = 1;
- break;
-
- case 'h':
- honorlevel = numarg('h', "honor level",
- 0L, 10L, &argc, &argv);
- break;
+ case 'W': /* what to do */
+ case 'w':
+ lastdump(ch);
+ exit(0); /* do nothing else */
default:
- (void)fprintf(stderr, "bad key '%c'\n", *cp);
- exit(X_ABORT);
+ usage();
}
- }
+ argc -= optind;
+ argv += optind;
+
if (argc < 1) {
(void)fprintf(stderr, "Must specify disk or filesystem\n");
exit(X_ABORT);
@@ -243,9 +225,9 @@ main(argc, argv)
tsize = cartridge ? 1700L*120L : 2300L*120L;
}
- if (index(tape, ':')) {
+ if (strchr(tape, ':')) {
host = tape;
- tape = index(host, ':');
+ tape = strchr(host, ':');
*tape++ = '\0';
#ifdef RDUMP
if (rmthost(host) == 0)
@@ -456,48 +438,33 @@ main(argc, argv)
/* NOTREACHED */
}
+static void
+usage()
+{
+
+ (void)fprintf(stderr, "usage: dump [-0123456789cnu] [-B records] [-b blocksize] [-d density] [-f file]\n [-h level] [-s feet] [-T date] filesystem\n");
+ (void)fprintf(stderr, " dump [-W | -w]\n");
+ exit(1);
+}
+
/*
* Pick up a numeric argument. It must be nonnegative and in the given
* range (except that a vmax of 0 means unlimited).
*/
static long
-numarg(letter, meaning, vmin, vmax, pargc, pargv)
- int letter;
+numarg(meaning, vmin, vmax)
char *meaning;
long vmin, vmax;
- int *pargc;
- char ***pargv;
{
- register char *p;
+ char *p;
long val;
- char *str;
-
- if (--*pargc < 0)
- missingarg(letter, meaning);
- str = *(*pargv)++;
- for (p = str; *p; p++)
- if (!isdigit(*p))
- goto bad;
- val = atol(str);
+
+ val = strtol(optarg, &p, 10);
+ if (*p)
+ errx(1, "illegal %s -- %s", meaning, optarg);
if (val < vmin || (vmax && val > vmax))
- goto bad;
+ errx(1, "%s must be between %ld and %ld", meaning, vmin, vmax);
return (val);
-
-bad:
- (void)fprintf(stderr, "bad '%c' (%s) value \"%s\"\n",
- letter, meaning, str);
- exit(X_ABORT);
-}
-
-static __dead void
-missingarg(letter, meaning)
- int letter;
- char *meaning;
-{
-
- (void)fprintf(stderr, "The '%c' flag (%s) requires an argument\n",
- letter, meaning);
- exit(X_ABORT);
}
void
@@ -532,7 +499,7 @@ rawname(cp)
char *cp;
{
static char rawbuf[MAXPATHLEN];
- char *dp = rindex(cp, '/');
+ char *dp = strrchr(cp, '/');
if (dp == NULL)
return (NULL);
@@ -544,17 +511,76 @@ rawname(cp)
return (rawbuf);
}
-#ifdef sunos
-const char *
-strerror(errnum)
- int errnum;
+/*
+ * obsolete --
+ * Change set of key letters and ordered arguments into something
+ * getopt(3) will like.
+ */
+static void
+obsolete(argcp, argvp)
+ int *argcp;
+ char **argvp[];
{
- extern int sys_nerr;
- extern const char *const sys_errlist[];
+ int argc, flags;
+ char *ap, **argv, *flagsp, **nargv, *p;
+
+ /* Setup. */
+ argv = *argvp;
+ argc = *argcp;
+
+ /* Return if no arguments or first argument has leading dash. */
+ ap = argv[1];
+ if (argc == 1 || *ap == '-')
+ return;
+
+ /* 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;
+
+ for (flags = 0; *ap; ++ap) {
+ switch (*ap) {
+ case 'B':
+ case 'b':
+ case 'd':
+ case 'f':
+ case 'h':
+ case 's':
+ case 'T':
+ if (*argv == NULL) {
+ warnx("option requires an argument -- %c", *ap);
+ 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);
+ ++argv;
+ ++nargv;
+ break;
+ default:
+ if (!flags) {
+ *p++ = '-';
+ flags = 1;
+ }
+ *p++ = *ap;
+ break;
+ }
+ }
- if (errnum < sys_nerr)
- return (sys_errlist[errnum]);
- else
- return ("bogus errno in strerror");
+ /* Terminate flags. */
+ if (flags) {
+ *p = '\0';
+ *nargv++ = flagsp;
+ }
+
+ /* Copy remaining arguments. */
+ while (*nargv++ = *argv++);
+
+ /* Update argument count. */
+ *argcp = nargv - *argvp - 1;
}
-#endif
diff --git a/sbin/dump/tape.c b/sbin/dump/tape.c
index f6a4e5b..db5c24a 100644
--- a/sbin/dump/tape.c
+++ b/sbin/dump/tape.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)tape.c 8.2 (Berkeley) 3/17/94";
+static char sccsid[] = "@(#)tape.c 8.4 (Berkeley) 5/1/95";
#endif /* not lint */
#include <sys/param.h>
@@ -45,8 +45,8 @@ static char sccsid[] = "@(#)tape.c 8.2 (Berkeley) 3/17/94";
#include <ufs/fs.h>
#include <ufs/inode.h>
#else
-#include <ufs/ffs/fs.h>
#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
#endif
#include <protocols/dumprestore.h>
@@ -584,10 +584,10 @@ restore_check_point:
* the remaining names for subsequent volumes.
*/
tapeno++; /* current tape sequence */
- if (nexttape || index(tape, ',')) {
+ if (nexttape || strchr(tape, ',')) {
if (nexttape && *nexttape)
tape = nexttape;
- if ((p = index(tape, ',')) != NULL) {
+ if ((p = strchr(tape, ',')) != NULL) {
*p = '\0';
nexttape = p + 1;
} else
diff --git a/sbin/dump/traverse.c b/sbin/dump/traverse.c
index ce70050..8eaabf3 100644
--- a/sbin/dump/traverse.c
+++ b/sbin/dump/traverse.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)traverse.c 8.2 (Berkeley) 9/23/93";
+static char sccsid[] = "@(#)traverse.c 8.7 (Berkeley) 6/15/95";
#endif /* not lint */
#include <sys/param.h>
@@ -45,9 +45,9 @@ static char sccsid[] = "@(#)traverse.c 8.2 (Berkeley) 9/23/93";
#include <ufs/fsdir.h>
#include <ufs/inode.h>
#else
-#include <ufs/ffs/fs.h>
#include <ufs/ufs/dir.h>
#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
#endif
#include <protocols/dumprestore.h>
@@ -115,13 +115,8 @@ blockest(dp)
}
/* Auxiliary macro to pick up files changed since previous dump. */
-#ifdef FS_44INODEFMT
-#define CHANGEDSINCE(dp, t) \
- ((dp)->di_mtime.ts_sec >= (t) || (dp)->di_ctime.ts_sec >= (t))
-#else
#define CHANGEDSINCE(dp, t) \
((dp)->di_mtime >= (t) || (dp)->di_ctime >= (t))
-#endif
/* The WANTTODUMP macro decides whether a file should be dumped. */
#ifdef UF_NODUMP
@@ -367,8 +362,7 @@ dumpino(dp, ino)
spcl.c_addr[0] = 1;
spcl.c_count = 1;
writeheader(ino);
- bcopy((caddr_t)dp->di_shortlink, buf,
- (u_long)dp->di_size);
+ memmove(buf, dp->di_shortlink, (u_long)dp->di_size);
buf[dp->di_size] = '\0';
writerec(buf, 0);
return;
@@ -423,7 +417,7 @@ dmpindir(ino, blk, ind_level, size)
if (blk != 0)
bread(fsbtodb(sblock, blk), (char *)idblk, (int) sblock->fs_bsize);
else
- bzero((char *)idblk, (int)sblock->fs_bsize);
+ memset(idblk, 0, (int)sblock->fs_bsize);
if (ind_level <= 0) {
if (*size < NINDIR(sblock) * sblock->fs_bsize)
cnt = howmany(*size, sblock->fs_fsize);
@@ -558,7 +552,7 @@ bread(blkno, buf, size)
extern int errno;
loop:
- if ((int)lseek(diskfd, ((off_t)blkno << dev_bshift), 0) < 0)
+ if ((int)lseek(diskfd, ((off_t)blkno << dev_bshift), 0) == -1)
msg("bread: lseek fails\n");
if ((cnt = read(diskfd, buf, size)) == size)
return;
@@ -596,9 +590,9 @@ loop:
/*
* Zero buffer, then try to read each sector of buffer separately.
*/
- bzero(buf, size);
+ memset(buf, 0, size);
for (i = 0; i < size; i += dev_bsize, buf += dev_bsize, blkno++) {
- if ((int)lseek(diskfd, ((off_t)blkno << dev_bshift), 0) < 0)
+ if ((int)lseek(diskfd, ((off_t)blkno << dev_bshift), 0) == -1)
msg("bread: lseek2 fails!\n");
if ((cnt = read(diskfd, buf, (int)dev_bsize)) == dev_bsize)
continue;
diff --git a/sbin/dump/unctime.c b/sbin/dump/unctime.c
index 7b3fd4e..bacb469 100644
--- a/sbin/dump/unctime.c
+++ b/sbin/dump/unctime.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)unctime.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)unctime.c 8.2 (Berkeley) 6/14/94";
#endif /* not lint */
#include <sys/types.h>
@@ -66,8 +66,6 @@ static char sccsid[] = "@(#)unctime.c 8.1 (Berkeley) 6/5/93";
#define E_SECOND 17
#define E_YEAR 20
-static int dcmp __P((struct tm *, struct tm *));
-static time_t emitl __P((struct tm *));
static int lookup __P((char *));
@@ -88,7 +86,8 @@ unctime(str)
then.tm_min = atoi(&dbuf[E_MINUTE]);
then.tm_sec = atoi(&dbuf[E_SECOND]);
then.tm_year = atoi(&dbuf[E_YEAR]) - 1900;
- return(emitl(&then));
+ then.tm_isdst = -1;
+ return(mktime(&then));
}
static char months[] =
@@ -105,53 +104,3 @@ lookup(str)
return((cp-months) / 3);
return(-1);
}
-/*
- * Routine to convert a localtime(3) format date back into
- * a system format date.
- *
- * Use a binary search.
- */
-
-static time_t
-emitl(dp)
- struct tm *dp;
-{
- time_t conv;
- register int i, bit;
- struct tm dcopy;
-
- dcopy = *dp;
- dp = &dcopy;
- conv = 0;
- for (i = 30; i >= 0; i--) {
- bit = 1 << i;
- conv |= bit;
- if (dcmp(localtime(&conv), dp) > 0)
- conv &= ~bit;
- }
- return(conv);
-}
-
-/*
- * Compare two localtime dates, return result.
- */
-
-#define DECIDE(a) \
- if (dp->a > dp2->a) \
- return(1); \
- if (dp->a < dp2->a) \
- return(-1)
-
-static int
-dcmp(dp, dp2)
- register struct tm *dp, *dp2;
-{
-
- DECIDE(tm_year);
- DECIDE(tm_mon);
- DECIDE(tm_mday);
- DECIDE(tm_hour);
- DECIDE(tm_min);
- DECIDE(tm_sec);
- return(0);
-}
diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c
index d453fab..ed68f5c 100644
--- a/sbin/dumpfs/dumpfs.c
+++ b/sbin/dumpfs/dumpfs.c
@@ -38,7 +38,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)dumpfs.c 8.2 (Berkeley) 2/2/94";
+static char sccsid[] = "@(#)dumpfs.c 8.5 (Berkeley) 4/29/95";
#endif /* not lint */
#include <sys/param.h>
@@ -47,13 +47,14 @@ static char sccsid[] = "@(#)dumpfs.c 8.2 (Berkeley) 2/2/94";
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
-#include <unistd.h>
-#include <fcntl.h>
+#include <err.h>
#include <errno.h>
+#include <fcntl.h>
#include <fstab.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
union {
struct fs fs;
@@ -82,7 +83,7 @@ main(argc, argv)
register struct fstab *fs;
int ch, eval;
- while ((ch = getopt(argc, argv, "")) != EOF)
+ while ((ch = getopt(argc, argv, "")) != -1)
switch(ch) {
case '?':
default:
@@ -115,6 +116,12 @@ dumpfs(name)
if (read(fd, &afs, SBSIZE) != SBSIZE)
goto err;
+ if (afs.fs_magic != FS_MAGIC) {
+ warnx("%s: superblock has bad magic number, skipped", name);
+ (void)close(fd);
+ return (1);
+ }
+
if (afs.fs_postblformat == FS_42POSTBLFMT)
afs.fs_nrpos = 8;
dev_bsize = afs.fs_fsize / fsbtodb(&afs, 1);
@@ -154,13 +161,13 @@ dumpfs(name)
afs.fs_sbsize, afs.fs_cgsize, afs.fs_cgoffset, afs.fs_cgmask);
printf("csaddr\t%d\tcssize\t%d\tshift\t%d\tmask\t0x%08x\n",
afs.fs_csaddr, afs.fs_cssize, afs.fs_csshift, afs.fs_csmask);
- printf("cgrotor\t%d\tfmod\t%d\tronly\t%d\n",
- afs.fs_cgrotor, afs.fs_fmod, afs.fs_ronly);
+ printf("cgrotor\t%d\tfmod\t%d\tronly\t%d\tclean\t%d\n",
+ afs.fs_cgrotor, afs.fs_fmod, afs.fs_ronly, afs.fs_clean);
if (afs.fs_cpc != 0)
printf("blocks available in each of %d rotational positions",
afs.fs_nrpos);
else
- printf("insufficient space to maintain rotational tables\n");
+ printf("(no rotational position table)\n");
for (c = 0; c < afs.fs_cpc; c++) {
printf("\ncylinder number %d:", c);
for (i = 0; i < afs.fs_nrpos; i++) {
@@ -212,7 +219,7 @@ dumpfs(name)
err: if (fd != -1)
(void)close(fd);
- (void)fprintf(stderr, "dumpfs: %s: %s\n", name, strerror(errno));
+ warn("%s", name);
return (1);
};
@@ -229,7 +236,7 @@ dumpcg(name, fd, c)
SEEK_SET)) == (off_t)-1)
return (1);
if (read(fd, &acg, afs.fs_bsize) != afs.fs_bsize) {
- (void)fprintf(stderr, "dumpfs: %s: error reading cg\n", name);
+ warnx("%s: error reading cg", name);
return (1);
}
printf("magic\t%x\ttell\t%qx\ttime\t%s",
diff --git a/sbin/fsck/Makefile b/sbin/fsck/Makefile
index 224f6b2..7186560 100644
--- a/sbin/fsck/Makefile
+++ b/sbin/fsck/Makefile
@@ -1,9 +1,10 @@
-# @(#)Makefile 8.1 (Berkeley) 6/5/93
+# @(#)Makefile 8.2 (Berkeley) 4/27/95
PROG= fsck
MAN8= fsck.0
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
+CFLAGS+=-W
.PATH: ${.CURDIR}/../../sys/ufs/ffs
.include <bsd.prog.mk>
diff --git a/sbin/fsck/dir.c b/sbin/fsck/dir.c
index ee5d095..f9b8b63 100644
--- a/sbin/fsck/dir.c
+++ b/sbin/fsck/dir.c
@@ -32,16 +32,19 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)dir.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
-#include <stdlib.h>
+
+#include <err.h>
#include <string.h>
+
#include "fsck.h"
char *lfname = "lost+found";
@@ -56,12 +59,19 @@ struct odirtemplate odirhead = {
0, DIRBLKSIZ - 12, 2, ".."
};
-struct direct *fsck_readdir();
-struct bufarea *getdirblk();
+static int chgino __P((struct inodesc *));
+static int dircheck __P((struct inodesc *, struct direct *));
+static int expanddir __P((struct dinode *dp, char *name));
+static void freedir __P((ino_t ino, ino_t parent));
+static struct direct *fsck_readdir __P((struct inodesc *));
+static struct bufarea *getdirblk __P((ufs_daddr_t blkno, long size));
+static int lftempname __P((char *bufp, ino_t ino));
+static int mkentry __P((struct inodesc *));
/*
* Propagate connected state through the tree.
*/
+void
propagate()
{
register struct inoinfo **inpp, *inp;
@@ -87,6 +97,7 @@ propagate()
/*
* Scan each entry in a directory block.
*/
+int
dirscan(idesc)
register struct inodesc *idesc;
{
@@ -97,7 +108,7 @@ dirscan(idesc)
char dbuf[DIRBLKSIZ];
if (idesc->id_type != DATA)
- errexit("wrong type to dirscan %d\n", idesc->id_type);
+ errx(EEXIT, "wrong type to dirscan %d", idesc->id_type);
if (idesc->id_entryno == 0 &&
(idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
@@ -109,7 +120,7 @@ dirscan(idesc)
idesc->id_loc = 0;
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
dsize = dp->d_reclen;
- bcopy((char *)dp, dbuf, (size_t)dsize);
+ memmove(dbuf, dp, (size_t)dsize);
# if (BYTE_ORDER == LITTLE_ENDIAN)
if (!newinofmt) {
struct direct *tdp = (struct direct *)dbuf;
@@ -134,7 +145,7 @@ dirscan(idesc)
}
# endif
bp = getdirblk(idesc->id_blkno, blksiz);
- bcopy(dbuf, bp->b_un.b_buf + idesc->id_loc - dsize,
+ memmove(bp->b_un.b_buf + idesc->id_loc - dsize, dbuf,
(size_t)dsize);
dirty(bp);
sbdirty();
@@ -148,7 +159,7 @@ dirscan(idesc)
/*
* get next entry in a directory.
*/
-struct direct *
+static struct direct *
fsck_readdir(idesc)
register struct inodesc *idesc;
{
@@ -163,6 +174,8 @@ fsck_readdir(idesc)
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
if (dircheck(idesc, dp))
goto dpok;
+ if (idesc->id_fix == IGNORE)
+ return (0);
fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
@@ -192,6 +205,8 @@ dpok:
size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
idesc->id_loc += size;
idesc->id_filesize -= size;
+ if (idesc->id_fix == IGNORE)
+ return (0);
fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct direct *)(bp->b_un.b_buf + dploc);
@@ -206,6 +221,7 @@ dpok:
* Verify that a directory entry is valid.
* This is a superset of the checks made in the kernel.
*/
+static int
dircheck(idesc, dp)
struct inodesc *idesc;
register struct direct *dp;
@@ -215,8 +231,15 @@ dircheck(idesc, dp)
u_char namlen, type;
int spaceleft;
- size = DIRSIZ(!newinofmt, dp);
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
+ if (dp->d_ino >= maxino ||
+ dp->d_reclen == 0 ||
+ dp->d_reclen > spaceleft ||
+ (dp->d_reclen & 0x3) != 0)
+ return (0);
+ if (dp->d_ino == 0)
+ return (1);
+ size = DIRSIZ(!newinofmt, dp);
# if (BYTE_ORDER == LITTLE_ENDIAN)
if (!newinofmt) {
type = dp->d_namlen;
@@ -229,25 +252,20 @@ dircheck(idesc, dp)
namlen = dp->d_namlen;
type = dp->d_type;
# endif
- if (dp->d_ino < maxino &&
- dp->d_reclen != 0 &&
- dp->d_reclen <= spaceleft &&
- (dp->d_reclen & 0x3) == 0 &&
- dp->d_reclen >= size &&
- idesc->id_filesize >= size &&
- namlen <= MAXNAMLEN &&
- type <= 15) {
- if (dp->d_ino == 0)
- return (1);
- for (cp = dp->d_name, size = 0; size < namlen; size++)
- if (*cp == 0 || (*cp++ == '/'))
- return (0);
- if (*cp == 0)
- return (1);
- }
- return (0);
+ if (dp->d_reclen < size ||
+ idesc->id_filesize < size ||
+ namlen > MAXNAMLEN ||
+ type > 15)
+ return (0);
+ for (cp = dp->d_name, size = 0; size < namlen; size++)
+ if (*cp == '\0' || (*cp++ == '/'))
+ return (0);
+ if (*cp != '\0')
+ return (0);
+ return (1);
}
+void
direrror(ino, errmesg)
ino_t ino;
char *errmesg;
@@ -256,6 +274,7 @@ direrror(ino, errmesg)
fileerror(ino, ino, errmesg);
}
+void
fileerror(cwd, ino, errmesg)
ino_t cwd, ino;
char *errmesg;
@@ -279,9 +298,10 @@ fileerror(cwd, ino, errmesg)
pfatal("NAME=%s\n", pathbuf);
}
+void
adjust(idesc, lcnt)
register struct inodesc *idesc;
- short lcnt;
+ int lcnt;
{
register struct dinode *dp;
@@ -309,6 +329,7 @@ adjust(idesc, lcnt)
}
}
+static int
mkentry(idesc)
struct inodesc *idesc;
{
@@ -328,22 +349,38 @@ mkentry(idesc)
dirp->d_reclen = oldlen;
dirp = (struct direct *)(((char *)dirp) + oldlen);
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
+ dirp->d_reclen = newent.d_reclen;
if (newinofmt)
dirp->d_type = typemap[idesc->id_parent];
else
dirp->d_type = 0;
- dirp->d_reclen = newent.d_reclen;
dirp->d_namlen = newent.d_namlen;
- bcopy(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
+ memmove(dirp->d_name, idesc->id_name, (size_t)newent.d_namlen + 1);
+# if (BYTE_ORDER == LITTLE_ENDIAN)
+ /*
+ * If the entry was split, dirscan() will only reverse the byte
+ * order of the original entry, and not the new one, before
+ * writing it back out. So, we reverse the byte order here if
+ * necessary.
+ */
+ if (oldlen != 0 && !newinofmt && !doinglevel2) {
+ u_char tmp;
+
+ tmp = dirp->d_namlen;
+ dirp->d_namlen = dirp->d_type;
+ dirp->d_type = tmp;
+ }
+# endif
return (ALTERED|STOP);
}
+static int
chgino(idesc)
struct inodesc *idesc;
{
register struct direct *dirp = idesc->id_dirp;
- if (bcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1))
+ if (memcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1))
return (KEEPON);
dirp->d_ino = idesc->id_parent;
if (newinofmt)
@@ -353,6 +390,7 @@ chgino(idesc)
return (ALTERED|STOP);
}
+int
linkup(orphan, parentdir)
ino_t orphan;
ino_t parentdir;
@@ -364,7 +402,7 @@ linkup(orphan, parentdir)
char tempname[BUFSIZ];
extern int pass4check();
- bzero((char *)&idesc, sizeof(struct inodesc));
+ memset(&idesc, 0, sizeof(struct inodesc));
dp = ginode(orphan);
lostdir = (dp->di_mode & IFMT) == IFDIR;
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
@@ -460,6 +498,7 @@ linkup(orphan, parentdir)
/*
* fix an entry in a directory.
*/
+int
changeino(dir, name, newnum)
ino_t dir;
char *name;
@@ -467,7 +506,7 @@ changeino(dir, name, newnum)
{
struct inodesc idesc;
- bzero((char *)&idesc, sizeof(struct inodesc));
+ memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA;
idesc.id_func = chgino;
idesc.id_number = dir;
@@ -480,6 +519,7 @@ changeino(dir, name, newnum)
/*
* make an entry in a directory
*/
+int
makeentry(parent, ino, name)
ino_t parent, ino;
char *name;
@@ -491,7 +531,7 @@ makeentry(parent, ino, name)
if (parent < ROOTINO || parent >= maxino ||
ino < ROOTINO || ino >= maxino)
return (0);
- bzero((char *)&idesc, sizeof(struct inodesc));
+ memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA;
idesc.id_func = mkentry;
idesc.id_number = parent;
@@ -515,11 +555,12 @@ makeentry(parent, ino, name)
/*
* Attempt to expand the size of a directory
*/
+static int
expanddir(dp, name)
register struct dinode *dp;
char *name;
{
- daddr_t lastbn, newblk;
+ ufs_daddr_t lastbn, newblk;
register struct bufarea *bp;
char *cp, firstblk[DIRBLKSIZ];
@@ -536,21 +577,21 @@ expanddir(dp, name)
(long)dblksize(&sblock, dp, lastbn + 1));
if (bp->b_errs)
goto bad;
- bcopy(bp->b_un.b_buf, firstblk, DIRBLKSIZ);
+ memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
bp = getdirblk(newblk, sblock.fs_bsize);
if (bp->b_errs)
goto bad;
- bcopy(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
+ memmove(bp->b_un.b_buf, firstblk, DIRBLKSIZ);
for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
cp < &bp->b_un.b_buf[sblock.fs_bsize];
cp += DIRBLKSIZ)
- bcopy((char *)&emptydir, cp, sizeof emptydir);
+ memmove(cp, &emptydir, sizeof emptydir);
dirty(bp);
bp = getdirblk(dp->di_db[lastbn + 1],
(long)dblksize(&sblock, dp, lastbn + 1));
if (bp->b_errs)
goto bad;
- bcopy((char *)&emptydir, bp->b_un.b_buf, sizeof emptydir);
+ memmove(bp->b_un.b_buf, &emptydir, sizeof emptydir);
pwarn("NO SPACE LEFT IN %s", name);
if (preen)
printf(" (EXPANDED)\n");
@@ -571,6 +612,7 @@ bad:
/*
* allocate a new directory
*/
+ino_t
allocdir(parent, request, mode)
ino_t parent, request;
int mode;
@@ -594,11 +636,11 @@ allocdir(parent, request, mode)
freeino(ino);
return (0);
}
- bcopy((char *)dirp, bp->b_un.b_buf, sizeof(struct dirtemplate));
+ memmove(bp->b_un.b_buf, dirp, sizeof(struct dirtemplate));
for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
cp < &bp->b_un.b_buf[sblock.fs_fsize];
cp += DIRBLKSIZ)
- bcopy((char *)&emptydir, cp, sizeof emptydir);
+ memmove(cp, &emptydir, sizeof emptydir);
dirty(bp);
dp->di_nlink = 2;
inodirty();
@@ -626,6 +668,7 @@ allocdir(parent, request, mode)
/*
* free a directory inode
*/
+static void
freedir(ino, parent)
ino_t ino, parent;
{
@@ -642,6 +685,7 @@ freedir(ino, parent)
/*
* generate a temporary name for the lost+found directory.
*/
+static int
lftempname(bufp, ino)
char *bufp;
ino_t ino;
@@ -668,9 +712,9 @@ lftempname(bufp, ino)
* Get a directory block.
* Insure that it is held until another is requested.
*/
-struct bufarea *
+static struct bufarea *
getdirblk(blkno, size)
- daddr_t blkno;
+ ufs_daddr_t blkno;
long size;
{
diff --git a/sbin/fsck/fsck.8 b/sbin/fsck/fsck.8
index cf8c499..fd3ff07 100644
--- a/sbin/fsck/fsck.8
+++ b/sbin/fsck/fsck.8
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93
+.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
.\"
-.Dd December 11, 1993
+.Dd May 9, 1995
.Dt FSCK 8
.Os BSD 4
.Sh NAME
@@ -71,6 +71,12 @@ running one process per disk drive.
The disk drive containing each filesystem is inferred from the longest prefix
of the device name that ends in a digit; the remaining characters are assumed
to be the partition designator.
+In preening mode,
+filesystems that are marked clean are skipped.
+Filesystems are marked clean when they are unmounted,
+when they have been mounted read-only, or when
+.Nm fsck
+runs on them successfully.
.Pp
The kernel takes care that only a restricted class of innocuous filesystem
inconsistencies can happen unless hardware or software failures intervene.
@@ -181,7 +187,7 @@ do not open the filesystem for writing.
Convert the filesystem to the specified level.
Note that the level of a filesystem can only be raised.
.Bl -tag -width indent
-There are currently three levels defined:
+There are currently four levels defined:
.It 0
The filesystem is in the old (static table) format.
.It 1
@@ -190,6 +196,10 @@ The filesystem is in the new (dynamic table) format.
The filesystem supports 32-bit uid's and gid's,
short symbolic links are stored in the inode,
and directories have an added field showing the file type.
+.It 3
+If maxcontig is greater than one,
+build the free segment maps to aid in finding contiguous sets of blocks.
+If maxcontig is equal to one, delete any existing segment maps.
.El
.Pp
In interactive mode,
diff --git a/sbin/fsck/fsck.h b/sbin/fsck/fsck.h
index 7fa831f..21b3658 100644
--- a/sbin/fsck/fsck.h
+++ b/sbin/fsck/fsck.h
@@ -30,9 +30,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)fsck.h 8.1 (Berkeley) 6/5/93
+ * @(#)fsck.h 8.4 (Berkeley) 5/9/95
*/
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
#define MAXDUP 10 /* limit on dup blks (per inode) */
#define MAXBAD 10 /* limit on bad blks (per inode) */
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
@@ -53,20 +57,20 @@
* buffer cache structure.
*/
struct bufarea {
- struct bufarea *b_next; /* free list queue */
- struct bufarea *b_prev; /* free list queue */
- daddr_t b_bno;
- int b_size;
- int b_errs;
- int b_flags;
+ struct bufarea *b_next; /* free list queue */
+ struct bufarea *b_prev; /* free list queue */
+ ufs_daddr_t b_bno;
+ int b_size;
+ int b_errs;
+ int b_flags;
union {
- char *b_buf; /* buffer space */
- daddr_t *b_indir; /* indirect block */
- struct fs *b_fs; /* super block */
- struct cg *b_cg; /* cylinder group */
- struct dinode *b_dinode; /* inode block */
+ char *b_buf; /* buffer space */
+ ufs_daddr_t *b_indir; /* indirect block */
+ struct fs *b_fs; /* super block */
+ struct cg *b_cg; /* cylinder group */
+ struct dinode *b_dinode; /* inode block */
} b_un;
- char b_dirty;
+ char b_dirty;
};
#define B_INUSE 1
@@ -77,12 +81,11 @@ struct bufarea sblk; /* file system superblock */
struct bufarea cgblk; /* cylinder group blocks */
struct bufarea *pdirbp; /* current directory contents */
struct bufarea *pbp; /* current inode block */
-struct bufarea *getdatablk();
#define dirty(bp) (bp)->b_dirty = 1
#define initbarea(bp) \
(bp)->b_dirty = 0; \
- (bp)->b_bno = (daddr_t)-1; \
+ (bp)->b_bno = (ufs_daddr_t)-1; \
(bp)->b_flags = 0;
#define sbdirty() sblk.b_dirty = 1
@@ -97,7 +100,7 @@ struct inodesc {
int (*id_func)(); /* function to be applied to blocks of inode */
ino_t id_number; /* inode number described */
ino_t id_parent; /* for DATA nodes, their parent */
- daddr_t id_blkno; /* current block number being examined */
+ ufs_daddr_t id_blkno; /* current block number being examined */
int id_numfrags; /* number of frags contained in block */
quad_t id_filesize; /* for DATA nodes, the size of the directory */
int id_loc; /* for DATA nodes, current location in dir */
@@ -133,7 +136,7 @@ struct inodesc {
*/
struct dups {
struct dups *next;
- daddr_t dup;
+ ufs_daddr_t dup;
};
struct dups *duplist; /* head of dup list */
struct dups *muldup; /* end of unique duplicate dup block numbers */
@@ -157,7 +160,7 @@ struct inoinfo {
ino_t i_dotdot; /* inode number of `..' */
size_t i_isize; /* size of inode */
u_int i_numblks; /* size of block array in bytes */
- daddr_t i_blks[1]; /* actually longer */
+ ufs_daddr_t i_blks[1]; /* actually longer */
} **inphead, **inpsort;
long numdirs, listmax, inplast;
@@ -179,20 +182,20 @@ int fsmodified; /* 1 => write done to file system */
int fsreadfd; /* file descriptor for reading file system */
int fswritefd; /* file descriptor for writing file system */
-daddr_t maxfsblock; /* number of blocks in the file system */
+ufs_daddr_t maxfsblock; /* number of blocks in the file system */
char *blockmap; /* ptr to primary blk allocation map */
ino_t maxino; /* number of inodes in file system */
ino_t lastino; /* last inode in use */
char *statemap; /* ptr to inode state table */
-char *typemap; /* ptr to inode type table */
+u_char *typemap; /* ptr to inode type table */
short *lncntp; /* ptr to link count table */
ino_t lfdir; /* lost & found directory inode number */
char *lfname; /* lost & found directory name */
int lfmode; /* lost & found directory creation mode */
-daddr_t n_blks; /* number of blocks in use */
-daddr_t n_files; /* number of files in use */
+ufs_daddr_t n_blks; /* number of blocks in use */
+ufs_daddr_t n_files; /* number of files in use */
#define clearinode(dp) (*(dp) = zino)
struct dinode zino;
@@ -207,9 +210,69 @@ struct dinode zino;
#define ALTERED 0x08
#define FOUND 0x10
-time_t time();
-struct dinode *ginode();
-struct inoinfo *getinoinfo();
-void getblk();
-ino_t allocino();
-int findino();
+#define EEXIT 8 /* Standard error exit. */
+
+struct fstab;
+
+void adjust __P((struct inodesc *, int lcnt));
+ufs_daddr_t allocblk __P((long frags));
+ino_t allocdir __P((ino_t parent, ino_t request, int mode));
+ino_t allocino __P((ino_t request, int type));
+void blkerror __P((ino_t ino, char *type, ufs_daddr_t blk));
+char *blockcheck __P((char *name));
+int bread __P((int fd, char *buf, ufs_daddr_t blk, long size));
+void bufinit __P((void));
+void bwrite __P((int fd, char *buf, ufs_daddr_t blk, long size));
+void cacheino __P((struct dinode *dp, ino_t inumber));
+void catch __P((int));
+void catchquit __P((int));
+int changeino __P((ino_t dir, char *name, ino_t newnum));
+int checkfstab __P((int preen, int maxrun,
+ int (*docheck)(struct fstab *),
+ int (*chkit)(char *, char *, long, int)));
+int chkrange __P((ufs_daddr_t blk, int cnt));
+void ckfini __P((int markclean));
+int ckinode __P((struct dinode *dp, struct inodesc *));
+void clri __P((struct inodesc *, char *type, int flag));
+void direrror __P((ino_t ino, char *errmesg));
+int dirscan __P((struct inodesc *));
+int dofix __P((struct inodesc *, char *msg));
+void ffs_clrblock __P((struct fs *, u_char *, ufs_daddr_t));
+void ffs_fragacct __P((struct fs *, int, int32_t [], int));
+int ffs_isblock __P((struct fs *, u_char *, ufs_daddr_t));
+void ffs_setblock __P((struct fs *, u_char *, ufs_daddr_t));
+void fileerror __P((ino_t cwd, ino_t ino, char *errmesg));
+int findino __P((struct inodesc *));
+int findname __P((struct inodesc *));
+void flush __P((int fd, struct bufarea *bp));
+void freeblk __P((ufs_daddr_t blkno, long frags));
+void freeino __P((ino_t ino));
+void freeinodebuf __P((void));
+int ftypeok __P((struct dinode *dp));
+void getblk __P((struct bufarea *bp, ufs_daddr_t blk, long size));
+struct bufarea *getdatablk __P((ufs_daddr_t blkno, long size));
+struct inoinfo *getinoinfo __P((ino_t inumber));
+struct dinode *getnextinode __P((ino_t inumber));
+void getpathname __P((char *namebuf, ino_t curdir, ino_t ino));
+struct dinode *ginode __P((ino_t inumber));
+void inocleanup __P((void));
+void inodirty __P((void));
+int linkup __P((ino_t orphan, ino_t parentdir));
+int makeentry __P((ino_t parent, ino_t ino, char *name));
+void panic __P((const char *fmt, ...));
+void pass1 __P((void));
+void pass1b __P((void));
+int pass1check __P((struct inodesc *));
+void pass2 __P((void));
+void pass3 __P((void));
+void pass4 __P((void));
+int pass4check __P((struct inodesc *));
+void pass5 __P((void));
+void pfatal __P((const char *fmt, ...));
+void pinode __P((ino_t ino));
+void propagate __P((void));
+void pwarn __P((const char *fmt, ...));
+int reply __P((char *question));
+void resetinodebuf __P((void));
+int setup __P((char *dev));
+void voidquit __P((int));
diff --git a/sbin/fsck/inode.c b/sbin/fsck/inode.c
index f1c1758..1d40761 100644
--- a/sbin/fsck/inode.c
+++ b/sbin/fsck/inode.c
@@ -32,26 +32,32 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)inode.c 8.4 (Berkeley) 4/18/94";
+static char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
+
+#include <err.h>
#include <pwd.h>
-#include <stdlib.h>
#include <string.h>
+
#include "fsck.h"
static ino_t startinum;
+static int iblock __P((struct inodesc *, long ilevel, quad_t isize));
+
+int
ckinode(dp, idesc)
struct dinode *dp;
register struct inodesc *idesc;
{
- register daddr_t *ap;
+ ufs_daddr_t *ap;
long ret, n, ndb, offset;
struct dinode dino;
quad_t remsize, sizepb;
@@ -99,18 +105,18 @@ ckinode(dp, idesc)
return (KEEPON);
}
+static int
iblock(idesc, ilevel, isize)
struct inodesc *idesc;
long ilevel;
quad_t isize;
{
- register daddr_t *ap;
- register daddr_t *aplim;
- register struct bufarea *bp;
+ ufs_daddr_t *ap;
+ ufs_daddr_t *aplim;
+ struct bufarea *bp;
int i, n, (*func)(), nif;
quad_t sizepb;
char buf[BUFSIZ];
- extern int dirscan(), pass1check();
if (idesc->id_type == ADDR) {
func = idesc->id_func;
@@ -164,8 +170,9 @@ iblock(idesc, ilevel, isize)
* Check that a block in a legal block number.
* Return 0 if in range, 1 if out of range.
*/
+int
chkrange(blk, cnt)
- daddr_t blk;
+ ufs_daddr_t blk;
int cnt;
{
register int c;
@@ -204,10 +211,10 @@ struct dinode *
ginode(inumber)
ino_t inumber;
{
- daddr_t iblk;
+ ufs_daddr_t iblk;
if (inumber < ROOTINO || inumber > maxino)
- errexit("bad inode number %d to ginode\n", inumber);
+ errx(EEXIT, "bad inode number %d to ginode", inumber);
if (startinum == 0 ||
inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
iblk = ino_to_fsba(&sblock, inumber);
@@ -232,11 +239,11 @@ getnextinode(inumber)
ino_t inumber;
{
long size;
- daddr_t dblk;
+ ufs_daddr_t dblk;
static struct dinode *dp;
if (inumber != nextino++ || inumber > maxino)
- errexit("bad inode number %d to nextinode\n", inumber);
+ errx(EEXIT, "bad inode number %d to nextinode", inumber);
if (inumber >= lastinum) {
readcnt++;
dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
@@ -253,6 +260,7 @@ getnextinode(inumber)
return (dp++);
}
+void
resetinodebuf()
{
@@ -273,11 +281,12 @@ resetinodebuf()
}
if (inodebuf == NULL &&
(inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
- errexit("Cannot allocate space for inode buffer\n");
+ errx(EEXIT, "Cannot allocate space for inode buffer");
while (nextino < ROOTINO)
(void)getnextinode(nextino);
}
+void
freeinodebuf()
{
@@ -293,6 +302,7 @@ freeinodebuf()
*
* Enter inodes into the cache.
*/
+void
cacheino(dp, inumber)
register struct dinode *dp;
ino_t inumber;
@@ -305,25 +315,27 @@ cacheino(dp, inumber)
if (blks > NDADDR)
blks = NDADDR + NIADDR;
inp = (struct inoinfo *)
- malloc(sizeof(*inp) + (blks - 1) * sizeof(daddr_t));
+ malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
if (inp == NULL)
return;
inpp = &inphead[inumber % numdirs];
inp->i_nexthash = *inpp;
*inpp = inp;
- inp->i_parent = (ino_t)0;
+ if (inumber == ROOTINO)
+ inp->i_parent = ROOTINO;
+ else
+ inp->i_parent = (ino_t)0;
inp->i_dotdot = (ino_t)0;
inp->i_number = inumber;
inp->i_isize = dp->di_size;
- inp->i_numblks = blks * sizeof(daddr_t);
- bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0],
- (size_t)inp->i_numblks);
+ inp->i_numblks = blks * sizeof(ufs_daddr_t);
+ memmove(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks);
if (inplast == listmax) {
listmax += 100;
inpsort = (struct inoinfo **)realloc((char *)inpsort,
(unsigned)listmax * sizeof(struct inoinfo *));
if (inpsort == NULL)
- errexit("cannot increase directory list");
+ errx(EEXIT, "cannot increase directory list");
}
inpsort[inplast++] = inp;
}
@@ -342,13 +354,14 @@ getinoinfo(inumber)
continue;
return (inp);
}
- errexit("cannot find inode %d\n", inumber);
+ errx(EEXIT, "cannot find inode %d", inumber);
return ((struct inoinfo *)0);
}
/*
* Clean up all the inode cache structure.
*/
+void
inocleanup()
{
register struct inoinfo **inpp;
@@ -362,12 +375,14 @@ inocleanup()
inphead = inpsort = NULL;
}
+void
inodirty()
{
dirty(pbp);
}
+void
clri(idesc, type, flag)
register struct inodesc *idesc;
char *type;
@@ -392,6 +407,7 @@ clri(idesc, type, flag)
}
}
+int
findname(idesc)
struct inodesc *idesc;
{
@@ -399,10 +415,11 @@ findname(idesc)
if (dirp->d_ino != idesc->id_parent)
return (KEEPON);
- bcopy(dirp->d_name, idesc->id_name, (size_t)dirp->d_namlen + 1);
+ memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
return (STOP|FOUND);
}
+int
findino(idesc)
struct inodesc *idesc;
{
@@ -418,6 +435,7 @@ findino(idesc)
return (KEEPON);
}
+void
pinode(ino)
ino_t ino;
{
@@ -439,14 +457,15 @@ pinode(ino)
if (preen)
printf("%s: ", cdevname);
printf("SIZE=%qu ", dp->di_size);
- p = ctime(&dp->di_mtime.ts_sec);
+ p = ctime(&dp->di_mtime);
printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
}
+void
blkerror(ino, type, blk)
ino_t ino;
char *type;
- daddr_t blk;
+ ufs_daddr_t blk;
{
pfatal("%ld %s I=%lu", blk, type, ino);
@@ -466,7 +485,7 @@ blkerror(ino, type, blk)
return;
default:
- errexit("BAD STATE %d TO BLKERR", statemap[ino]);
+ errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]);
/* NOTREACHED */
}
}
@@ -509,7 +528,7 @@ allocino(request, type)
return (0);
}
dp->di_mode = type;
- (void)time(&dp->di_atime.ts_sec);
+ (void)time(&dp->di_atime);
dp->di_mtime = dp->di_ctime = dp->di_atime;
dp->di_size = sblock.fs_fsize;
dp->di_blocks = btodb(sblock.fs_fsize);
@@ -523,14 +542,14 @@ allocino(request, type)
/*
* deallocate an inode
*/
+void
freeino(ino)
ino_t ino;
{
struct inodesc idesc;
- extern int pass4check();
struct dinode *dp;
- bzero((char *)&idesc, sizeof(struct inodesc));
+ memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR;
idesc.id_func = pass4check;
idesc.id_number = ino;
diff --git a/sbin/fsck/main.c b/sbin/fsck/main.c
index 2e69715..f719ac9 100644
--- a/sbin/fsck/main.c
+++ b/sbin/fsck/main.c
@@ -38,32 +38,40 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94";
+static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <sys/mount.h>
+
#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/ufsmount.h>
#include <ufs/ffs/fs.h>
+
+#include <ctype.h>
+#include <err.h>
#include <fstab.h>
-#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
+
#include "fsck.h"
-void catch(), catchquit(), voidquit();
int returntosingle;
+static int argtoi __P((int flag, char *req, char *str, int base));
+static int docheck __P((struct fstab *fsp));
+static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
+ int child));
+void main __P((int argc, char *argv[]));
+
+void
main(argc, argv)
int argc;
char *argv[];
{
int ch;
int ret, maxrun = 0;
- extern int docheck(), checkfilesys();
- extern char *optarg, *blockcheck();
+ extern char *optarg;
extern int optind;
sync();
@@ -93,7 +101,7 @@ main(argc, argv)
case 'm':
lfmode = argtoi('m', "mode", optarg, 8);
if (lfmode &~ 07777)
- errexit("bad mode to -m: %o\n", lfmode);
+ errx(EEXIT, "bad mode to -m: %o", lfmode);
printf("** lost+found creation mode %o\n", lfmode);
break;
@@ -110,7 +118,7 @@ main(argc, argv)
break;
default:
- errexit("%c option?\n", ch);
+ errx(EEXIT, "%c option?", ch);
}
}
argc -= optind;
@@ -130,6 +138,7 @@ main(argc, argv)
exit(ret);
}
+static int
argtoi(flag, req, str, base)
int flag;
char *req, *str;
@@ -140,13 +149,14 @@ argtoi(flag, req, str, base)
ret = (int)strtol(str, &cp, base);
if (cp == str || *cp)
- errexit("-%c flag requires a %s\n", flag, req);
+ errx(EEXIT, "-%c flag requires a %s", flag, req);
return (ret);
}
/*
* Determine whether a filesystem should be checked.
*/
+static int
docheck(fsp)
register struct fstab *fsp;
{
@@ -163,23 +173,28 @@ docheck(fsp)
* Check the specified filesystem.
*/
/* ARGSUSED */
+static int
checkfilesys(filesys, mntpt, auxdata, child)
char *filesys, *mntpt;
long auxdata;
+ int child;
{
- daddr_t n_ffree, n_bfree;
+ ufs_daddr_t n_ffree, n_bfree;
struct dups *dp;
struct zlncnt *zlnp;
- int cylno;
+ int cylno, flags;
if (preen && child)
(void)signal(SIGQUIT, voidquit);
cdevname = filesys;
if (debug && preen)
pwarn("starting\n");
- if (setup(filesys) == 0) {
+ switch (setup(filesys)) {
+ case 0:
if (preen)
pfatal("CAN'T CHECK FILE SYSTEM.");
+ /* fall through */
+ case -1:
return (0);
}
/*
@@ -280,7 +295,19 @@ checkfilesys(filesys, mntpt, auxdata, child)
bwrite(fswritefd, (char *)&sblock,
fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE);
}
- ckfini();
+ if (!hotroot) {
+ ckfini(1);
+ } else {
+ struct statfs stfs_buf;
+ /*
+ * Check to see if root is mounted read-write.
+ */
+ if (statfs("/", &stfs_buf) == 0)
+ flags = stfs_buf.f_flags;
+ else
+ flags = 0;
+ ckfini(flags & MNT_RDONLY);
+ }
free(blockmap);
free(statemap);
free((char *)lncntp);
@@ -289,25 +316,20 @@ checkfilesys(filesys, mntpt, auxdata, child)
if (!preen)
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
if (hotroot) {
- struct statfs stfs_buf;
+ struct ufs_args args;
+ int ret;
/*
* We modified the root. Do a mount update on
* it, unless it is read-write, so we can continue.
*/
- if (statfs("/", &stfs_buf) == 0) {
- long flags = stfs_buf.f_flags;
- struct ufs_args args;
- int ret;
-
- if (flags & MNT_RDONLY) {
- args.fspec = 0;
- args.export.ex_flags = 0;
- args.export.ex_root = 0;
- flags |= MNT_UPDATE | MNT_RELOAD;
- ret = mount(MOUNT_UFS, "/", flags, &args);
- if (ret == 0)
- return(0);
- }
+ if (flags & MNT_RDONLY) {
+ args.fspec = 0;
+ args.export.ex_flags = 0;
+ args.export.ex_root = 0;
+ flags |= MNT_UPDATE | MNT_RELOAD;
+ ret = mount("ufs", "/", flags, &args);
+ if (ret == 0)
+ return (0);
}
if (!preen)
printf("\n***** REBOOT NOW *****\n");
diff --git a/sbin/fsck/pass1.c b/sbin/fsck/pass1.c
index ca255fe..1169adb 100644
--- a/sbin/fsck/pass1.c
+++ b/sbin/fsck/pass1.c
@@ -32,23 +32,26 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
-#include <stdlib.h>
+
+#include <err.h>
#include <string.h>
+
#include "fsck.h"
-static daddr_t badblk;
-static daddr_t dupblk;
-int pass1check();
-struct dinode *getnextinode();
+static ufs_daddr_t badblk;
+static ufs_daddr_t dupblk;
+static void checkinode __P((ino_t inumber, struct inodesc *));
+void
pass1()
{
ino_t inumber;
@@ -71,7 +74,7 @@ pass1()
/*
* Find all allocated blocks.
*/
- bzero((char *)&idesc, sizeof(struct inodesc));
+ memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR;
idesc.id_func = pass1check;
inumber = 0;
@@ -87,6 +90,7 @@ pass1()
freeinodebuf();
}
+static void
checkinode(inumber, idesc)
ino_t inumber;
register struct inodesc *idesc;
@@ -95,15 +99,15 @@ checkinode(inumber, idesc)
struct zlncnt *zlnp;
int ndb, j;
mode_t mode;
- char symbuf[MAXSYMLINKLEN];
+ char *symbuf;
dp = getnextinode(inumber);
mode = dp->di_mode & IFMT;
if (mode == 0) {
- if (bcmp((char *)dp->di_db, (char *)zino.di_db,
- NDADDR * sizeof(daddr_t)) ||
- bcmp((char *)dp->di_ib, (char *)zino.di_ib,
- NIADDR * sizeof(daddr_t)) ||
+ if (memcmp(dp->di_db, zino.di_db,
+ NDADDR * sizeof(ufs_daddr_t)) ||
+ memcmp(dp->di_ib, zino.di_ib,
+ NIADDR * sizeof(ufs_daddr_t)) ||
dp->di_mode || dp->di_size) {
pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber);
if (reply("CLEAR") == 1) {
@@ -117,7 +121,8 @@ checkinode(inumber, idesc)
}
lastino = inumber;
if (/* dp->di_size < 0 || */
- dp->di_size + sblock.fs_bsize - 1 < dp->di_size) {
+ dp->di_size + sblock.fs_bsize - 1 < dp->di_size ||
+ (mode == IFDIR && dp->di_size > MAXDIRSIZE)) {
if (debug)
printf("bad size %qu:", dp->di_size);
goto unknown;
@@ -141,18 +146,18 @@ checkinode(inumber, idesc)
if (doinglevel2 &&
dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN &&
dp->di_blocks != 0) {
+ symbuf = alloca(secsize);
if (bread(fsreadfd, symbuf,
fsbtodb(&sblock, dp->di_db[0]),
- (long)dp->di_size) != 0)
- errexit("cannot read symlink");
+ (long)secsize) != 0)
+ errx(EEXIT, "cannot read symlink");
if (debug) {
symbuf[dp->di_size] = 0;
printf("convert symlink %d(%s) of size %d\n",
inumber, symbuf, (long)dp->di_size);
}
dp = ginode(inumber);
- bcopy(symbuf, (caddr_t)dp->di_shortlink,
- (long)dp->di_size);
+ memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
dp->di_blocks = 0;
inodirty();
}
@@ -161,7 +166,7 @@ checkinode(inumber, idesc)
* will detect any garbage after symlink string.
*/
if (dp->di_size < sblock.fs_maxsymlinklen) {
- ndb = howmany(dp->di_size, sizeof(daddr_t));
+ ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
if (ndb > NDADDR) {
j = ndb - NDADDR;
for (ndb = 1; j > 1; j--)
@@ -194,7 +199,7 @@ checkinode(inumber, idesc)
if (zlnp == NULL) {
pfatal("LINK COUNT TABLE OVERFLOW");
if (reply("CONTINUE") == 0)
- errexit("");
+ exit(EEXIT);
} else {
zlnp->zlncnt = inumber;
zlnp->next = zlnhead;
@@ -246,12 +251,13 @@ unknown:
}
}
+int
pass1check(idesc)
register struct inodesc *idesc;
{
int res = KEEPON;
int anyout, nfrags;
- daddr_t blkno = idesc->id_blkno;
+ ufs_daddr_t blkno = idesc->id_blkno;
register struct dups *dlp;
struct dups *new;
@@ -263,7 +269,7 @@ pass1check(idesc)
if (preen)
printf(" (SKIPPING)\n");
else if (reply("CONTINUE") == 0)
- errexit("");
+ exit(EEXIT);
return (STOP);
}
}
@@ -281,14 +287,14 @@ pass1check(idesc)
if (preen)
printf(" (SKIPPING)\n");
else if (reply("CONTINUE") == 0)
- errexit("");
+ exit(EEXIT);
return (STOP);
}
new = (struct dups *)malloc(sizeof(struct dups));
if (new == NULL) {
pfatal("DUP TABLE OVERFLOW.");
if (reply("CONTINUE") == 0)
- errexit("");
+ exit(EEXIT);
return (STOP);
}
new->dup = blkno;
diff --git a/sbin/fsck/pass1b.c b/sbin/fsck/pass1b.c
index 27b2dfd..203fb53 100644
--- a/sbin/fsck/pass1b.c
+++ b/sbin/fsck/pass1b.c
@@ -32,19 +32,23 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
+
#include <string.h>
+
#include "fsck.h"
-int pass1bcheck();
static struct dups *duphead;
+static int pass1bcheck __P((struct inodesc *));
+void
pass1b()
{
register int c, i;
@@ -52,7 +56,7 @@ pass1b()
struct inodesc idesc;
ino_t inumber;
- bzero((char *)&idesc, sizeof(struct inodesc));
+ memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR;
idesc.id_func = pass1bcheck;
duphead = duplist;
@@ -72,12 +76,13 @@ pass1b()
}
}
+static int
pass1bcheck(idesc)
register struct inodesc *idesc;
{
register struct dups *dlp;
int nfrags, res = KEEPON;
- daddr_t blkno = idesc->id_blkno;
+ ufs_daddr_t blkno = idesc->id_blkno;
for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1))
diff --git a/sbin/fsck/pass2.c b/sbin/fsck/pass2.c
index 6314751..27490fe 100644
--- a/sbin/fsck/pass2.c
+++ b/sbin/fsck/pass2.c
@@ -32,22 +32,27 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)pass2.c 8.2 (Berkeley) 2/27/94";
+static char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
-#include <stdlib.h>
+
+#include <err.h>
#include <string.h>
+
#include "fsck.h"
#define MINDIRSIZE (sizeof (struct dirtemplate))
-int pass2check(), blksort();
+static int blksort __P((const void *, const void *));
+static int pass2check __P((struct inodesc *));
+void
pass2()
{
register struct dinode *dp;
@@ -62,9 +67,9 @@ pass2()
case USTATE:
pfatal("ROOT INODE UNALLOCATED");
if (reply("ALLOCATE") == 0)
- errexit("");
+ exit(EEXIT);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
- errexit("CANNOT ALLOCATE ROOT INODE\n");
+ errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break;
case DCLEAR:
@@ -72,11 +77,11 @@ pass2()
if (reply("REALLOCATE")) {
freeino(ROOTINO);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
- errexit("CANNOT ALLOCATE ROOT INODE\n");
+ errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break;
}
if (reply("CONTINUE") == 0)
- errexit("");
+ exit(EEXIT);
break;
case FSTATE:
@@ -85,11 +90,11 @@ pass2()
if (reply("REALLOCATE")) {
freeino(ROOTINO);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
- errexit("CANNOT ALLOCATE ROOT INODE\n");
+ errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break;
}
if (reply("FIX") == 0)
- errexit("");
+ exit(EEXIT);
dp = ginode(ROOTINO);
dp->di_mode &= ~IFMT;
dp->di_mode |= IFDIR;
@@ -100,9 +105,13 @@ pass2()
break;
default:
- errexit("BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
+ errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
}
statemap[ROOTINO] = DFOUND;
+ if (newinofmt) {
+ statemap[WINO] = FSTATE;
+ typemap[WINO] = DT_WHT;
+ }
/*
* Sort the directory list into disk block order.
*/
@@ -110,7 +119,7 @@ pass2()
/*
* Check the integrity of each directory.
*/
- bzero((char *)&curino, sizeof(struct inodesc));
+ memset(&curino, 0, sizeof(struct inodesc));
curino.id_type = DATA;
curino.id_func = pass2check;
dp = &dino;
@@ -142,11 +151,10 @@ pass2()
dp = &dino;
}
}
- bzero((char *)&dino, sizeof(struct dinode));
+ memset(&dino, 0, sizeof(struct dinode));
dino.di_mode = IFDIR;
dp->di_size = inp->i_isize;
- bcopy((char *)&inp->i_blks[0], (char *)&dp->di_db[0],
- (size_t)inp->i_numblks);
+ memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks);
curino.id_number = inp->i_number;
curino.id_parent = inp->i_parent;
(void)ckinode(dp, &curino);
@@ -189,6 +197,7 @@ pass2()
propagate();
}
+static int
pass2check(idesc)
struct inodesc *idesc;
{
@@ -236,6 +245,15 @@ pass2check(idesc)
proto.d_type = 0;
proto.d_namlen = 1;
(void)strcpy(proto.d_name, ".");
+# if BYTE_ORDER == LITTLE_ENDIAN
+ if (!newinofmt) {
+ u_char tmp;
+
+ tmp = proto.d_type;
+ proto.d_type = proto.d_namlen;
+ proto.d_namlen = tmp;
+ }
+# endif
entrysize = DIRSIZ(0, &proto);
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
@@ -244,17 +262,17 @@ pass2check(idesc)
pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
} else if (dirp->d_reclen < 2 * entrysize) {
proto.d_reclen = dirp->d_reclen;
- bcopy((char *)&proto, (char *)dirp, (size_t)entrysize);
+ memmove(dirp, &proto, (size_t)entrysize);
if (reply("FIX") == 1)
ret |= ALTERED;
} else {
n = dirp->d_reclen - entrysize;
proto.d_reclen = entrysize;
- bcopy((char *)&proto, (char *)dirp, (size_t)entrysize);
+ memmove(dirp, &proto, (size_t)entrysize);
idesc->id_entryno++;
lncntp[dirp->d_ino]--;
dirp = (struct direct *)((char *)(dirp) + entrysize);
- bzero((char *)dirp, (size_t)n);
+ memset(dirp, 0, (size_t)n);
dirp->d_reclen = n;
if (reply("FIX") == 1)
ret |= ALTERED;
@@ -270,6 +288,15 @@ chk1:
proto.d_type = 0;
proto.d_namlen = 2;
(void)strcpy(proto.d_name, "..");
+# if BYTE_ORDER == LITTLE_ENDIAN
+ if (!newinofmt) {
+ u_char tmp;
+
+ tmp = proto.d_type;
+ proto.d_type = proto.d_namlen;
+ proto.d_namlen = tmp;
+ }
+# endif
entrysize = DIRSIZ(0, &proto);
if (idesc->id_entryno == 0) {
n = DIRSIZ(0, dirp);
@@ -280,7 +307,7 @@ chk1:
idesc->id_entryno++;
lncntp[dirp->d_ino]--;
dirp = (struct direct *)((char *)(dirp) + n);
- bzero((char *)dirp, (size_t)proto.d_reclen);
+ memset(dirp, 0, (size_t)proto.d_reclen);
dirp->d_reclen = proto.d_reclen;
}
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
@@ -309,7 +336,7 @@ chk1:
inp->i_dotdot = inp->i_parent;
fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
proto.d_reclen = dirp->d_reclen;
- bcopy((char *)&proto, (char *)dirp, (size_t)entrysize);
+ memmove(dirp, &proto, (size_t)entrysize);
if (reply("FIX") == 1)
ret |= ALTERED;
}
@@ -343,6 +370,14 @@ chk2:
if (dirp->d_ino > maxino) {
fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE");
n = reply("REMOVE");
+ } else if (newinofmt &&
+ ((dirp->d_ino == WINO && dirp->d_type != DT_WHT) ||
+ (dirp->d_ino != WINO && dirp->d_type == DT_WHT))) {
+ fileerror(idesc->id_number, dirp->d_ino, "BAD WHITEOUT ENTRY");
+ dirp->d_ino = WINO;
+ dirp->d_type = DT_WHT;
+ if (reply("FIX") == 1)
+ ret |= ALTERED;
} else {
again:
switch (statemap[dirp->d_ino]) {
@@ -409,7 +444,7 @@ again:
break;
default:
- errexit("BAD STATE %d FOR INODE I=%d",
+ errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
statemap[dirp->d_ino], dirp->d_ino);
}
}
@@ -422,9 +457,11 @@ again:
/*
* Routine to sort disk blocks.
*/
-blksort(inpp1, inpp2)
- struct inoinfo **inpp1, **inpp2;
+static int
+blksort(arg1, arg2)
+ const void *arg1, *arg2;
{
- return ((*inpp1)->i_blks[0] - (*inpp2)->i_blks[0]);
+ return ((*(struct inoinfo **)arg1)->i_blks[0] -
+ (*(struct inoinfo **)arg2)->i_blks[0]);
}
diff --git a/sbin/fsck/pass3.c b/sbin/fsck/pass3.c
index 5c6f09d..e8c9446 100644
--- a/sbin/fsck/pass3.c
+++ b/sbin/fsck/pass3.c
@@ -32,15 +32,18 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)pass3.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
+
#include "fsck.h"
+void
pass3()
{
register struct inoinfo **inpp, *inp;
diff --git a/sbin/fsck/pass4.c b/sbin/fsck/pass4.c
index 7450530..97bc7d0 100644
--- a/sbin/fsck/pass4.c
+++ b/sbin/fsck/pass4.c
@@ -32,19 +32,21 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)pass4.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
-#include <stdlib.h>
+
+#include <err.h>
#include <string.h>
-#include "fsck.h"
-int pass4check();
+#include "fsck.h"
+void
pass4()
{
register ino_t inumber;
@@ -53,7 +55,7 @@ pass4()
struct inodesc idesc;
int n;
- bzero((char *)&idesc, sizeof(struct inodesc));
+ memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR;
idesc.id_func = pass4check;
for (inumber = ROOTINO; inumber <= lastino; inumber++) {
@@ -97,18 +99,19 @@ pass4()
break;
default:
- errexit("BAD STATE %d FOR INODE I=%d",
+ errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
statemap[inumber], inumber);
}
}
}
+int
pass4check(idesc)
register struct inodesc *idesc;
{
register struct dups *dlp;
int nfrags, res = KEEPON;
- daddr_t blkno = idesc->id_blkno;
+ ufs_daddr_t blkno = idesc->id_blkno;
for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1)) {
diff --git a/sbin/fsck/pass5.c b/sbin/fsck/pass5.c
index 2e98f96..27509d3 100644
--- a/sbin/fsck/pass5.c
+++ b/sbin/fsck/pass5.c
@@ -32,24 +32,29 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)pass5.c 8.2 (Berkeley) 2/2/94";
+static char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
+
+#include <err.h>
#include <string.h>
+
#include "fsck.h"
+void
pass5()
{
int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
- register struct fs *fs = &sblock;
- register struct cg *cg = &cgrp;
- daddr_t dbase, dmax;
- register daddr_t d;
- register long i, j;
+ struct fs *fs = &sblock;
+ struct cg *cg = &cgrp;
+ ufs_daddr_t dbase, dmax;
+ ufs_daddr_t d;
+ long i, j;
struct csum *cs;
struct csum cstotal;
struct inodesc idesc[3];
@@ -57,9 +62,10 @@ pass5()
register struct cg *newcg = (struct cg *)buf;
struct ocg *ocg = (struct ocg *)buf;
- bzero((char *)newcg, (size_t)fs->fs_cgsize);
+ statemap[WINO] = USTATE;
+ memset(newcg, 0, (size_t)fs->fs_cgsize);
newcg->cg_niblk = fs->fs_ipg;
- if (cvtlevel > 3) {
+ if (cvtlevel >= 3) {
if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
if (preen)
pwarn("DELETING CLUSTERING MAPS\n");
@@ -101,8 +107,9 @@ pass5()
switch ((int)fs->fs_postblformat) {
case FS_42POSTBLFMT:
- basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link);
- sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]);
+ basesize = (char *)(&ocg->cg_btot[0]) -
+ (char *)(&ocg->cg_firstfield);
+ sumsize = &ocg->cg_iused[0] - (u_int8_t *)(&ocg->cg_btot[0]);
mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
(u_char *)&ocg->cg_iused[0];
ocg->cg_magic = CG_MAGIC;
@@ -112,7 +119,7 @@ pass5()
case FS_DYNAMICPOSTBLFMT:
newcg->cg_btotoff =
- &newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
+ &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield);
newcg->cg_boff =
newcg->cg_btotoff + fs->fs_cpg * sizeof(long);
newcg->cg_iusedoff = newcg->cg_boff +
@@ -134,22 +141,24 @@ pass5()
howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY);
}
newcg->cg_magic = CG_MAGIC;
- basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
+ basesize = &newcg->cg_space[0] -
+ (u_char *)(&newcg->cg_firstfield);
sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
break;
default:
- errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n",
+ sumsize = 0; /* keep lint happy */
+ errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
fs->fs_postblformat);
}
- bzero((char *)&idesc[0], sizeof idesc);
+ memset(&idesc[0], 0, sizeof idesc);
for (i = 0; i < 3; i++) {
idesc[i].id_type = ADDR;
if (doinglevel2)
idesc[i].id_fix = FIX;
}
- bzero((char *)&cstotal, sizeof(struct csum));
+ memset(&cstotal, 0, sizeof(struct csum));
j = blknum(fs, fs->fs_size + fs->fs_frag - 1);
for (i = fs->fs_size; i < j; i++)
setbmap(i);
@@ -186,8 +195,8 @@ pass5()
newcg->cg_irotor = cg->cg_irotor;
else
newcg->cg_irotor = 0;
- bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum);
- bzero((char *)&cg_blktot(newcg)[0],
+ memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
+ memset(&cg_blktot(newcg)[0], 0,
(size_t)(sumsize + mapsize));
if (fs->fs_postblformat == FS_42POSTBLFMT)
ocg->cg_magic = CG_MAGIC;
@@ -213,7 +222,7 @@ pass5()
default:
if (j < ROOTINO)
break;
- errexit("BAD STATE %d FOR INODE I=%d",
+ errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
statemap[j], j);
}
}
@@ -247,7 +256,7 @@ pass5()
}
}
if (fs->fs_contigsumsize > 0) {
- long *sump = cg_clustersum(newcg);
+ int32_t *sump = cg_clustersum(newcg);
u_char *mapp = cg_clustersfree(newcg);
int map = *mapp++;
int bit = 1;
@@ -280,38 +289,38 @@ pass5()
cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
cs = &fs->fs_cs(fs, c);
- if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 &&
+ if (memcmp(&newcg->cg_cs, cs, sizeof *cs) != 0 &&
dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
- bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs);
+ memmove(cs, &newcg->cg_cs, sizeof *cs);
sbdirty();
}
if (doinglevel1) {
- bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize);
+ memmove(cg, newcg, (size_t)fs->fs_cgsize);
cgdirty();
continue;
}
- if (bcmp(cg_inosused(newcg),
+ if (memcmp(cg_inosused(newcg),
cg_inosused(cg), mapsize) != 0 &&
dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
- bcopy(cg_inosused(newcg), cg_inosused(cg),
+ memmove(cg_inosused(cg), cg_inosused(newcg),
(size_t)mapsize);
cgdirty();
}
- if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 ||
- bcmp((char *)&cg_blktot(newcg)[0],
- (char *)&cg_blktot(cg)[0], sumsize) != 0) &&
+ if ((memcmp(newcg, cg, basesize) != 0 ||
+ memcmp(&cg_blktot(newcg)[0],
+ &cg_blktot(cg)[0], sumsize) != 0) &&
dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
- bcopy((char *)newcg, (char *)cg, (size_t)basesize);
- bcopy((char *)&cg_blktot(newcg)[0],
- (char *)&cg_blktot(cg)[0], (size_t)sumsize);
+ memmove(cg, newcg, (size_t)basesize);
+ memmove(&cg_blktot(cg)[0],
+ &cg_blktot(newcg)[0], (size_t)sumsize);
cgdirty();
}
}
if (fs->fs_postblformat == FS_42POSTBLFMT)
fs->fs_nrpos = savednrpos;
- if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0
+ if (memcmp(&cstotal, &fs->fs_cstotal, sizeof *cs) != 0
&& dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
- bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs);
+ memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
fs->fs_ronly = 0;
fs->fs_fmod = 0;
sbdirty();
diff --git a/sbin/fsck/preen.c b/sbin/fsck/preen.c
index 005a65d..b5fae6b 100644
--- a/sbin/fsck/preen.c
+++ b/sbin/fsck/preen.c
@@ -32,19 +32,20 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
+
+#include <ufs/ufs/dinode.h>
+
+#include <ctype.h>
#include <fstab.h>
#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-char *rawname(), *unrawname(), *blockcheck();
+#include "fsck.h"
struct part {
struct part *next; /* forward link of partitions on disk */
@@ -63,9 +64,19 @@ struct disk {
int nrun, ndisks;
char hotroot;
+static void addpart __P((char *name, char *fsname, long auxdata));
+static struct disk *finddisk __P((char *name));
+static char *rawname __P((char *name));
+static int startdisk __P((struct disk *dk,
+ int (*checkit)(char *, char *, long, int)));
+static char *unrawname __P((char *name));
+
+int
checkfstab(preen, maxrun, docheck, chkit)
- int preen, maxrun;
- int (*docheck)(), (*chkit)();
+ int preen;
+ int maxrun;
+ int (*docheck)(struct fstab *);
+ int (*chkit)(char *, char *, long, int);
{
register struct fstab *fsp;
register struct disk *dk, *nextdisk;
@@ -84,10 +95,11 @@ checkfstab(preen, maxrun, docheck, chkit)
while ((fsp = getfsent()) != 0) {
if ((auxdata = (*docheck)(fsp)) == 0)
continue;
- if (preen == 0 || passno == 1 && fsp->fs_passno == 1) {
- if (name = blockcheck(fsp->fs_spec)) {
- if (sumstatus = (*chkit)(name,
- fsp->fs_file, auxdata, 0))
+ if (preen == 0 ||
+ (passno == 1 && fsp->fs_passno == 1)) {
+ if ((name = blockcheck(fsp->fs_spec)) != 0) {
+ if ((sumstatus = (*chkit)(name,
+ fsp->fs_file, auxdata, 0)) != 0)
return (sumstatus);
} else if (preen)
return (8);
@@ -111,7 +123,7 @@ checkfstab(preen, maxrun, docheck, chkit)
maxrun = ndisks;
nextdisk = disks;
for (passno = 0; passno < maxrun; ++passno) {
- while (ret = startdisk(nextdisk, chkit) && nrun > 0)
+ while ((ret = startdisk(nextdisk, chkit)) && nrun > 0)
sleep(10);
if (ret)
return (ret);
@@ -150,7 +162,7 @@ checkfstab(preen, maxrun, docheck, chkit)
if (nextdisk == NULL) {
if (dk->part) {
- while (ret = startdisk(dk, chkit) &&
+ while ((ret = startdisk(dk, chkit)) &&
nrun > 0)
sleep(10);
if (ret)
@@ -164,7 +176,7 @@ checkfstab(preen, maxrun, docheck, chkit)
nextdisk->pid == 0)
break;
}
- while (ret = startdisk(nextdisk, chkit) &&
+ while ((ret = startdisk(nextdisk, chkit)) &&
nrun > 0)
sleep(10);
if (ret)
@@ -186,7 +198,7 @@ checkfstab(preen, maxrun, docheck, chkit)
return (0);
}
-struct disk *
+static struct disk *
finddisk(name)
char *name;
{
@@ -194,13 +206,11 @@ finddisk(name)
register char *p;
size_t len;
- for (p = name + strlen(name) - 1; p >= name; --p)
+ for (len = strlen(name), p = name + len - 1; p >= name; --p)
if (isdigit(*p)) {
len = p - name + 1;
break;
}
- if (p < name)
- len = strlen(name);
for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) {
if (strncmp(dk->name, name, len) == 0 &&
@@ -225,6 +235,7 @@ finddisk(name)
return (dk);
}
+static void
addpart(name, fsname, auxdata)
char *name, *fsname;
long auxdata;
@@ -256,9 +267,10 @@ addpart(name, fsname, auxdata)
pt->auxdata = auxdata;
}
+static int
startdisk(dk, checkit)
register struct disk *dk;
- int (*checkit)();
+ int (*checkit)(char *, char *, long, int);
{
register struct part *pt = dk->part;
@@ -274,57 +286,61 @@ startdisk(dk, checkit)
}
char *
-blockcheck(name)
- char *name;
+blockcheck(origname)
+ char *origname;
{
struct stat stslash, stblock, stchar;
- char *raw;
+ char *newname, *raw;
int retried = 0;
hotroot = 0;
if (stat("/", &stslash) < 0) {
perror("/");
printf("Can't stat root\n");
- return (0);
+ return (origname);
}
+ newname = origname;
retry:
- if (stat(name, &stblock) < 0) {
- perror(name);
- printf("Can't stat %s\n", name);
- return (0);
+ if (stat(newname, &stblock) < 0) {
+ perror(newname);
+ printf("Can't stat %s\n", newname);
+ return (origname);
}
if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
if (stslash.st_dev == stblock.st_rdev)
hotroot++;
- raw = rawname(name);
+ raw = rawname(newname);
if (stat(raw, &stchar) < 0) {
perror(raw);
printf("Can't stat %s\n", raw);
- return (name);
+ return (origname);
}
if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
return (raw);
} else {
printf("%s is not a character device\n", raw);
- return (name);
+ return (origname);
}
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
- name = unrawname(name);
+ newname = unrawname(newname);
retried++;
goto retry;
}
- printf("Can't make sense out of name %s\n", name);
- return (0);
+ /*
+ * Not a block or character device, just return name and
+ * let the user decide whether to use it.
+ */
+ return (origname);
}
-char *
+static char *
unrawname(name)
char *name;
{
char *dp;
struct stat stb;
- if ((dp = rindex(name, '/')) == 0)
+ if ((dp = strrchr(name, '/')) == 0)
return (name);
if (stat(name, &stb) < 0)
return (name);
@@ -336,14 +352,14 @@ unrawname(name)
return (name);
}
-char *
+static char *
rawname(name)
char *name;
{
static char rawbuf[32];
char *dp;
- if ((dp = rindex(name, '/')) == 0)
+ if ((dp = strrchr(name, '/')) == 0)
return (0);
*dp = 0;
(void)strcpy(rawbuf, name);
diff --git a/sbin/fsck/setup.c b/sbin/fsck/setup.c
index a32b23c..a9ab994 100644
--- a/sbin/fsck/setup.c
+++ b/sbin/fsck/setup.c
@@ -32,35 +32,47 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)setup.c 8.2 (Berkeley) 2/21/94";
+static char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
#endif /* not lint */
#define DKTYPENAMES
#include <sys/param.h>
#include <sys/time.h>
-#include <ufs/ufs/dinode.h>
-#include <ufs/ffs/fs.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <sys/file.h>
+
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+
+#include <ctype.h>
+#include <err.h>
#include <errno.h>
-#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
+
#include "fsck.h"
struct bufarea asblk;
#define altsblock (*asblk.b_un.b_fs)
#define POWEROF2(num) (((num) & ((num) - 1)) == 0)
-struct disklabel *getdisklabel();
+static void badsb __P((int listerr, char *s));
+static int calcsb __P((char *dev, int devfd, struct fs *fs));
+static struct disklabel *getdisklabel __P((char *s, int fd));
+static int readsb __P((int listerr));
+/*
+ * Read in a superblock finding an alternate if necessary.
+ * Return 1 if successful, 0 if unsuccessful, -1 if filesystem
+ * is already clean (preen mode only).
+ */
+int
setup(dev)
char *dev;
{
long cg, size, asked, i, j;
- long bmapsize;
+ long skipclean, bmapsize;
struct disklabel *lp;
off_t sizepb;
struct stat statb;
@@ -68,6 +80,7 @@ setup(dev)
havesb = 0;
fswritefd = -1;
+ skipclean = preen;
if (stat(dev, &statb) < 0) {
printf("Can't stat %s: %s\n", dev, strerror(errno));
return (0);
@@ -98,8 +111,8 @@ setup(dev)
sblk.b_un.b_buf = malloc(SBSIZE);
asblk.b_un.b_buf = malloc(SBSIZE);
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
- errexit("cannot allocate space for superblock\n");
- if (lp = getdisklabel((char *)NULL, fsreadfd))
+ errx(EEXIT, "cannot allocate space for superblock");
+ if (lp = getdisklabel(NULL, fsreadfd))
dev_bsize = secsize = lp->d_secsize;
else
dev_bsize = secsize = DEV_BSIZE;
@@ -107,6 +120,7 @@ setup(dev)
* Read in the superblock, looking for alternates if necessary
*/
if (readsb(1) == 0) {
+ skipclean = 0;
if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0)
return(0);
if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0)
@@ -128,6 +142,10 @@ setup(dev)
}
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
}
+ if (skipclean && sblock.fs_clean) {
+ pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
+ return (-1);
+ }
maxfsblock = sblock.fs_size;
maxino = sblock.fs_ncg * sblock.fs_ipg;
/*
@@ -214,17 +232,16 @@ setup(dev)
sblock.fs_nrpos = 8;
sblock.fs_postbloff =
(char *)(&sblock.fs_opostbl[0][0]) -
- (char *)(&sblock.fs_link);
+ (char *)(&sblock.fs_firstfield);
sblock.fs_rotbloff = &sblock.fs_space[0] -
- (u_char *)(&sblock.fs_link);
+ (u_char *)(&sblock.fs_firstfield);
sblock.fs_cgsize =
fragroundup(&sblock, CGSIZE(&sblock));
sbdirty();
dirty(&asblk);
}
- if (asblk.b_dirty) {
- bcopy((char *)&sblock, (char *)&altsblock,
- (size_t)sblock.fs_sbsize);
+ if (asblk.b_dirty && !bflag) {
+ memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize);
flush(fswritefd, &asblk);
}
/*
@@ -240,7 +257,7 @@ setup(dev)
size) != 0 && !asked) {
pfatal("BAD SUMMARY INFORMATION");
if (reply("CONTINUE") == 0)
- errexit("");
+ exit(EEXIT);
asked++;
}
}
@@ -288,17 +305,18 @@ setup(dev)
return (1);
badsb:
- ckfini();
+ ckfini(0);
return (0);
}
/*
* Read in the super block and its summary info.
*/
+static int
readsb(listerr)
int listerr;
{
- daddr_t super = bflag ? bflag : SBOFF / dev_bsize;
+ ufs_daddr_t super = bflag ? bflag : SBOFF / dev_bsize;
if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0)
return (0);
@@ -338,8 +356,8 @@ readsb(listerr)
getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
if (asblk.b_errs)
return (0);
- altsblock.fs_link = sblock.fs_link;
- altsblock.fs_rlink = sblock.fs_rlink;
+ altsblock.fs_firstfield = sblock.fs_firstfield;
+ altsblock.fs_unused_1 = sblock.fs_unused_1;
altsblock.fs_time = sblock.fs_time;
altsblock.fs_cstotal = sblock.fs_cstotal;
altsblock.fs_cgrotor = sblock.fs_cgrotor;
@@ -352,12 +370,11 @@ readsb(listerr)
altsblock.fs_optim = sblock.fs_optim;
altsblock.fs_rotdelay = sblock.fs_rotdelay;
altsblock.fs_maxbpg = sblock.fs_maxbpg;
- bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp,
- sizeof sblock.fs_csp);
- bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt,
- sizeof sblock.fs_fsmnt);
- bcopy((char *)sblock.fs_sparecon, (char *)altsblock.fs_sparecon,
- sizeof sblock.fs_sparecon);
+ memmove(altsblock.fs_csp, sblock.fs_csp, sizeof sblock.fs_csp);
+ altsblock.fs_maxcluster = sblock.fs_maxcluster;
+ memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt);
+ memmove(altsblock.fs_sparecon,
+ sblock.fs_sparecon, sizeof sblock.fs_sparecon);
/*
* The following should not have to be copied.
*/
@@ -365,11 +382,26 @@ readsb(listerr)
altsblock.fs_interleave = sblock.fs_interleave;
altsblock.fs_npsect = sblock.fs_npsect;
altsblock.fs_nrpos = sblock.fs_nrpos;
+ altsblock.fs_state = sblock.fs_state;
altsblock.fs_qbmask = sblock.fs_qbmask;
altsblock.fs_qfmask = sblock.fs_qfmask;
altsblock.fs_state = sblock.fs_state;
altsblock.fs_maxfilesize = sblock.fs_maxfilesize;
- if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) {
+ if (memcmp(&sblock, &altsblock, (int)sblock.fs_sbsize)) {
+ if (debug) {
+ long *nlp, *olp, *endlp;
+
+ printf("superblock mismatches\n");
+ nlp = (long *)&altsblock;
+ olp = (long *)&sblock;
+ endlp = olp + (sblock.fs_sbsize / sizeof *olp);
+ for ( ; olp < endlp; olp++, nlp++) {
+ if (*olp == *nlp)
+ continue;
+ printf("offset %d, original %d, alternate %d\n",
+ olp - (long *)&sblock, *olp, *nlp);
+ }
+ }
badsb(listerr,
"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
return (0);
@@ -378,6 +410,7 @@ readsb(listerr)
return (1);
}
+static void
badsb(listerr, s)
int listerr;
char *s;
@@ -396,6 +429,7 @@ badsb(listerr, s)
* can be used. Do NOT attempt to use other macros without verifying that
* their needed information is available!
*/
+static int
calcsb(dev, devfd, fs)
char *dev;
int devfd;
@@ -406,8 +440,8 @@ calcsb(dev, devfd, fs)
register char *cp;
int i;
- cp = index(dev, '\0') - 1;
- if (cp == (char *)-1 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) {
+ cp = strchr(dev, '\0') - 1;
+ if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) {
pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
return (0);
}
@@ -422,7 +456,7 @@ calcsb(dev, devfd, fs)
fstypenames[pp->p_fstype] : "unknown");
return (0);
}
- bzero((char *)fs, sizeof(struct fs));
+ memset(fs, 0, sizeof(struct fs));
fs->fs_fsize = pp->p_fsize;
fs->fs_frag = pp->p_frag;
fs->fs_cpg = pp->p_cpg;
@@ -449,7 +483,7 @@ calcsb(dev, devfd, fs)
return (1);
}
-struct disklabel *
+static struct disklabel *
getdisklabel(s, fd)
char *s;
int fd;
@@ -460,7 +494,7 @@ getdisklabel(s, fd)
if (s == NULL)
return ((struct disklabel *)NULL);
pwarn("ioctl (GCINFO): %s\n", strerror(errno));
- errexit("%s: can't read disk label\n", s);
+ errx(EEXIT, "%s: can't read disk label", s);
}
return (&lab);
}
diff --git a/sbin/fsck/utilities.c b/sbin/fsck/utilities.c
index 64a4cac..a5c56da 100644
--- a/sbin/fsck/utilities.c
+++ b/sbin/fsck/utilities.c
@@ -32,22 +32,27 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+
#include <ctype.h>
+#include <err.h>
+#include <string.h>
+
#include "fsck.h"
long diskreads, totalreads; /* Disk cache statistics */
+static void rwerror __P((char *mesg, ufs_daddr_t blk));
+
+int
ftypeok(dp)
struct dinode *dp;
{
@@ -69,6 +74,7 @@ ftypeok(dp)
}
}
+int
reply(question)
char *question;
{
@@ -104,6 +110,7 @@ reply(question)
/*
* Malloc buffers and set up cache.
*/
+void
bufinit()
{
register struct bufarea *bp;
@@ -113,7 +120,7 @@ bufinit()
pbp = pdirbp = (struct bufarea *)0;
bufp = malloc((unsigned int)sblock.fs_bsize);
if (bufp == 0)
- errexit("cannot allocate buffer pool\n");
+ errx(EEXIT, "cannot allocate buffer pool");
cgblk.b_un.b_buf = bufp;
initbarea(&cgblk);
bufhead.b_next = bufhead.b_prev = &bufhead;
@@ -126,7 +133,7 @@ bufinit()
if (bp == NULL || bufp == NULL) {
if (i >= MINBUFS)
break;
- errexit("cannot allocate buffer pool\n");
+ errx(EEXIT, "cannot allocate buffer pool");
}
bp->b_un.b_buf = bufp;
bp->b_prev = &bufhead;
@@ -143,7 +150,7 @@ bufinit()
*/
struct bufarea *
getdatablk(blkno, size)
- daddr_t blkno;
+ ufs_daddr_t blkno;
long size;
{
register struct bufarea *bp;
@@ -155,7 +162,7 @@ getdatablk(blkno, size)
if ((bp->b_flags & B_INUSE) == 0)
break;
if (bp == &bufhead)
- errexit("deadlocked buffer pool\n");
+ errx(EEXIT, "deadlocked buffer pool");
getblk(bp, blkno, size);
/* fall through */
foundit:
@@ -173,10 +180,10 @@ foundit:
void
getblk(bp, blk, size)
register struct bufarea *bp;
- daddr_t blk;
+ ufs_daddr_t blk;
long size;
{
- daddr_t dblk;
+ ufs_daddr_t dblk;
dblk = fsbtodb(&sblock, blk);
if (bp->b_bno != dblk) {
@@ -188,6 +195,7 @@ getblk(bp, blk, size)
}
}
+void
flush(fd, bp)
int fd;
register struct bufarea *bp;
@@ -213,22 +221,25 @@ flush(fd, bp)
}
}
+static void
rwerror(mesg, blk)
char *mesg;
- daddr_t blk;
+ ufs_daddr_t blk;
{
if (preen == 0)
printf("\n");
pfatal("CANNOT %s: BLK %ld", mesg, blk);
if (reply("CONTINUE") == 0)
- errexit("Program terminated\n");
+ exit(EEXIT);
}
-ckfini()
+void
+ckfini(markclean)
+ int markclean;
{
register struct bufarea *bp, *nbp;
- int cnt = 0;
+ int ofsmodified, cnt = 0;
if (fswritefd < 0) {
(void)close(fsreadfd);
@@ -251,8 +262,17 @@ ckfini()
free((char *)bp);
}
if (bufhead.b_size != cnt)
- errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt);
+ errx(EEXIT, "Panic: lost %d buffers", bufhead.b_size - cnt);
pbp = pdirbp = (struct bufarea *)0;
+ if (markclean && sblock.fs_clean == 0) {
+ sblock.fs_clean = 1;
+ sbdirty();
+ ofsmodified = fsmodified;
+ flush(fswritefd, &sblk);
+ fsmodified = ofsmodified;
+ if (!preen)
+ printf("\n***** FILE SYSTEM MARKED CLEAN *****\n");
+ }
if (debug)
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
totalreads, (int)(diskreads * 100 / totalreads));
@@ -260,10 +280,11 @@ ckfini()
(void)close(fswritefd);
}
+int
bread(fd, buf, blk, size)
int fd;
char *buf;
- daddr_t blk;
+ ufs_daddr_t blk;
long size;
{
char *cp;
@@ -280,7 +301,7 @@ bread(fd, buf, blk, size)
if (lseek(fd, offset, 0) < 0)
rwerror("SEEK", blk);
errs = 0;
- bzero(buf, (size_t)size);
+ memset(buf, 0, (size_t)size);
printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
if (read(fd, cp, (int)secsize) != secsize) {
@@ -298,10 +319,11 @@ bread(fd, buf, blk, size)
return (errs);
}
+void
bwrite(fd, buf, blk, size)
int fd;
char *buf;
- daddr_t blk;
+ ufs_daddr_t blk;
long size;
{
int i;
@@ -334,6 +356,7 @@ bwrite(fd, buf, blk, size)
/*
* allocate a data block with the specified number of fragments
*/
+ufs_daddr_t
allocblk(frags)
long frags;
{
@@ -364,8 +387,9 @@ allocblk(frags)
/*
* Free a previously allocated block
*/
+void
freeblk(blkno, frags)
- daddr_t blkno;
+ ufs_daddr_t blkno;
long frags;
{
struct inodesc idesc;
@@ -378,6 +402,7 @@ freeblk(blkno, frags)
/*
* Find a pathname
*/
+void
getpathname(namebuf, curdir, ino)
char *namebuf;
ino_t curdir, ino;
@@ -398,7 +423,7 @@ getpathname(namebuf, curdir, ino)
return;
}
busy = 1;
- bzero((char *)&idesc, sizeof(struct inodesc));
+ memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA;
idesc.id_fix = IGNORE;
cp = &namebuf[MAXPATHLEN - 1];
@@ -422,7 +447,7 @@ getpathname(namebuf, curdir, ino)
break;
len = strlen(namebuf);
cp -= len;
- bcopy(namebuf, cp, (size_t)len);
+ memmove(cp, namebuf, (size_t)len);
*--cp = '/';
if (cp < &namebuf[MAXNAMLEN])
break;
@@ -431,14 +456,15 @@ getpathname(namebuf, curdir, ino)
busy = 0;
if (ino != ROOTINO)
*--cp = '?';
- bcopy(cp, namebuf, (size_t)(&namebuf[MAXPATHLEN] - cp));
+ memmove(namebuf, cp, (size_t)(&namebuf[MAXPATHLEN] - cp));
}
void
-catch()
+catch(sig)
+ int sig;
{
if (!doinglevel2)
- ckfini();
+ ckfini(0);
exit(12);
}
@@ -448,7 +474,8 @@ catch()
* so that reboot sequence may be interrupted.
*/
void
-catchquit()
+catchquit(sig)
+ int sig;
{
extern returntosingle;
@@ -462,7 +489,8 @@ catchquit()
* Used by child processes in preen.
*/
void
-voidquit()
+voidquit(sig)
+ int sig;
{
sleep(1);
@@ -473,6 +501,7 @@ voidquit()
/*
* determine whether an inode should be fixed.
*/
+int
dofix(idesc, msg)
register struct inodesc *idesc;
char *msg;
@@ -505,62 +534,95 @@ dofix(idesc, msg)
return (0);
default:
- errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix);
+ errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix);
}
/* NOTREACHED */
+ return (0);
}
-/* VARARGS1 */
-errexit(s1, s2, s3, s4)
- char *s1;
-{
- printf(s1, s2, s3, s4);
- exit(8);
-}
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
/*
* An unexpected inconsistency occured.
* Die if preening, otherwise just print message and continue.
*/
-/* VARARGS1 */
-pfatal(s, a1, a2, a3)
- char *s;
+void
+#if __STDC__
+pfatal(const char *fmt, ...)
+#else
+pfatal(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
{
-
- if (preen) {
- printf("%s: ", cdevname);
- printf(s, a1, a2, a3);
- printf("\n");
- printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
- cdevname);
- exit(8);
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ if (!preen) {
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ return;
}
- printf(s, a1, a2, a3);
+ (void)fprintf(stderr, "%s: ", cdevname);
+ (void)vfprintf(stderr, fmt, ap);
+ (void)fprintf(stderr,
+ "\n%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
+ cdevname);
+ exit(EEXIT);
}
/*
* Pwarn just prints a message when not preening,
* or a warning (preceded by filename) when preening.
*/
-/* VARARGS1 */
-pwarn(s, a1, a2, a3, a4, a5, a6)
- char *s;
+void
+#if __STDC__
+pwarn(const char *fmt, ...)
+#else
+pwarn(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
{
-
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
if (preen)
- printf("%s: ", cdevname);
- printf(s, a1, a2, a3, a4, a5, a6);
+ (void)fprintf(stderr, "%s: ", cdevname);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
}
-#ifndef lint
/*
* Stub for routines from kernel.
*/
-panic(s)
- char *s;
+void
+#if __STDC__
+panic(const char *fmt, ...)
+#else
+panic(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
{
-
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
pfatal("INTERNAL INCONSISTENCY:");
- errexit(s);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ exit(EEXIT);
}
-#endif
diff --git a/sbin/mount_cd9660/mount_cd9660.c b/sbin/mount_cd9660/mount_cd9660.c
index 9ef716d..91cf5af 100644
--- a/sbin/mount_cd9660/mount_cd9660.c
+++ b/sbin/mount_cd9660/mount_cd9660.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)mount_cd9660.c 8.4 (Berkeley) 3/27/94
+ * @(#)mount_cd9660.c 8.7 (Berkeley) 5/1/95
*/
#ifndef lint
@@ -45,12 +45,12 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_cd9660.c 8.4 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_cd9660.c 8.7 (Berkeley) 5/1/95";
#endif /* not lint */
#include <sys/param.h>
-#define CD9660
#include <sys/mount.h>
+#include <sys/../isofs/cd9660/cd9660_mount.h>
#include <err.h>
#include <stdlib.h>
@@ -75,9 +75,8 @@ main(argc, argv)
{
struct iso_args args;
int ch, mntflags, opts;
- char *dev, *dir, *options;
+ char *dev, *dir;
- options = NULL;
mntflags = opts = 0;
while ((ch = getopt(argc, argv, "ego:r")) != EOF)
switch (ch) {
@@ -88,7 +87,7 @@ main(argc, argv)
opts |= ISOFSMNT_GENS;
break;
case 'o':
- getmntopts(options, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, 0);
break;
case 'r':
opts |= ISOFSMNT_NORRIP;
@@ -107,16 +106,16 @@ main(argc, argv)
dir = argv[1];
#define DEFAULT_ROOTUID -2
+ /*
+ * ISO 9660 filesystems are not writeable.
+ */
+ mntflags |= MNT_RDONLY;
+ args.export.ex_flags = MNT_EXRDONLY;
args.fspec = dev;
args.export.ex_root = DEFAULT_ROOTUID;
-
- if (mntflags & MNT_RDONLY)
- args.export.ex_flags = MNT_EXRDONLY;
- else
- args.export.ex_flags = 0;
args.flags = opts;
- if (mount(MOUNT_CD9660, dir, mntflags, &args) < 0)
+ if (mount("cd9660", dir, mntflags, &args) < 0)
err(1, NULL);
exit(0);
}
diff --git a/sbin/mount_fdesc/mount_fdesc.c b/sbin/mount_fdesc/mount_fdesc.c
index 55927d8..e2bef61 100644
--- a/sbin/mount_fdesc/mount_fdesc.c
+++ b/sbin/mount_fdesc/mount_fdesc.c
@@ -42,7 +42,7 @@ char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_fdesc.c 8.2 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_fdesc.c 8.3 (Berkeley) 4/26/95";
#endif /* not lint */
#include <sys/param.h>
@@ -74,7 +74,7 @@ main(argc, argv)
while ((ch = getopt(argc, argv, "o:")) != EOF)
switch (ch) {
case 'o':
- getmntopts(optarg, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, 0);
break;
case '?':
default:
@@ -86,7 +86,7 @@ main(argc, argv)
if (argc != 2)
usage();
- if (mount(MOUNT_FDESC, argv[1], mntflags, NULL))
+ if (mount("fdesc", argv[1], mntflags, NULL))
err(1, NULL);
exit(0);
}
diff --git a/sbin/mount_kernfs/mount_kernfs.c b/sbin/mount_kernfs/mount_kernfs.c
index 33a6b5e..69fcb77 100644
--- a/sbin/mount_kernfs/mount_kernfs.c
+++ b/sbin/mount_kernfs/mount_kernfs.c
@@ -42,7 +42,7 @@ char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_kernfs.c 8.2 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_kernfs.c 8.3 (Berkeley) 5/4/95";
#endif /* not lint */
#include <sys/param.h>
@@ -74,7 +74,7 @@ main(argc, argv)
while ((ch = getopt(argc, argv, "o:")) != EOF)
switch (ch) {
case 'o':
- getmntopts(optarg, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, 0);
break;
case '?':
default:
@@ -86,7 +86,7 @@ main(argc, argv)
if (argc != 2)
usage();
- if (mount(MOUNT_KERNFS, argv[1], mntflags, NULL))
+ if (mount("kernfs", argv[1], mntflags, NULL))
err(1, NULL);
exit(0);
}
diff --git a/sbin/mount_lfs/mount_lfs.c b/sbin/mount_lfs/mount_lfs.c
index 374c930..67b7f80 100644
--- a/sbin/mount_lfs/mount_lfs.c
+++ b/sbin/mount_lfs/mount_lfs.c
@@ -38,11 +38,12 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_lfs.c 8.3 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_lfs.c 8.4 (Berkeley) 4/26/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/mount.h>
+#include <ufs/ufs/ufsmount.h>
#include <err.h>
#include <stdio.h>
@@ -84,7 +85,7 @@ main(argc, argv)
noclean = 1;
break;
case 'o':
- getmntopts(optarg, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, 0);
break;
case 's':
short_rds = 1;
@@ -109,7 +110,7 @@ main(argc, argv)
else
args.export.ex_flags = 0;
- if (mount(MOUNT_LFS, fs_name, mntflags, &args))
+ if (mount("lfs", fs_name, mntflags, &args))
err(1, NULL);
if (!noclean)
diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8
index decac6e..07d2c5f 100644
--- a/sbin/mount_nfs/mount_nfs.8
+++ b/sbin/mount_nfs/mount_nfs.8
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1992, 1993, 1994
+.\" Copyright (c) 1992, 1993, 1994, 1995
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)mount_nfs.8 8.2 (Berkeley) 3/27/94
+.\" @(#)mount_nfs.8 8.3 (Berkeley) 3/29/95
.\"
-.Dd March 27, 1994
+.Dd March 29, 1995
.Dt MOUNT_NFS 8
.Os BSD 4.4
.Sh NAME
@@ -39,8 +39,9 @@
.Nd mount nfs file systems
.Sh SYNOPSIS
.Nm mount_nfs
-.Op Fl KMPTbcdiklqs
+.Op Fl 3KPTUbcdilqs
.Op Fl D Ar deadthresh
+.Op Fl I Ar readdirsize
.Op Fl L Ar leaseterm
.Op Fl R Ar retrycnt
.Op Fl a Ar maxreadahead
@@ -63,10 +64,14 @@ on to the file system tree at the point
.Ar node.
This command is normally executed by
.Xr mount 8 .
-It implements the mount protocol as described in RFC 1094, Appendix A.
+It implements the mount protocol as described in RFC 1094, Appendix A and
+.%T "NFS: Network File System Version 3 Protocol Specification" ,
+Appendix I.
.Pp
The options are:
.Bl -tag -width indent
+.It Fl 3
+Use the NFS Version 3 protocol (Version 2 is the default).
.It Fl D
Used with NQNFS to set the
.Dq "dead server threshold"
@@ -80,23 +85,27 @@ Values may be set in the range of 1 - 9, with 9 referring to an
(i.e. never assume cached data still valid).
This option is not generally recommended and is really an experimental
feature.
+.It Fl I
+Set the readdir read size to the specified value. The value should normally
+be a multiple of DIRBLKSIZ that is <= the read size for the mount.
.It Fl K
Pass Kerberos authenticators to the server for client-to-server
user-credential mapping.
-This may only be used over TCP mounts between 4.4BSD clients and servers.
+This requires that the kernel be built with the NFSKERB option.
+(Refer to the INTERNET-DRAFT titled
+.%T "Authentication Mechanisms for ONC RPC" ,
+for more information.)
.It Fl L
Used with NQNFS to set the lease term to the specified number of seconds.
Only use this argument for mounts with a large round trip delay.
Values are normally in the 10-30 second range.
-.It Fl M
-Assume that other clients are not writing a file concurrently with this client.
-This implements a slightly less strict consistency criteria than 4.3BSD-Reno
-did, that is more in line with most commercial client implementations.
-This is recommended for servers that do not support leasing.
.It Fl P
Use a reserved socket port number.
This is useful for mounting servers that require clients to use a
-reserved port number.
+reserved port number on the mistaken belief that this makes NFS
+more secure. (For the rare case where the client has a trusted root account
+but untrusworthy users and the network cables are in secure areas this does
+help, but for normal desktop clients this does not apply.)
.It Fl R
Set the retry count for doing the mount to the specified value.
.It Fl T
@@ -104,11 +113,15 @@ Use TCP transport instead of UDP.
This is recommended for servers that are not on the same LAN cable as
the client.
(NB: This is NOT supported by most non-BSD servers.)
+.It Fl U
+Force the mount protocol to use UDP transport, even for TCP NFS mounts.
+(Necessary for some old BSD servers.)
.It Fl a
Set the read-ahead count to the specified value.
This may be in the range of 0 - 4, and determines how many blocks
will be read ahead when a large file is being read sequentially.
-This is recommended for mounts with a large bandwidth * delay product.
+Trying a value greater than 1 for this is suggested for
+mounts with a large bandwidth * delay product.
.It Fl b
If an initial attempt to contact the server fails, fork off a child to keep
trying the mount in the background.
@@ -119,10 +132,12 @@ where the filesystem mount is not critical to multiuser operation.
For UDP mount points, do not do a
.Xr connect 2 .
This must be used for servers that do not reply to requests from the
-standard port number.
+standard NFS port number 2049.
.It Fl d
-Do not estimate retransmit timeout dynamically.
-This may be useful for UDP mounts that exhibit high retry rates.
+Turn off the dynamic retransmit timeout estimator.
+This may be useful for UDP mounts that exhibit high retry rates,
+since it is possible that the dynamically estimated timeout interval is too
+short.
.It Fl g
Set the maximum size of the group list for the credentials to the
specified value.
@@ -134,20 +149,15 @@ point.
Make the mount interruptible, which implies that file system calls that
are delayed due to an unresponsive server will fail with EINTR when a
termination signal is posted for the process.
-.It Fl k
-Used with NQNFS to specify
-.Dq get a lease
-for the file name being looked up.
-This is recommended unless the server is complaining about excessive
-lease load.
.It Fl l
-Used with NQNFS to specify that the \fBReaddir_and_Lookup\fR RPC should
+Used with NQNFS and NFSV3 to specify that the \fBReaddirPlus\fR RPC should
be used.
This option reduces RPC traffic for cases such as
.Dq "ls -l" ,
-but increases the lease load on the server.
-This is recommended unless the server is complaining about excessive
-lease load.
+but tends to flood the attribute and name caches with prefetched entries.
+Try this option and see whether performance improves or degrades. Probably
+most useful for client to server network interconnects with a large bandwidth
+times delay product.
.It Fl m
Set the Kerberos realm to the string argument.
Used with the
@@ -161,12 +171,18 @@ See the
.Xr mount 8
man page for possible options and their meanings.
.It Fl q
-Use the leasing extensions to the protocol to maintain cache consistency.
-This protocol, referred to as Not Quite Nfs (NQNFS),
-is only supported by 4.4BSD servers.
+Use the leasing extensions to the NFS Version 3 protocol
+to maintain cache consistency.
+This protocol version 2 revision to Not Quite Nfs (NQNFS)
+is only supported by this updated release of NFS code.
+It is not backwards compatible with the version 1 NQNFS protocol
+that was part of the first release of 4.4BSD-Lite.
+To interoperate with a first release 4.4BSD-Lite NFS system you will have to
+avoid this option until you have had an oppurtunity to upgrade the NFS code
+to release 2 of 4.4BSD-Lite on all your systems.
.It Fl r
Set the read data size to the specified value.
-It should be a power of 2 greater than or equal to 1024.
+It should normally be a power of 2 greater than or equal to 1024.
This should be used for UDP mounts when the
.Dq "fragments dropped due to timeout"
value is getting large while actively using a mount point.
@@ -191,6 +207,9 @@ Try increasing the interval if
.Xr nfsstat 1
shows high retransmit rates while the file system is active or reducing the
value if there is a low retransmit rate but long response delay observed.
+(Normally, the -d option should be specified when using this option to manually
+tune the timeout
+interval.)
.It Fl w
Set the write data size to the specified value.
Ditto the comments w.r.t. the
diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c
index cbb3ddb..91508d3 100644
--- a/sbin/mount_nfs/mount_nfs.c
+++ b/sbin/mount_nfs/mount_nfs.c
@@ -41,7 +41,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_nfs.c 8.3 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_nfs.c 8.11 (Berkeley) 5/4/95";
#endif /* not lint */
#include <sys/param.h>
@@ -59,13 +59,13 @@ static char sccsid[] = "@(#)mount_nfs.c 8.3 (Berkeley) 3/27/94";
#include <netiso/iso.h>
#endif
-#ifdef KERBEROS
+#ifdef NFSKERB
#include <kerberosIV/des.h>
#include <kerberosIV/krb.h>
#endif
#include <nfs/rpcv2.h>
-#include <nfs/nfsv2.h>
+#include <nfs/nfsproto.h>
#define KERNEL
#include <nfs/nfs.h>
#undef KERNEL
@@ -86,23 +86,57 @@ static char sccsid[] = "@(#)mount_nfs.c 8.3 (Berkeley) 3/27/94";
#include "mntopts.h"
+#define ALTF_BG 0x1
+#define ALTF_NOCONN 0x2
+#define ALTF_DUMBTIMR 0x4
+#define ALTF_INTR 0x8
+#define ALTF_KERB 0x10
+#define ALTF_NFSV3 0x20
+#define ALTF_RDIRPLUS 0x40
+#define ALTF_MNTUDP 0x80
+#define ALTF_RESVPORT 0x100
+#define ALTF_SEQPACKET 0x200
+#define ALTF_NQNFS 0x400
+#define ALTF_SOFT 0x800
+#define ALTF_TCP 0x1000
+
struct mntopt mopts[] = {
MOPT_STDOPTS,
MOPT_FORCE,
MOPT_UPDATE,
+ { "bg", 0, ALTF_BG, 1 },
+ { "conn", 1, ALTF_NOCONN, 1 },
+ { "dumbtimer", 0, ALTF_DUMBTIMR, 1 },
+ { "intr", 0, ALTF_INTR, 1 },
+#ifdef NFSKERB
+ { "kerb", 0, ALTF_KERB, 1 },
+#endif
+ { "nfsv3", 0, ALTF_NFSV3, 1 },
+ { "rdirplus", 0, ALTF_RDIRPLUS, 1 },
+ { "mntudp", 0, ALTF_MNTUDP, 1 },
+ { "resvport", 0, ALTF_RESVPORT, 1 },
+#ifdef ISO
+ { "seqpacket", 0, ALTF_SEQPACKET, 1 },
+#endif
+ { "nqnfs", 0, ALTF_NQNFS, 1 },
+ { "soft", 0, ALTF_SOFT, 1 },
+ { "tcp", 0, ALTF_TCP, 1 },
{ NULL }
};
struct nfs_args nfsdefargs = {
+ NFS_ARGSVERSION,
(struct sockaddr *)0,
sizeof (struct sockaddr_in),
SOCK_DGRAM,
0,
- (nfsv2fh_t *)0,
+ (u_char *)0,
+ 0,
0,
NFS_WSIZE,
NFS_RSIZE,
- NFS_TIMEO,
+ NFS_READDIRSIZE,
+ 10,
NFS_RETRANS,
NFS_MAXGRPS,
NFS_DEFRAHEAD,
@@ -112,19 +146,33 @@ struct nfs_args nfsdefargs = {
};
struct nfhret {
- u_long stat;
- nfsv2fh_t nfh;
+ u_long stat;
+ long vers;
+ long auth;
+ long fhsize;
+ u_char nfh[NFSX_V3FHMAX];
};
#define DEF_RETRY 10000
#define BGRND 1
#define ISBGRND 2
int retrycnt = DEF_RETRY;
int opflags = 0;
+int nfsproto = IPPROTO_UDP;
+int mnttcp_ok = 1;
-#ifdef KERBEROS
+#ifdef NFSKERB
char inst[INST_SZ];
char realm[REALM_SZ];
-KTEXT_ST kt;
+struct {
+ u_long kind;
+ KTEXT_ST kt;
+} ktick;
+struct nfsrpc_nickverf kverf;
+struct nfsrpc_fullblock kin, kout;
+NFSKERBKEY_T kivec;
+CREDENTIALS kcr;
+struct timeval ktv;
+NFSKERBKEYSCHED_T kerb_keysched;
#endif
int getnfsargs __P((char *, struct nfs_args *));
@@ -145,25 +193,32 @@ main(argc, argv)
register struct nfs_args *nfsargsp;
struct nfs_args nfsargs;
struct nfsd_cargs ncd;
- int mntflags, i, nfssvc_flag, num;
+ int mntflags, altflags, i, nfssvc_flag, num;
char *name, *p, *spec;
int error = 0;
-#ifdef KERBEROS
+#ifdef NFSKERB
uid_t last_ruid;
-#endif
-#ifdef KERBEROS
last_ruid = -1;
(void)strcpy(realm, KRB_REALM);
-#endif
+ if (sizeof (struct nfsrpc_nickverf) != RPCX_NICKVERF ||
+ sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK ||
+ ((char *)&ktick.kt) - ((char *)&ktick) != NFSX_UNSIGNED ||
+ ((char *)ktick.kt.dat) - ((char *)&ktick) != 2 * NFSX_UNSIGNED)
+ fprintf(stderr, "Yikes! NFSKERB structs not packed!!\n");
+#endif /* NFSKERB */
retrycnt = DEF_RETRY;
mntflags = 0;
+ altflags = 0;
nfsargs = nfsdefargs;
nfsargsp = &nfsargs;
while ((c = getopt(argc, argv,
- "a:bcdD:g:iKklL:Mm:o:PpqR:r:sTt:w:x:")) != EOF)
+ "3a:bcdD:g:I:iKL:lm:o:PpqR:r:sTt:w:x:U")) != EOF)
switch (c) {
+ case '3':
+ nfsargsp->flags |= NFSMNT_NFSV3;
+ break;
case 'a':
num = strtol(optarg, &p, 10);
if (*p || num < 0)
@@ -195,17 +250,21 @@ main(argc, argv)
nfsargsp->maxgrouplist = num;
nfsargsp->flags |= NFSMNT_MAXGRPS;
break;
+ case 'I':
+ num = strtol(optarg, &p, 10);
+ if (*p || num <= 0)
+ errx(1, "illegal -I value -- %s", optarg);
+ nfsargsp->readdirsize = num;
+ nfsargsp->flags |= NFSMNT_READDIRSIZE;
+ break;
case 'i':
nfsargsp->flags |= NFSMNT_INT;
break;
-#ifdef KERBEROS
+#ifdef NFSKERB
case 'K':
nfsargsp->flags |= NFSMNT_KERB;
break;
#endif
- case 'k':
- nfsargsp->flags |= NFSMNT_NQLOOKLEASE;
- break;
case 'L':
num = strtol(optarg, &p, 10);
if (*p || num < 2)
@@ -214,19 +273,49 @@ main(argc, argv)
nfsargsp->flags |= NFSMNT_LEASETERM;
break;
case 'l':
- nfsargsp->flags |= NFSMNT_RDIRALOOK;
- break;
- case 'M':
- nfsargsp->flags |= NFSMNT_MYWRITE;
+ nfsargsp->flags |= NFSMNT_RDIRPLUS;
break;
-#ifdef KERBEROS
+#ifdef NFSKERB
case 'm':
(void)strncpy(realm, optarg, REALM_SZ - 1);
realm[REALM_SZ - 1] = '\0';
break;
#endif
case 'o':
- getmntopts(optarg, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, &altflags);
+ if(altflags & ALTF_BG)
+ opflags |= BGRND;
+ if(altflags & ALTF_NOCONN)
+ nfsargsp->flags |= NFSMNT_NOCONN;
+ if(altflags & ALTF_DUMBTIMR)
+ nfsargsp->flags |= NFSMNT_DUMBTIMR;
+ if(altflags & ALTF_INTR)
+ nfsargsp->flags |= NFSMNT_INT;
+#ifdef NFSKERB
+ if(altflags & ALTF_KERB)
+ nfsargsp->flags |= NFSMNT_KERB;
+#endif
+ if(altflags & ALTF_NFSV3)
+ nfsargsp->flags |= NFSMNT_NFSV3;
+ if(altflags & ALTF_RDIRPLUS)
+ nfsargsp->flags |= NFSMNT_RDIRPLUS;
+ if(altflags & ALTF_MNTUDP)
+ mnttcp_ok = 0;
+ if(altflags & ALTF_RESVPORT)
+ nfsargsp->flags |= NFSMNT_RESVPORT;
+#ifdef ISO
+ if(altflags & ALTF_SEQPACKET)
+ nfsargsp->sotype = SOCK_SEQPACKET;
+#endif
+ if(altflags & ALTF_NQNFS)
+ nfsargsp->flags |= (NFSMNT_NQNFS|NFSMNT_NFSV3);
+ if(altflags & ALTF_SOFT)
+ nfsargsp->flags |= NFSMNT_SOFT;
+ if(altflags & ALTF_TCP) {
+ nfsargsp->sotype = SOCK_STREAM;
+ nfsproto = IPPROTO_TCP;
+ }
+ altflags = 0;
break;
case 'P':
nfsargsp->flags |= NFSMNT_RESVPORT;
@@ -237,7 +326,7 @@ main(argc, argv)
break;
#endif
case 'q':
- nfsargsp->flags |= NFSMNT_NQNFS;
+ nfsargsp->flags |= (NFSMNT_NQNFS | NFSMNT_NFSV3);
break;
case 'R':
num = strtol(optarg, &p, 10);
@@ -257,6 +346,7 @@ main(argc, argv)
break;
case 'T':
nfsargsp->sotype = SOCK_STREAM;
+ nfsproto = IPPROTO_TCP;
break;
case 't':
num = strtol(optarg, &p, 10);
@@ -279,6 +369,9 @@ main(argc, argv)
nfsargsp->retrans = num;
nfsargsp->flags |= NFSMNT_RETRANS;
break;
+ case 'U':
+ mnttcp_ok = 0;
+ break;
default:
usage();
break;
@@ -286,15 +379,18 @@ main(argc, argv)
argc -= optind;
argv += optind;
- if (argc != 2)
- error = 1;
+ if (argc != 2) {
+ usage();
+ /* NOTREACHED */
+ }
spec = *argv++;
name = *argv;
if (!getnfsargs(spec, nfsargsp))
exit(1);
- if (mount(MOUNT_NFS, name, mntflags, nfsargsp))
+
+ if (mount("nfs", name, mntflags, nfsargsp))
err(1, "%s", name);
if (nfsargsp->flags & (NFSMNT_NQNFS | NFSMNT_KERB)) {
if ((opflags & ISBGRND) == 0) {
@@ -319,29 +415,79 @@ main(argc, argv)
}
nfssvc_flag =
NFSSVC_MNTD | NFSSVC_GOTAUTH | NFSSVC_AUTHINFAIL;
-#ifdef KERBEROS
+#ifdef NFSKERB
/*
* Set up as ncd_authuid for the kerberos call.
* Must set ruid to ncd_authuid and reset the
* ticket name iff ncd_authuid is not the same
* as last time, so that the right ticket file
* is found.
+ * Get the Kerberos credential structure so that
+ * we have the seesion key and get a ticket for
+ * this uid.
+ * For more info see the IETF Draft "Authentication
+ * in ONC RPC".
*/
if (ncd.ncd_authuid != last_ruid) {
krb_set_tkt_string("");
last_ruid = ncd.ncd_authuid;
}
setreuid(ncd.ncd_authuid, 0);
- if (krb_mk_req(&kt, "rcmd", inst, realm, 0) ==
- KSUCCESS &&
- kt.length <= (RPCAUTH_MAXSIZ - 2 * NFSX_UNSIGNED)) {
- ncd.ncd_authtype = RPCAUTH_NQNFS;
- ncd.ncd_authlen = kt.length;
- ncd.ncd_authstr = (char *)kt.dat;
- nfssvc_flag = NFSSVC_MNTD | NFSSVC_GOTAUTH;
+ kret = krb_get_cred(NFS_KERBSRV, inst, realm, &kcr);
+ if (kret == RET_NOTKT) {
+ kret = get_ad_tkt(NFS_KERBSRV, inst, realm,
+ DEFAULT_TKT_LIFE);
+ if (kret == KSUCCESS)
+ kret = krb_get_cred(NFS_KERBSRV, inst, realm,
+ &kcr);
+ }
+ if (kret == KSUCCESS)
+ kret = krb_mk_req(&ktick.kt, NFS_KERBSRV, inst,
+ realm, 0);
+
+ /*
+ * Fill in the AKN_FULLNAME authenticator and verfier.
+ * Along with the Kerberos ticket, we need to build
+ * the timestamp verifier and encrypt it in CBC mode.
+ */
+ if (kret == KSUCCESS &&
+ ktick.kt.length <= (RPCAUTH_MAXSIZ-3*NFSX_UNSIGNED)
+ && gettimeofday(&ktv, (struct timezone *)0) == 0) {
+ ncd.ncd_authtype = RPCAUTH_KERB4;
+ ncd.ncd_authstr = (u_char *)&ktick;
+ ncd.ncd_authlen = nfsm_rndup(ktick.kt.length) +
+ 3 * NFSX_UNSIGNED;
+ ncd.ncd_verfstr = (u_char *)&kverf;
+ ncd.ncd_verflen = sizeof (kverf);
+ memmove(ncd.ncd_key, kcr.session,
+ sizeof (kcr.session));
+ kin.t1 = htonl(ktv.tv_sec);
+ kin.t2 = htonl(ktv.tv_usec);
+ kin.w1 = htonl(NFS_KERBTTL);
+ kin.w2 = htonl(NFS_KERBTTL - 1);
+ bzero((caddr_t)kivec, sizeof (kivec));
+
+ /*
+ * Encrypt kin in CBC mode using the session
+ * key in kcr.
+ */
+ XXX
+
+ /*
+ * Finally, fill the timestamp verifier into the
+ * authenticator and verifier.
+ */
+ ktick.kind = htonl(RPCAKN_FULLNAME);
+ kverf.kind = htonl(RPCAKN_FULLNAME);
+ NFS_KERBW1(ktick.kt) = kout.w1;
+ ktick.kt.length = htonl(ktick.kt.length);
+ kverf.verf.t1 = kout.t1;
+ kverf.verf.t2 = kout.t2;
+ kverf.verf.w2 = kout.w2;
+ nfssvc_flag = NFSSVC_MNTD | NFSSVC_GOTAUTH;
}
setreuid(0, 0);
-#endif /* KERBEROS */
+#endif /* NFSKERB */
}
}
exit(0);
@@ -362,9 +508,9 @@ getnfsargs(spec, nfsargsp)
#endif
struct timeval pertry, try;
enum clnt_stat clnt_stat;
- int so = RPC_ANYSOCK, i;
+ int so = RPC_ANYSOCK, i, nfsvers, mntvers;
char *hostp, *delimp;
-#ifdef KERBEROS
+#ifdef NFSKERB
char *cp;
#endif
u_short tport;
@@ -402,14 +548,13 @@ getnfsargs(spec, nfsargsp)
warnx("bad ISO address");
return (0);
}
- bzero((caddr_t)&isoaddr, sizeof (isoaddr));
- bcopy((caddr_t)isop, (caddr_t)&isoaddr.siso_addr,
- sizeof (struct iso_addr));
+ memset(&isoaddr, 0, sizeof (isoaddr));
+ memmove(&isoaddr.siso_addr, isop, sizeof (struct iso_addr));
isoaddr.siso_len = sizeof (isoaddr);
isoaddr.siso_family = AF_ISO;
isoaddr.siso_tlen = 2;
isoport = htons(NFS_PORT);
- bcopy((caddr_t)&isoport, TSEL(&isoaddr), isoaddr.siso_tlen);
+ memmove(TSEL(&isoaddr), &isoport, isoaddr.siso_tlen);
hostp = delimp + 1;
}
#endif /* ISO */
@@ -423,46 +568,64 @@ getnfsargs(spec, nfsargsp)
warnx("bad net address %s", hostp);
return (0);
}
- if ((nfsargsp->flags & NFSMNT_KERB) &&
- (hp = gethostbyaddr((char *)&saddr.sin_addr.s_addr,
+ } else if ((hp = gethostbyname(hostp)) != NULL)
+ memmove(&saddr.sin_addr, hp->h_addr, hp->h_length);
+ else {
+ warnx("can't get net id for host");
+ return (0);
+ }
+#ifdef NFSKERB
+ if ((nfsargsp->flags & NFSMNT_KERB)) {
+ if ((hp = gethostbyaddr((char *)&saddr.sin_addr.s_addr,
sizeof (u_long), AF_INET)) == (struct hostent *)0) {
warnx("can't reverse resolve net address");
return (0);
}
- } else if ((hp = gethostbyname(hostp)) == NULL) {
- warnx("can't get net id for host");
- return (0);
- }
-#ifdef KERBEROS
- if (nfsargsp->flags & NFSMNT_KERB) {
+ memmove(&saddr.sin_addr, hp->h_addr, hp->h_length);
strncpy(inst, hp->h_name, INST_SZ);
inst[INST_SZ - 1] = '\0';
if (cp = strchr(inst, '.'))
*cp = '\0';
}
-#endif /* KERBEROS */
+#endif /* NFSKERB */
- bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length);
+ if (nfsargsp->flags & NFSMNT_NFSV3) {
+ nfsvers = 3;
+ mntvers = 3;
+ } else {
+ nfsvers = 2;
+ mntvers = 1;
+ }
nfhret.stat = EACCES; /* Mark not yet successful */
while (retrycnt > 0) {
saddr.sin_family = AF_INET;
saddr.sin_port = htons(PMAPPORT);
if ((tport = pmap_getport(&saddr, RPCPROG_NFS,
- NFS_VER2, IPPROTO_UDP)) == 0) {
+ nfsvers, nfsproto)) == 0) {
if ((opflags & ISBGRND) == 0)
clnt_pcreateerror("NFS Portmap");
} else {
saddr.sin_port = 0;
pertry.tv_sec = 10;
pertry.tv_usec = 0;
- if ((clp = clntudp_create(&saddr, RPCPROG_MNT,
- RPCMNT_VER1, pertry, &so)) == NULL) {
+ if (mnttcp_ok && nfsargsp->sotype == SOCK_STREAM)
+ clp = clnttcp_create(&saddr, RPCPROG_MNT, mntvers,
+ &so, 0, 0);
+ else
+ clp = clntudp_create(&saddr, RPCPROG_MNT, mntvers,
+ pertry, &so);
+ if (clp == NULL) {
if ((opflags & ISBGRND) == 0)
clnt_pcreateerror("Cannot MNT PRC");
} else {
clp->cl_auth = authunix_create_default();
try.tv_sec = 10;
try.tv_usec = 0;
+ if (nfsargsp->flags & NFSMNT_KERB)
+ nfhret.auth = RPCAUTH_KERB4;
+ else
+ nfhret.auth = RPCAUTH_UNIX;
+ nfhret.vers = mntvers;
clnt_stat = clnt_call(clp, RPCMNT_MOUNT,
xdr_dir, spec, xdr_fh, &nfhret, try);
if (clnt_stat != RPC_SUCCESS) {
@@ -497,7 +660,7 @@ getnfsargs(spec, nfsargsp)
if (nfhret.stat) {
if (opflags & ISBGRND)
exit(1);
- warn("can't access %s", spec);
+ warnx("can't access %s: %s", spec, strerror(nfhret.stat));
return (0);
}
saddr.sin_port = htons(tport);
@@ -511,7 +674,8 @@ getnfsargs(spec, nfsargsp)
nfsargsp->addr = (struct sockaddr *) &saddr;
nfsargsp->addrlen = sizeof (saddr);
}
- nfsargsp->fh = &nfhret.nfh;
+ nfsargsp->fh = nfhret.nfh;
+ nfsargsp->fhsize = nfhret.fhsize;
nfsargsp->hostname = nam;
return (1);
}
@@ -530,13 +694,43 @@ xdr_dir(xdrsp, dirp)
int
xdr_fh(xdrsp, np)
XDR *xdrsp;
- struct nfhret *np;
+ register struct nfhret *np;
{
- if (!xdr_u_long(xdrsp, &(np->stat)))
+ register int i;
+ long auth, authcnt, authfnd = 0;
+
+ if (!xdr_u_long(xdrsp, &np->stat))
return (0);
if (np->stat)
return (1);
- return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH));
+ switch (np->vers) {
+ case 1:
+ np->fhsize = NFSX_V2FH;
+ return (xdr_opaque(xdrsp, (caddr_t)np->nfh, NFSX_V2FH));
+ case 3:
+ if (!xdr_long(xdrsp, &np->fhsize))
+ return (0);
+ if (np->fhsize <= 0 || np->fhsize > NFSX_V3FHMAX)
+ return (0);
+ if (!xdr_opaque(xdrsp, (caddr_t)np->nfh, np->fhsize))
+ return (0);
+ if (!xdr_long(xdrsp, &authcnt))
+ return (0);
+ for (i = 0; i < authcnt; i++) {
+ if (!xdr_long(xdrsp, &auth))
+ return (0);
+ if (auth == np->auth)
+ authfnd++;
+ }
+ /*
+ * Some servers, such as DEC's OSF/1 return a nil authenticator
+ * list to indicate RPCAUTH_UNIX.
+ */
+ if (!authfnd && (authcnt > 0 || np->auth != RPCAUTH_UNIX))
+ np->stat = EAUTH;
+ return (1);
+ };
+ return (0);
}
__dead void
diff --git a/sbin/mount_null/mount_null.8 b/sbin/mount_null/mount_null.8
index 6c8106f..1bdc04f 100644
--- a/sbin/mount_null/mount_null.8
+++ b/sbin/mount_null/mount_null.8
@@ -34,15 +34,16 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)mount_null.8 8.4 (Berkeley) 4/19/94
+.\" @(#)mount_null.8 8.6 (Berkeley) 5/1/95
.\"
.\"
-.Dd April 19, 1994
+.Dd May 1, 1995
.Dt MOUNT_NULL 8
.Os BSD 4.4
.Sh NAME
.Nm mount_null
-.Nd demonstrate the use of a null file system layer
+.Nd mount a loopback filesystem sub-tree;
+demonstrate the use of a null file system layer
.Sh SYNOPSIS
.Nm mount_null
.Op Fl o Ar options
@@ -54,11 +55,22 @@ The
command creates a
null layer, duplicating a sub-tree of the file system
name space under another part of the global file system namespace.
-In this respect, it is
-similar to the loopback file system (see
-.Xr mount_lofs 8 ) .
-It differs from
-the loopback file system in two respects: it is implemented using
+This allows existing files and directories to be accessed
+using a different pathname.
+.Pp
+The primary differences between a virtual copy of the filesystem
+and a symbolic link are that
+.Xr getcwd 3
+functions correctly in the virtual copy, and that other filesystems
+may be mounted on the virtual copy without affecting the original.
+A different device number for the virtual copy is returned by
+.Xr stat 2 ,
+but in other respects it is indistinguishable from the original.
+.Pp
+The
+.Nm mount_null
+filesystem differs from a traditional
+loopback file system in two respects: it is implemented using
a stackable layers techniques, and it's
.Do
null-node
diff --git a/sbin/mount_null/mount_null.c b/sbin/mount_null/mount_null.c
index e8c26df..f7568b6 100644
--- a/sbin/mount_null/mount_null.c
+++ b/sbin/mount_null/mount_null.c
@@ -41,7 +41,7 @@ char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_null.c 8.5 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_null.c 8.6 (Berkeley) 4/26/95";
#endif /* not lint */
#include <sys/param.h>
@@ -77,7 +77,7 @@ main(argc, argv)
while ((ch = getopt(argc, argv, "o:")) != EOF)
switch(ch) {
case 'o':
- getmntopts(optarg, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, 0);
break;
case '?':
default:
@@ -98,7 +98,7 @@ main(argc, argv)
args.target = target;
- if (mount(MOUNT_NULL, argv[1], mntflags, &args))
+ if (mount("loopback", argv[1], mntflags, &args))
err(1, NULL);
exit(0);
}
diff --git a/sbin/mount_portal/activate.c b/sbin/mount_portal/activate.c
index 3361798..b6d3971 100644
--- a/sbin/mount_portal/activate.c
+++ b/sbin/mount_portal/activate.c
@@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)activate.c 8.2 (Berkeley) 3/27/94
+ * @(#)activate.c 8.3 (Berkeley) 4/28/95
*
* $Id: activate.c,v 1.2 1992/05/27 07:09:27 jsp Exp jsp $
*/
@@ -89,7 +89,7 @@ int klen;
iov[1].iov_base = key;
iov[1].iov_len = klen;
- bzero((char *) &msg, sizeof(msg));
+ memset(&msg, 0, sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = 2;
@@ -129,7 +129,7 @@ int error;
/*
* Build a msghdr
*/
- bzero((char *) &msg, sizeof(msg));
+ memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
diff --git a/sbin/mount_portal/mount_portal.c b/sbin/mount_portal/mount_portal.c
index ae5345d..ad6d041 100644
--- a/sbin/mount_portal/mount_portal.c
+++ b/sbin/mount_portal/mount_portal.c
@@ -41,7 +41,7 @@ char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_portal.c 8.4 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_portal.c 8.6 (Berkeley) 4/26/95";
#endif /* not lint */
#include <sys/param.h>
@@ -79,7 +79,7 @@ int sig;
while ((pid = waitpid((pid_t) -1, (int *) 0, WNOHANG)) > 0)
;
- if (pid < 0)
+ if (pid < 0 && errno != ECHILD)
syslog(LOG_WARNING, "waitpid: %s", strerror(errno));
}
@@ -108,7 +108,7 @@ main(argc, argv)
while ((ch = getopt(argc, argv, "o:")) != EOF) {
switch (ch) {
case 'o':
- getmntopts(optarg, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, 0);
break;
default:
error = 1;
@@ -156,16 +156,14 @@ main(argc, argv)
sprintf(tag, "portal:%d", getpid());
args.pa_config = tag;
- rc = mount(MOUNT_PORTAL, mountpt, mntflags, &args);
+ rc = mount("portal", mountpt, mntflags, &args);
if (rc < 0)
err(1, NULL);
-#ifdef notdef
/*
* Everything is ready to go - now is a good time to fork
*/
daemon(0, 0);
-#endif
/*
* Start logging (and change name)
@@ -242,7 +240,7 @@ main(argc, argv)
case 0:
(void) close(so);
activate(&q, so2);
- break;
+ exit(0);
default:
(void) close(so2);
break;
diff --git a/sbin/mount_portal/pt_file.c b/sbin/mount_portal/pt_file.c
index ace35c0..1d8e594 100644
--- a/sbin/mount_portal/pt_file.c
+++ b/sbin/mount_portal/pt_file.c
@@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)pt_file.c 8.2 (Berkeley) 3/27/94
+ * @(#)pt_file.c 8.3 (Berkeley) 7/3/94
*
* $Id: pt_file.c,v 1.1 1992/05/25 21:43:09 jsp Exp jsp $
*/
@@ -61,7 +61,7 @@ int *fdp;
int fd;
char pbuf[MAXPATHLEN];
int error;
- int gidset[NGROUPS];
+ gid_t gidset[NGROUPS];
int i;
pbuf[0] = '/';
diff --git a/sbin/mount_portal/pt_tcp.c b/sbin/mount_portal/pt_tcp.c
index 18a53ce..47ca7bf 100644
--- a/sbin/mount_portal/pt_tcp.c
+++ b/sbin/mount_portal/pt_tcp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1992, 1993
+ * Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
@@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)pt_tcp.c 8.3 (Berkeley) 3/27/94
+ * @(#)pt_tcp.c 8.5 (Berkeley) 4/28/95
*
* $Id: pt_tcp.c,v 1.1 1992/05/25 21:43:09 jsp Exp jsp $
*/
@@ -62,11 +62,11 @@
* An unrecognised suffix is an error.
*/
int portal_tcp(pcr, key, v, kso, fdp)
-struct portal_cred *pcr;
-char *key;
-char **v;
-int kso;
-int *fdp;
+ struct portal_cred *pcr;
+ char *key;
+ char **v;
+ int kso;
+ int *fdp;
{
char host[MAXHOSTNAMELEN];
char port[MAXHOSTNAMELEN];
@@ -122,12 +122,13 @@ int *fdp;
if (sp != 0)
s_port = sp->s_port;
else {
- s_port = atoi(port);
- if (s_port == 0)
+ s_port = strtoul(port, &p, 0);
+ if (s_port == 0 || *p != '\0')
return (EINVAL);
+ s_port = htons(s_port);
}
- bzero(&sain, sizeof(sain));
+ memset(&sain, 0, sizeof(sain));
sain.sin_len = sizeof(sain);
sain.sin_family = AF_INET;
sain.sin_port = s_port;
diff --git a/sbin/mount_procfs/mount_procfs.8 b/sbin/mount_procfs/mount_procfs.8
index 3aa20e0..db0eeab 100644
--- a/sbin/mount_procfs/mount_procfs.8
+++ b/sbin/mount_procfs/mount_procfs.8
@@ -34,10 +34,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)mount_procfs.8 8.2 (Berkeley) 3/27/94
+.\" @(#)mount_procfs.8 8.3 (Berkeley) 6/1/94
.\"
.\"
-.Dd March 27, 1994
+.Dd June 1, 1994
.Dt MOUNT_PROCFS 8
.Os BSD 4.4
.Sh NAME
@@ -136,6 +136,7 @@ defined in
.Pa <machine/reg.h> .
.Pa regs
can only be written when the process is stopped.
+.ne 1i
.It Pa fpregs
The floating point registers as defined by
.Dv "struct fpregs"
diff --git a/sbin/mount_procfs/mount_procfs.c b/sbin/mount_procfs/mount_procfs.c
index 79016c8..7e0f187 100644
--- a/sbin/mount_procfs/mount_procfs.c
+++ b/sbin/mount_procfs/mount_procfs.c
@@ -42,7 +42,7 @@ char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_procfs.c 8.3 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_procfs.c 8.4 (Berkeley) 4/26/95";
#endif /* not lint */
#include <sys/param.h>
@@ -74,7 +74,7 @@ main(argc, argv)
while ((ch = getopt(argc, argv, "o:")) != EOF)
switch (ch) {
case 'o':
- getmntopts(optarg, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, 0);
break;
case '?':
default:
@@ -86,7 +86,7 @@ main(argc, argv)
if (argc != 2)
usage();
- if (mount(MOUNT_PROCFS, argv[1], mntflags, NULL))
+ if (mount("procfs", argv[1], mntflags, NULL))
err(1, NULL);
exit(0);
}
diff --git a/sbin/mount_umap/mount_umap.8 b/sbin/mount_umap/mount_umap.8
index e90ce26..54df401 100644
--- a/sbin/mount_umap/mount_umap.8
+++ b/sbin/mount_umap/mount_umap.8
@@ -33,9 +33,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)mount_umap.8 8.3 (Berkeley) 3/27/94
+.\" @(#)mount_umap.8 8.4 (Berkeley) 5/1/95
.\"
-.Dd "March 27, 1994"
+.Dd "May 1, 1995"
.Dt MOUNT_UMAP 8
.Os BSD 4.4
.Sh NAME
@@ -123,8 +123,7 @@ It is not meant for production use. The implementation is not very
sophisticated.
.Sh SEE ALSO
.Xr mount 8 ,
-.Xr mount_null 8 ,
-.Xr mount_lofs 8
+.Xr mount_null 8
.Sh HISTORY
The
.Nm mount_umap
diff --git a/sbin/mount_umap/mount_umap.c b/sbin/mount_umap/mount_umap.c
index a069fe5..fb8349c 100644
--- a/sbin/mount_umap/mount_umap.c
+++ b/sbin/mount_umap/mount_umap.c
@@ -41,7 +41,7 @@ char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_umap.c 8.3 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_umap.c 8.5 (Berkeley) 4/26/95";
#endif /* not lint */
#include <sys/param.h>
@@ -104,7 +104,7 @@ main(argc, argv)
gmapfile = optarg;
break;
case 'o':
- getmntopts(optarg, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, 0);
break;
case 'u':
mapfile = optarg;
@@ -189,7 +189,7 @@ main(argc, argv)
errx(1, "%s does not belong to root%s", gmapfile, not);
#endif /* MAPSECURITY */
- if ((fscanf(fp, "%d\n", &gnentries)) != 1)
+ if ((fscanf(gfp, "%d\n", &gnentries)) != 1)
errx(1, "nentries not found%s", gmapfile, not);
if (gnentries > MAPFILEENTRIES)
errx(1,
@@ -199,11 +199,11 @@ main(argc, argv)
#endif
for (count = 0; count < gnentries; ++count)
- if ((fscanf(fp, "%lu %lu\n",
+ if ((fscanf(gfp, "%lu %lu\n",
&(gmapdata[count][0]), &(gmapdata[count][1]))) != 2) {
- if (ferror(fp))
+ if (ferror(gfp))
err(1, "%s%s", gmapfile, not);
- if (feof(fp))
+ if (feof(gfp))
errx(1, "%s: unexpected end-of-file%s",
gmapfile, not);
errx(1, "%s: illegal format (line %d)%s",
@@ -218,7 +218,7 @@ main(argc, argv)
args.gnentries = gnentries;
args.gmapdata = gmapdata;
- if (mount(MOUNT_UMAP, argv[1], mntflags, &args))
+ if (mount("umap", argv[1], mntflags, &args))
err(1, NULL);
exit(0);
}
diff --git a/sbin/mount_union/Makefile b/sbin/mount_union/Makefile
index a6b33af..d2f4e23 100644
--- a/sbin/mount_union/Makefile
+++ b/sbin/mount_union/Makefile
@@ -1,4 +1,4 @@
-# @(#)Makefile 8.3 (Berkeley) 3/27/94
+# @(#)Makefile 8.4 (Berkeley) 7/13/94
PROG= mount_union
SRCS= mount_union.c getmntopts.c
@@ -8,7 +8,4 @@ MOUNT= ${.CURDIR}/../mount
CFLAGS+= -I/sys -I${MOUNT}
.PATH: ${MOUNT}
-BINOWN= root
-BINMODE=4555
-
.include <bsd.prog.mk>
diff --git a/sbin/mount_union/mount_union.8 b/sbin/mount_union/mount_union.8
index 65a6497..93b191e 100644
--- a/sbin/mount_union/mount_union.8
+++ b/sbin/mount_union/mount_union.8
@@ -32,9 +32,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)mount_union.8 8.6 (Berkeley) 3/27/94
+.\" @(#)mount_union.8 8.7 (Berkeley) 5/1/95
.\"
-.Dd March 27, 1994
+.Dd May 1, 1995
.Dt MOUNT_UNION 8
.Os BSD 4.4
.Sh NAME
@@ -85,8 +85,6 @@ See the
man page for possible options and their meanings.
.It Fl r
Hide the lower layer completely in the same way as mounting with
-.Xr mount_lofs 8
-or
.Xr mount_null 8 .
.El
.Pp
@@ -182,7 +180,6 @@ accessible via
.Xr unmount 2 ,
.Xr fstab 5 ,
.Xr mount 8 ,
-.Xr mount_lofs 8 ,
.Xr mount_null 8
.Sh BUGS
Without whiteout support from the filesystem backing the upper layer,
diff --git a/sbin/mount_union/mount_union.c b/sbin/mount_union/mount_union.c
index 90d075b..971da64 100644
--- a/sbin/mount_union/mount_union.c
+++ b/sbin/mount_union/mount_union.c
@@ -41,7 +41,7 @@ char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)mount_union.c 8.5 (Berkeley) 3/27/94";
+static char sccsid[] = "@(#)mount_union.c 8.6 (Berkeley) 4/26/95";
#endif /* not lint */
#include <sys/param.h>
@@ -83,7 +83,7 @@ main(argc, argv)
args.mntflags |= UNMNT_BELOW;
break;
case 'o':
- getmntopts(optarg, mopts, &mntflags);
+ getmntopts(optarg, mopts, &mntflags, 0);
break;
case 'r':
args.mntflags &= ~UNMNT_OPMASK;
@@ -109,7 +109,7 @@ main(argc, argv)
args.target = target;
- if (mount(MOUNT_UNION, argv[1], mntflags, &args))
+ if (mount("union", argv[1], mntflags, &args))
err(1, NULL);
exit(0);
}
diff --git a/sbin/mountd/exports.5 b/sbin/mountd/exports.5
index d32527f..f4ae166 100644
--- a/sbin/mountd/exports.5
+++ b/sbin/mountd/exports.5
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)exports.5 8.2 (Berkeley) 1/28/94
+.\" @(#)exports.5 8.3 (Berkeley) 3/29/95
.\"
-.Dd January 28, 1994
+.Dd March 29, 1995
.Dt EXPORTS 5
.Os
.Sh NAME
@@ -49,7 +49,9 @@ file specifies remote mount points for the
mount protocol per the
.Tn NFS
server specification; see
-.%T "Network File System Protocol Specification \\*(tNRFC\\*(sP 1094, Appendix A" .
+.%T "Network File System Protocol Specification \\*(tNRFC\\*(sP 1094, Appendix A"
+and
+.%T "NFS: Network File System Version 3 Specification, Appendix I" .
.Pp
Each line in the file
(other than comment lines that begin with a #)
@@ -71,7 +73,10 @@ The second is to specify the pathname of the root of the filesystem
followed by the
.Fl alldirs
flag;
-this form allows the host(s) to mount any directory within the filesystem.
+this form allows the host(s) to mount at any point within the filesystem,
+including regular files if the
+.Fl r
+option is used on mountd.
The pathnames must not have any symbolic links in them and should not have
any "." or ".." components.
Mount points for a filesystem may appear on multiple lines each with
@@ -140,8 +145,7 @@ The
.Fl kerb
option specifies that the Kerberos authentication server should be
used to authenticate and map client credentials.
-(Note that this is NOT Sun NFS compatible and
-is supported for TCP transport only.)
+This option requires that the kernel be built with the NFSKERB option.
.Pp
The
.Fl ro
diff --git a/sbin/mountd/mountd.8 b/sbin/mountd/mountd.8
index 47a6cfc..c6adaca 100644
--- a/sbin/mountd/mountd.8
+++ b/sbin/mountd/mountd.8
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)mountd.8 8.1 (Berkeley) 6/9/93
+.\" @(#)mountd.8 8.4 (Berkeley) 4/28/95
.\"
-.Dd June 9, 1993
+.Dd April 28, 1995
.Dt MOUNTD 8
.Os
.Sh NAME
@@ -41,7 +41,7 @@
mount requests
.Sh SYNOPSIS
.Nm /sbin/mountd
-.Op Fl n
+.Op Fl nr
.Op Ar exportsfile
.Sh DESCRIPTION
.Xr Mountd
@@ -53,7 +53,9 @@ listens for service requests at the port indicated in the
.Tn NFS
server specification; see
.%T "Network File System Protocol Specification" ,
-RFC1094.
+RFC1094, Appendix A and
+.%T "NFS: Network File System Version 3 Protocol Specification" ,
+Appendix I.
.Pp
Options and operands available for
.Nm mountd :
@@ -64,6 +66,19 @@ The
option allows non-root mount requests to be served.
This should only be specified if there are clients such as PC's,
that require it.
+.It Fl r
+The
+.Fl r
+option allows mount RPCs requests for regular files to be served.
+Although this seems to violate the mount protocol specification,
+some diskless workstations do mount requests for
+their swapfiles and expect them to be regular files.
+Since a regular file cannot be specified in
+.Pa /etc/exports ,
+the entire file system in which the swapfiles resides
+will have to be exported with the
+.Fl alldirs
+flag.
.It Ar exportsfile
The
.Ar exportsfile
@@ -78,7 +93,7 @@ After changing the exports file,
a hangup signal should be sent to the mountd daemon
to get it to reload the export information.
After sending the SIGHUP
-(kill -HUP `cat /var/run/mountd.pid`),
+(kill \-s HUP `cat /var/run/mountd.pid`),
check the syslog output to see if mountd logged any parsing
errors in the exports file.
.Sh FILES
diff --git a/sbin/mountd/mountd.c b/sbin/mountd/mountd.c
index d7c31df..7067909 100644
--- a/sbin/mountd/mountd.c
+++ b/sbin/mountd/mountd.c
@@ -41,7 +41,7 @@ static char copyright[] =
#endif not lint
#ifndef lint
-static char sccsid[] = "@(#)mountd.c 8.8 (Berkeley) 2/20/94";
+static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95";
#endif not lint
#include <sys/param.h>
@@ -60,7 +60,9 @@ static char sccsid[] = "@(#)mountd.c 8.8 (Berkeley) 2/20/94";
#include <netiso/iso.h>
#endif
#include <nfs/rpcv2.h>
-#include <nfs/nfsv2.h>
+#include <nfs/nfsproto.h>
+#include <ufs/ufs/ufsmount.h>
+#include <sys/../isofs/cd9660/cd9660_mount.h> /* XXX need isofs in include */
#include <arpa/inet.h>
@@ -98,6 +100,8 @@ struct dirlist {
};
/* dp_flag bits */
#define DP_DEFSET 0x1
+#define DP_HOSTSET 0x2
+#define DP_KERB 0x4
struct exportlist {
struct exportlist *ex_next;
@@ -136,22 +140,29 @@ struct grouplist {
#define GT_ISO 0x4
struct hostlist {
+ int ht_flag; /* Uses DP_xx bits */
struct grouplist *ht_grp;
struct hostlist *ht_next;
};
+struct fhreturn {
+ int fhr_flag;
+ int fhr_vers;
+ nfsfh_t fhr_fh;
+};
+
/* Global defs */
char *add_expdir __P((struct dirlist **, char *, int));
void add_dlist __P((struct dirlist **, struct dirlist *,
- struct grouplist *));
+ struct grouplist *, int));
void add_mlist __P((char *, char *));
int check_dirpath __P((char *));
int check_options __P((struct dirlist *));
-int chk_host __P((struct dirlist *, u_long, int *));
+int chk_host __P((struct dirlist *, u_long, int *, int *));
void del_mlist __P((char *, char *));
struct dirlist *dirp_search __P((struct dirlist *, char *));
int do_mount __P((struct exportlist *, struct grouplist *, int,
- struct ucred *, char *, int, struct statfs *));
+ struct ucred *, char *, int, struct statfs *));
int do_opt __P((char **, char **, struct exportlist *, struct grouplist *,
int *, int *, struct ucred *));
struct exportlist *ex_search __P((fsid_t *));
@@ -162,6 +173,7 @@ void free_grp __P((struct grouplist *));
void free_host __P((struct hostlist *));
void get_exportlist __P((void));
int get_host __P((char *, struct grouplist *));
+int get_num __P((char *));
struct hostlist *get_ht __P((void));
int get_line __P((void));
void get_mountlist __P((void));
@@ -180,7 +192,7 @@ void send_umntall __P((void));
int umntall_each __P((caddr_t, struct sockaddr_in *));
int xdr_dir __P((XDR *, char *));
int xdr_explist __P((XDR *, caddr_t));
-int xdr_fhs __P((XDR *, nfsv2fh_t *));
+int xdr_fhs __P((XDR *, caddr_t));
int xdr_mlist __P((XDR *, caddr_t));
/* C library */
@@ -202,7 +214,8 @@ struct ucred def_anon = {
1,
{ (gid_t) -2 }
};
-int root_only = 1;
+int resvport_only = 1;
+int dir_only = 1;
int opt_flags;
/* Bits for above */
#define OP_MAPROOT 0x01
@@ -233,16 +246,19 @@ main(argc, argv)
int argc;
char **argv;
{
- SVCXPRT *transp;
+ SVCXPRT *udptransp, *tcptransp;
int c;
- while ((c = getopt(argc, argv, "n")) != EOF)
+ while ((c = getopt(argc, argv, "nr")) != EOF)
switch (c) {
case 'n':
- root_only = 0;
+ resvport_only = 0;
+ break;
+ case 'r':
+ dir_only = 0;
break;
default:
- fprintf(stderr, "Usage: mountd [-n] [export_file]\n");
+ fprintf(stderr, "Usage: mountd [-r] [-n] [export_file]\n");
exit(1);
};
argc -= optind;
@@ -277,13 +293,17 @@ main(argc, argv)
fclose(pidfile);
}
}
- if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL) {
+ if ((udptransp = svcudp_create(RPC_ANYSOCK)) == NULL ||
+ (tcptransp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL) {
syslog(LOG_ERR, "Can't create socket");
exit(1);
}
- pmap_unset(RPCPROG_MNT, RPCMNT_VER1);
- if (!svc_register(transp, RPCPROG_MNT, RPCMNT_VER1, mntsrv,
- IPPROTO_UDP)) {
+ pmap_unset(RPCPROG_MNT, 1);
+ pmap_unset(RPCPROG_MNT, 3);
+ if (!svc_register(udptransp, RPCPROG_MNT, 1, mntsrv, IPPROTO_UDP) ||
+ !svc_register(udptransp, RPCPROG_MNT, 3, mntsrv, IPPROTO_UDP) ||
+ !svc_register(tcptransp, RPCPROG_MNT, 1, mntsrv, IPPROTO_TCP) ||
+ !svc_register(tcptransp, RPCPROG_MNT, 3, mntsrv, IPPROTO_TCP)) {
syslog(LOG_ERR, "Can't register mount");
exit(1);
}
@@ -302,28 +322,20 @@ mntsrv(rqstp, transp)
{
struct exportlist *ep;
struct dirlist *dp;
- nfsv2fh_t nfh;
- struct authunix_parms *ucr;
+ struct fhreturn fhr;
struct stat stb;
struct statfs fsb;
struct hostent *hp;
u_long saddr;
- char rpcpath[RPCMNT_PATHLEN+1], dirpath[MAXPATHLEN];
- int bad = ENOENT, omask, defset;
- uid_t uid = -2;
-
- /* Get authorization */
- switch (rqstp->rq_cred.oa_flavor) {
- case AUTH_UNIX:
- ucr = (struct authunix_parms *)rqstp->rq_clntcred;
- uid = ucr->aup_uid;
- break;
- case AUTH_NULL:
- default:
- break;
- }
+ u_short sport;
+ char rpcpath[RPCMNT_PATHLEN + 1], dirpath[MAXPATHLEN];
+ int bad = ENOENT, defset, hostset;
+ sigset_t sighup_mask;
+ sigemptyset(&sighup_mask);
+ sigaddset(&sighup_mask, SIGHUP);
saddr = transp->xp_raddr.sin_addr.s_addr;
+ sport = ntohs(transp->xp_raddr.sin_port);
hp = (struct hostent *)NULL;
switch (rqstp->rq_proc) {
case NULLPROC:
@@ -331,7 +343,7 @@ mntsrv(rqstp, transp)
syslog(LOG_ERR, "Can't send reply");
return;
case RPCMNT_MOUNT:
- if ((uid != 0 && root_only) || uid == -2) {
+ if (sport >= IPPORT_RESERVED && resvport_only) {
svcerr_weakauth(transp);
return;
}
@@ -342,11 +354,13 @@ mntsrv(rqstp, transp)
/*
* Get the real pathname and make sure it is a directory
- * that exists.
+ * or a regular file if the -r option was specified
+ * and it exists.
*/
if (realpath(rpcpath, dirpath) == 0 ||
stat(dirpath, &stb) < 0 ||
- (stb.st_mode & S_IFMT) != S_IFDIR ||
+ (!S_ISDIR(stb.st_mode) &&
+ (dir_only || !S_ISREG(stb.st_mode))) ||
statfs(dirpath, &fsb) < 0) {
chdir("/"); /* Just in case realpath doesn't */
if (debug)
@@ -357,26 +371,31 @@ mntsrv(rqstp, transp)
}
/* Check in the exports list */
- omask = sigblock(sigmask(SIGHUP));
+ sigprocmask(SIG_BLOCK, &sighup_mask, NULL);
ep = ex_search(&fsb.f_fsid);
- defset = 0;
- if (ep && (chk_host(ep->ex_defdir, saddr, &defset) ||
+ hostset = defset = 0;
+ if (ep && (chk_host(ep->ex_defdir, saddr, &defset, &hostset) ||
((dp = dirp_search(ep->ex_dirl, dirpath)) &&
- chk_host(dp, saddr, &defset)) ||
+ chk_host(dp, saddr, &defset, &hostset)) ||
(defset && scan_tree(ep->ex_defdir, saddr) == 0 &&
scan_tree(ep->ex_dirl, saddr) == 0))) {
+ if (hostset & DP_HOSTSET)
+ fhr.fhr_flag = hostset;
+ else
+ fhr.fhr_flag = defset;
+ fhr.fhr_vers = rqstp->rq_vers;
/* Get the file handle */
- bzero((caddr_t)&nfh, sizeof(nfh));
- if (getfh(dirpath, (fhandle_t *)&nfh) < 0) {
+ memset(&fhr.fhr_fh, 0, sizeof(nfsfh_t));
+ if (getfh(dirpath, (fhandle_t *)&fhr.fhr_fh) < 0) {
bad = errno;
syslog(LOG_ERR, "Can't get fh for %s", dirpath);
if (!svc_sendreply(transp, xdr_long,
(caddr_t)&bad))
syslog(LOG_ERR, "Can't send reply");
- sigsetmask(omask);
+ sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
return;
}
- if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&nfh))
+ if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&fhr))
syslog(LOG_ERR, "Can't send reply");
if (hp == NULL)
hp = gethostbyaddr((caddr_t)&saddr,
@@ -393,14 +412,14 @@ mntsrv(rqstp, transp)
if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
syslog(LOG_ERR, "Can't send reply");
}
- sigsetmask(omask);
+ sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
return;
case RPCMNT_DUMP:
if (!svc_sendreply(transp, xdr_mlist, (caddr_t)NULL))
syslog(LOG_ERR, "Can't send reply");
return;
case RPCMNT_UMOUNT:
- if ((uid != 0 && root_only) || uid == -2) {
+ if (sport >= IPPORT_RESERVED && resvport_only) {
svcerr_weakauth(transp);
return;
}
@@ -416,7 +435,7 @@ mntsrv(rqstp, transp)
del_mlist(inet_ntoa(transp->xp_raddr.sin_addr), dirpath);
return;
case RPCMNT_UMNTALL:
- if ((uid != 0 && root_only) || uid == -2) {
+ if (sport >= IPPORT_RESERVED && resvport_only) {
svcerr_weakauth(transp);
return;
}
@@ -449,18 +468,37 @@ xdr_dir(xdrsp, dirp)
}
/*
- * Xdr routine to generate fhstatus
+ * Xdr routine to generate file handle reply
*/
int
-xdr_fhs(xdrsp, nfh)
+xdr_fhs(xdrsp, cp)
XDR *xdrsp;
- nfsv2fh_t *nfh;
+ caddr_t cp;
{
- int ok = 0;
+ register struct fhreturn *fhrp = (struct fhreturn *)cp;
+ long ok = 0, len, auth;
if (!xdr_long(xdrsp, &ok))
return (0);
- return (xdr_opaque(xdrsp, (caddr_t)nfh, NFSX_FH));
+ switch (fhrp->fhr_vers) {
+ case 1:
+ return (xdr_opaque(xdrsp, (caddr_t)&fhrp->fhr_fh, NFSX_V2FH));
+ case 3:
+ len = NFSX_V3FH;
+ if (!xdr_long(xdrsp, &len))
+ return (0);
+ if (!xdr_opaque(xdrsp, (caddr_t)&fhrp->fhr_fh, len))
+ return (0);
+ if (fhrp->fhr_flag & DP_KERB)
+ auth = RPCAUTH_KERB4;
+ else
+ auth = RPCAUTH_UNIX;
+ len = 1;
+ if (!xdr_long(xdrsp, &len))
+ return (0);
+ return (xdr_long(xdrsp, &auth));
+ };
+ return (0);
}
int
@@ -500,9 +538,12 @@ xdr_explist(xdrsp, cp)
{
struct exportlist *ep;
int false = 0;
- int omask, putdef;
+ int putdef;
+ sigset_t sighup_mask;
- omask = sigblock(sigmask(SIGHUP));
+ sigemptyset(&sighup_mask);
+ sigaddset(&sighup_mask, SIGHUP);
+ sigprocmask(SIG_BLOCK, &sighup_mask, NULL);
ep = exphead;
while (ep) {
putdef = 0;
@@ -514,12 +555,12 @@ xdr_explist(xdrsp, cp)
goto errout;
ep = ep->ex_next;
}
- sigsetmask(omask);
+ sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
if (!xdr_bool(xdrsp, &false))
return (0);
return (1);
errout:
- sigsetmask(omask);
+ sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
return (0);
}
@@ -631,7 +672,7 @@ get_exportlist()
* And delete exports that are in the kernel for all local
* file systems.
* XXX: Should know how to handle all local exportable file systems
- * instead of just MOUNT_UFS.
+ * instead of just "ufs".
*/
num = getmntinfo(&fsp, MNT_NOWAIT);
for (i = 0; i < num; i++) {
@@ -641,13 +682,12 @@ get_exportlist()
struct mfs_args ma;
} targs;
- switch (fsp->f_type) {
- case MOUNT_MFS:
- case MOUNT_UFS:
- case MOUNT_CD9660:
+ if (!strcmp(fsp->f_fstypename, "mfs") ||
+ !strcmp(fsp->f_fstypename, "ufs") ||
+ !strcmp(fsp->f_fstypename, "cd9660")) {
targs.ua.fspec = NULL;
targs.ua.export.ex_flags = MNT_DELEXPORT;
- if (mount(fsp->f_type, fsp->f_mntonname,
+ if (mount(fsp->f_fstypename, fsp->f_mntonname,
fsp->f_flags | MNT_UPDATE,
(caddr_t)&targs) < 0)
syslog(LOG_ERR, "Can't delete exports for %s",
@@ -783,6 +823,7 @@ get_exportlist()
if (get_host(hst, grp)) {
syslog(LOG_ERR, "Bad netgroup %s", cp);
getexp_err(ep, tgrp);
+ endnetgrent();
goto nextline;
}
} else if (get_host(cp, grp)) {
@@ -843,12 +884,12 @@ get_exportlist()
* Success. Update the data structures.
*/
if (has_host) {
- hang_dirp(dirhead, tgrp, ep, (opt_flags & OP_ALLDIRS));
+ hang_dirp(dirhead, tgrp, ep, opt_flags);
grp->gr_next = grphead;
grphead = tgrp;
} else {
hang_dirp(dirhead, (struct grouplist *)NULL, ep,
- (opt_flags & OP_ALLDIRS));
+ opt_flags);
free_grp(grp);
}
dirhead = (struct dirlist *)NULL;
@@ -888,7 +929,7 @@ get_exp()
ep = (struct exportlist *)malloc(sizeof (struct exportlist));
if (ep == (struct exportlist *)NULL)
out_of_mem();
- bzero((caddr_t)ep, sizeof (struct exportlist));
+ memset(ep, 0, sizeof(struct exportlist));
return (ep);
}
@@ -903,7 +944,7 @@ get_grp()
gp = (struct grouplist *)malloc(sizeof (struct grouplist));
if (gp == (struct grouplist *)NULL)
out_of_mem();
- bzero((caddr_t)gp, sizeof (struct grouplist));
+ memset(gp, 0, sizeof(struct grouplist));
return (gp);
}
@@ -972,24 +1013,28 @@ add_expdir(dpp, cp, len)
* and update the entry for host.
*/
void
-hang_dirp(dp, grp, ep, alldirs)
+hang_dirp(dp, grp, ep, flags)
struct dirlist *dp;
struct grouplist *grp;
struct exportlist *ep;
- int alldirs;
+ int flags;
{
struct hostlist *hp;
struct dirlist *dp2;
- if (alldirs) {
+ if (flags & OP_ALLDIRS) {
if (ep->ex_defdir)
free((caddr_t)dp);
else
ep->ex_defdir = dp;
- if (grp == (struct grouplist *)NULL)
+ if (grp == (struct grouplist *)NULL) {
ep->ex_defdir->dp_flag |= DP_DEFSET;
- else while (grp) {
+ if (flags & OP_KERB)
+ ep->ex_defdir->dp_flag |= DP_KERB;
+ } else while (grp) {
hp = get_ht();
+ if (flags & OP_KERB)
+ hp->ht_flag |= DP_KERB;
hp->ht_grp = grp;
hp->ht_next = ep->ex_defdir->dp_hosts;
ep->ex_defdir->dp_hosts = hp;
@@ -1002,7 +1047,7 @@ hang_dirp(dp, grp, ep, alldirs)
*/
while (dp) {
dp2 = dp->dp_left;
- add_dlist(&ep->ex_dirl, dp, grp);
+ add_dlist(&ep->ex_dirl, dp, grp, flags);
dp = dp2;
}
}
@@ -1013,10 +1058,11 @@ hang_dirp(dp, grp, ep, alldirs)
* for the new directory or adding the new node.
*/
void
-add_dlist(dpp, newdp, grp)
+add_dlist(dpp, newdp, grp, flags)
struct dirlist **dpp;
struct dirlist *newdp;
struct grouplist *grp;
+ int flags;
{
struct dirlist *dp;
struct hostlist *hp;
@@ -1026,10 +1072,10 @@ add_dlist(dpp, newdp, grp)
if (dp) {
cmp = strcmp(dp->dp_dirp, newdp->dp_dirp);
if (cmp > 0) {
- add_dlist(&dp->dp_left, newdp, grp);
+ add_dlist(&dp->dp_left, newdp, grp, flags);
return;
} else if (cmp < 0) {
- add_dlist(&dp->dp_right, newdp, grp);
+ add_dlist(&dp->dp_right, newdp, grp, flags);
return;
} else
free((caddr_t)newdp);
@@ -1045,13 +1091,18 @@ add_dlist(dpp, newdp, grp)
*/
do {
hp = get_ht();
+ if (flags & OP_KERB)
+ hp->ht_flag |= DP_KERB;
hp->ht_grp = grp;
hp->ht_next = dp->dp_hosts;
dp->dp_hosts = hp;
grp = grp->gr_next;
} while (grp);
- } else
+ } else {
dp->dp_flag |= DP_DEFSET;
+ if (flags & OP_KERB)
+ dp->dp_flag |= DP_KERB;
+ }
}
/*
@@ -1080,10 +1131,11 @@ dirp_search(dp, dirpath)
* Scan for a host match in a directory tree.
*/
int
-chk_host(dp, saddr, defsetp)
+chk_host(dp, saddr, defsetp, hostsetp)
struct dirlist *dp;
u_long saddr;
int *defsetp;
+ int *hostsetp;
{
struct hostlist *hp;
struct grouplist *grp;
@@ -1091,7 +1143,7 @@ chk_host(dp, saddr, defsetp)
if (dp) {
if (dp->dp_flag & DP_DEFSET)
- *defsetp = 1;
+ *defsetp = dp->dp_flag;
hp = dp->dp_hosts;
while (hp) {
grp = hp->ht_grp;
@@ -1100,15 +1152,19 @@ chk_host(dp, saddr, defsetp)
addrp = (u_long **)
grp->gr_ptr.gt_hostent->h_addr_list;
while (*addrp) {
- if (**addrp == saddr)
+ if (**addrp == saddr) {
+ *hostsetp = (hp->ht_flag | DP_HOSTSET);
return (1);
+ }
addrp++;
}
break;
case GT_NET:
if ((saddr & grp->gr_ptr.gt_net.nt_mask) ==
- grp->gr_ptr.gt_net.nt_net)
+ grp->gr_ptr.gt_net.nt_net) {
+ *hostsetp = (hp->ht_flag | DP_HOSTSET);
return (1);
+ }
break;
};
hp = hp->ht_next;
@@ -1125,12 +1181,12 @@ scan_tree(dp, saddr)
struct dirlist *dp;
u_long saddr;
{
- int defset;
+ int defset, hostset;
if (dp) {
if (scan_tree(dp->dp_left, saddr))
return (1);
- if (chk_host(dp, saddr, &defset))
+ if (chk_host(dp, saddr, &defset, &hostset))
return (1);
if (scan_tree(dp->dp_right, saddr))
return (1);
@@ -1180,12 +1236,12 @@ do_opt(cpp, endcpp, ep, grp, has_hostp, exflagsp, cr)
while (cpopt && *cpopt) {
allflag = 1;
usedarg = -2;
- if (cpoptend = index(cpopt, ',')) {
+ if (cpoptend = strchr(cpopt, ',')) {
*cpoptend++ = '\0';
- if (cpoptarg = index(cpopt, '='))
+ if (cpoptarg = strchr(cpopt, '='))
*cpoptarg++ = '\0';
} else {
- if (cpoptarg = index(cpopt, '='))
+ if (cpoptarg = strchr(cpopt, '='))
*cpoptarg++ = '\0';
else {
*cp = savedc;
@@ -1288,7 +1344,7 @@ get_host(cp, grp)
if (isdigit(*cp)) {
saddr = inet_addr(cp);
if (saddr == -1) {
- syslog(LOG_ERR, "Inet_addr failed");
+ syslog(LOG_ERR, "Inet_addr failed for %s", cp);
return (1);
}
if ((hp = gethostbyaddr((caddr_t)&saddr, sizeof (saddr),
@@ -1302,7 +1358,7 @@ get_host(cp, grp)
aptr[1] = (char *)NULL;
}
} else {
- syslog(LOG_ERR, "Gethostbyname failed");
+ syslog(LOG_ERR, "Gethostbyname failed for %s", cp);
return (1);
}
}
@@ -1311,13 +1367,12 @@ get_host(cp, grp)
malloc(sizeof(struct hostent));
if (nhp == (struct hostent *)NULL)
out_of_mem();
- bcopy((caddr_t)hp, (caddr_t)nhp,
- sizeof(struct hostent));
+ memmove(nhp, hp, sizeof(struct hostent));
i = strlen(hp->h_name)+1;
nhp->h_name = (char *)malloc(i);
if (nhp->h_name == (char *)NULL)
out_of_mem();
- bcopy(hp->h_name, nhp->h_name, i);
+ memmove(nhp->h_name, hp->h_name, i);
addrp = hp->h_addr_list;
i = 1;
while (*addrp++)
@@ -1332,8 +1387,7 @@ get_host(cp, grp)
malloc(hp->h_length);
if (*naddrp == (char *)NULL)
out_of_mem();
- bcopy(*addrp, *naddrp,
- hp->h_length);
+ memmove(*naddrp, *addrp, hp->h_length);
addrp++;
naddrp++;
}
@@ -1386,6 +1440,7 @@ get_ht()
if (hp == (struct hostlist *)NULL)
out_of_mem();
hp->ht_next = (struct hostlist *)NULL;
+ hp->ht_flag = 0;
return (hp);
}
@@ -1411,10 +1466,9 @@ get_isoaddr(cp, grp)
malloc(sizeof (struct sockaddr_iso));
if (isoaddr == (struct sockaddr_iso *)NULL)
out_of_mem();
- bzero((caddr_t)isoaddr, sizeof (struct sockaddr_iso));
- bcopy((caddr_t)isop, (caddr_t)&isoaddr->siso_addr,
- sizeof (struct iso_addr));
- isoaddr->siso_len = sizeof (struct sockaddr_iso);
+ memset(isoaddr, 0, sizeof(struct sockaddr_iso));
+ memmove(&isoaddr->siso_addr, isop, sizeof(struct iso_addr));
+ isoaddr->siso_len = sizeof(struct sockaddr_iso);
isoaddr->siso_family = AF_ISO;
grp->gr_type = GT_ISO;
grp->gr_ptr.gt_isoaddr = isoaddr;
@@ -1462,8 +1516,8 @@ do_mount(ep, grp, exflags, anoncrp, dirp, dirplen, fsb)
args.ua.fspec = 0;
args.ua.export.ex_flags = exflags;
args.ua.export.ex_anon = *anoncrp;
- bzero((char *)&sin, sizeof(sin));
- bzero((char *)&imask, sizeof(imask));
+ memset(&sin, 0, sizeof(sin));
+ memset(&imask, 0, sizeof(imask));
sin.sin_family = AF_INET;
sin.sin_len = sizeof(sin);
imask.sin_family = AF_INET;
@@ -1526,9 +1580,9 @@ do_mount(ep, grp, exflags, anoncrp, dirp, dirplen, fsb)
* Maybe I should just use the fsb->f_mntonname path instead
* of looping back up the dirp to the mount point??
* Also, needs to know how to export all types of local
- * exportable file systems and not just MOUNT_UFS.
+ * exportable file systems and not just "ufs".
*/
- while (mount(fsb->f_type, dirp,
+ while (mount(fsb->f_fstypename, dirp,
fsb->f_flags | MNT_UPDATE, (caddr_t)&args) < 0) {
if (cp)
*cp-- = savedc;
@@ -1540,7 +1594,8 @@ do_mount(ep, grp, exflags, anoncrp, dirp, dirplen, fsb)
return (1);
}
if (opt_flags & OP_ALLDIRS) {
- syslog(LOG_ERR, "Not root dir");
+ syslog(LOG_ERR, "Could not remount %s: %m",
+ dirp);
return (1);
}
/* back up over the last component */
@@ -1777,7 +1832,7 @@ void
get_mountlist()
{
struct mountlist *mlp, **mlpp;
- char *eos, *dirp;
+ char *host, *dirp, *cp;
int len;
char str[STRSIZ];
FILE *mlfile;
@@ -1788,27 +1843,16 @@ get_mountlist()
}
mlpp = &mlhead;
while (fgets(str, STRSIZ, mlfile) != NULL) {
- if ((dirp = index(str, '\t')) == NULL &&
- (dirp = index(str, ' ')) == NULL)
+ cp = str;
+ host = strsep(&cp, " \t\n");
+ dirp = strsep(&cp, " \t\n");
+ if (host == NULL || dirp == NULL)
continue;
mlp = (struct mountlist *)malloc(sizeof (*mlp));
- len = dirp-str;
- if (len > RPCMNT_NAMELEN)
- len = RPCMNT_NAMELEN;
- bcopy(str, mlp->ml_host, len);
- mlp->ml_host[len] = '\0';
- while (*dirp == '\t' || *dirp == ' ')
- dirp++;
- if ((eos = index(dirp, '\t')) == NULL &&
- (eos = index(dirp, ' ')) == NULL &&
- (eos = index(dirp, '\n')) == NULL)
- len = strlen(dirp);
- else
- len = eos-dirp;
- if (len > RPCMNT_PATHLEN)
- len = RPCMNT_PATHLEN;
- bcopy(dirp, mlp->ml_dirp, len);
- mlp->ml_dirp[len] = '\0';
+ strncpy(mlp->ml_host, host, RPCMNT_NAMELEN);
+ mlp->ml_host[RPCMNT_NAMELEN] = '\0';
+ strncpy(mlp->ml_dirp, dirp, RPCMNT_PATHLEN);
+ mlp->ml_dirp[RPCMNT_PATHLEN] = '\0';
mlp->ml_next = (struct mountlist *)NULL;
*mlpp = mlp;
mlpp = &mlp->ml_next;
@@ -1991,15 +2035,30 @@ check_dirpath(dirp)
while (*cp && ret) {
if (*cp == '/') {
*cp = '\0';
- if (lstat(dirp, &sb) < 0 ||
- (sb.st_mode & S_IFMT) != S_IFDIR)
+ if (lstat(dirp, &sb) < 0 || !S_ISDIR(sb.st_mode))
ret = 0;
*cp = '/';
}
cp++;
}
- if (lstat(dirp, &sb) < 0 ||
- (sb.st_mode & S_IFMT) != S_IFDIR)
+ if (lstat(dirp, &sb) < 0 || !S_ISDIR(sb.st_mode))
ret = 0;
return (ret);
}
+
+/*
+ * Just translate an ascii string to an integer.
+ */
+int
+get_num(cp)
+ register char *cp;
+{
+ register int res = 0;
+
+ while (*cp) {
+ if (*cp < '0' || *cp > '9')
+ return (-1);
+ res = res * 10 + (*cp++ - '0');
+ }
+ return (res);
+}
diff --git a/sbin/newlfs/config.h b/sbin/newlfs/config.h
index 9c8b394..2747f61 100644
--- a/sbin/newlfs/config.h
+++ b/sbin/newlfs/config.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)config.h 8.2 (Berkeley) 4/22/94
+ * @(#)config.h 8.3 (Berkeley) 5/24/95
*/
/*
@@ -132,3 +132,9 @@
#define DFL_LFSBLOCK 4096
#define DFL_LFSBLOCK_SHIFT 12
#define DFL_LFSBLOCK_MASK 0xFFF
+
+#define DFL_LFSFRAG 4096
+#define DFL_LFS_FFMASK DFL_LFSBLOCK_MASK
+#define DFL_LFS_FFSHIFT DFL_LFSBLOCK_SHIFT
+#define DFL_LFS_FBMASK 0
+#define DFL_LFS_FBSHIFT 0
diff --git a/sbin/newlfs/extern.h b/sbin/newlfs/extern.h
index c65cdba..27da835 100644
--- a/sbin/newlfs/extern.h
+++ b/sbin/newlfs/extern.h
@@ -30,15 +30,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)extern.h 8.1 (Berkeley) 6/5/93
+ * @(#)extern.h 8.2 (Berkeley) 5/24/95
*/
u_long cksum __P((void *, size_t));
u_short dkcksum __P((struct disklabel *));
void fatal __P((const char *fmt, ...));
u_int log2 __P((u_int));
-int make_lfs
- __P((int, struct disklabel *, struct partition *, int, int, int));
+int make_lfs __P((int, struct disklabel *, struct partition *, int,
+ int, int, int));
int mkfs __P((struct partition *, char *, int, int));
extern char *progname;
diff --git a/sbin/newlfs/lfs.c b/sbin/newlfs/lfs.c
index c79a0dc..dc271c4 100644
--- a/sbin/newlfs/lfs.c
+++ b/sbin/newlfs/lfs.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lfs.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)lfs.c 8.5 (Berkeley) 5/24/95";
#endif /* not lint */
#include <sys/param.h>
@@ -91,7 +91,7 @@ static struct lfs lfs_default = {
/* lfs_ssize */ DFL_LFSSEG/DFL_LFSBLOCK,
/* lfs_dsize */ 0,
/* lfs_bsize */ DFL_LFSBLOCK,
- /* lfs_fsize */ DFL_LFSBLOCK,
+ /* lfs_fsize */ DFL_LFSFRAG,
/* lfs_frag */ 1,
/* lfs_free */ LFS_FIRST_INUM,
/* lfs_bfree */ 0,
@@ -121,10 +121,10 @@ static struct lfs lfs_default = {
/* lfs_segshift */ DFL_LFSSEG_SHIFT,
/* lfs_bmask */ DFL_LFSBLOCK_MASK,
/* lfs_bshift */ DFL_LFSBLOCK_SHIFT,
- /* lfs_ffmask */ 0,
- /* lfs_ffshift */ 0,
- /* lfs_fbmask */ 0,
- /* lfs_fbshift */ 0,
+ /* lfs_ffmask */ DFL_LFS_FFMASK,
+ /* lfs_ffshift */ DFL_LFS_FFSHIFT,
+ /* lfs_fbmask */ DFL_LFS_FBMASK,
+ /* lfs_fbshift */ DFL_LFS_FBSHIFT,
/* lfs_fsbtodb */ 0,
/* lfs_sushift */ 0,
/* lfs_sboffs */ { 0 },
@@ -143,7 +143,8 @@ static struct lfs lfs_default = {
/* lfs_flags */ 0,
/* lfs_fsmnt */ { 0 },
/* lfs_pad */ { 0 },
- /* lfs_cksum */ 0
+ /* lfs_cksum */ 0,
+ /* lfs_maxsymlinklen */ MAXSYMLINKLEN
};
@@ -165,12 +166,13 @@ static void make_dir __P(( void *, struct direct *, int));
static void put __P((int, off_t, void *, size_t));
int
-make_lfs(fd, lp, partp, minfree, block_size, seg_size)
+make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size)
int fd;
struct disklabel *lp;
struct partition *partp;
int minfree;
int block_size;
+ int frag_size;
int seg_size;
{
struct dinode *dip; /* Pointer to a disk inode */
@@ -196,6 +198,7 @@ make_lfs(fd, lp, partp, minfree, block_size, seg_size)
u_long *datasump; /* Used to computed checksum on data */
int block_array_size; /* How many entries in block array */
int bsize; /* Block size */
+ int fsize; /* Fragment size */
int db_per_fb; /* Disk blocks per file block */
int i, j;
int off; /* Offset at which to write */
@@ -208,18 +211,27 @@ make_lfs(fd, lp, partp, minfree, block_size, seg_size)
if (!(bsize = block_size))
bsize = DFL_LFSBLOCK;
+ if (!(fsize = frag_size))
+ fsize = DFL_LFSFRAG;
if (!(ssize = seg_size))
ssize = DFL_LFSSEG;
/* Modify parts of superblock overridden by command line arguments */
- if (bsize != DFL_LFSBLOCK) {
+ if (bsize != DFL_LFSBLOCK || fsize != DFL_LFSFRAG) {
lfsp->lfs_bshift = log2(bsize);
if (1 << lfsp->lfs_bshift != bsize)
fatal("%d: block size not a power of 2", bsize);
lfsp->lfs_bsize = bsize;
- lfsp->lfs_fsize = bsize;
+ lfsp->lfs_fsize = fsize;
lfsp->lfs_bmask = bsize - 1;
lfsp->lfs_inopb = bsize / sizeof(struct dinode);
+ lfsp->lfs_ffmask = fsize - 1;
+ lfsp->lfs_ffshift = log2(fsize);
+ if (1 << lfsp->lfs_ffshift != fsize)
+ fatal("%d: frag size not a power of 2", fsize);
+ lfsp->lfs_frag = numfrags(lfsp, bsize);
+ lfsp->lfs_fbmask = lfsp->lfs_frag - 1;
+ lfsp->lfs_fbshift = log2(lfsp->lfs_frag);
/* MIS -- should I round to power of 2 */
lfsp->lfs_ifpb = bsize / sizeof(IFILE);
lfsp->lfs_sepb = bsize / sizeof(SEGUSE);
@@ -363,7 +375,7 @@ make_lfs(fd, lp, partp, minfree, block_size, seg_size)
if (!(dpagep = malloc(lfsp->lfs_bsize)))
fatal("%s", strerror(errno));
dip = (struct dinode *)dpagep;
- bzero(dip, lfsp->lfs_bsize);
+ memset(dip, 0, lfsp->lfs_bsize);
/* Create a block of IFILE structures. */
if (!(ipagep = malloc(lfsp->lfs_bsize)))
@@ -455,14 +467,14 @@ make_lfs(fd, lp, partp, minfree, block_size, seg_size)
*/
/* Write out the root and lost and found directories */
- bzero(ipagep, lfsp->lfs_bsize);
+ memset(ipagep, 0, lfsp->lfs_bsize);
make_dir(ipagep, lfs_root_dir,
sizeof(lfs_root_dir) / sizeof(struct direct));
*dp++ = ((u_long *)ipagep)[0];
put(fd, off, ipagep, lfsp->lfs_bsize);
off += lfsp->lfs_bsize;
- bzero(ipagep, lfsp->lfs_bsize);
+ memset(ipagep, 0, lfsp->lfs_bsize);
make_dir(ipagep, lfs_lf_dir,
sizeof(lfs_lf_dir) / sizeof(struct direct));
*dp++ = ((u_long *)ipagep)[0];
@@ -481,6 +493,7 @@ make_lfs(fd, lp, partp, minfree, block_size, seg_size)
summary.ss_create = lfsp->lfs_tstamp;
summary.ss_nfinfo = 3;
summary.ss_ninos = 3;
+ summary.ss_magic = SS_MAGIC;
summary.ss_datasum = cksum(datasump, sizeof(u_long) * blocks_used);
/*
@@ -511,30 +524,32 @@ make_lfs(fd, lp, partp, minfree, block_size, seg_size)
/* copy into segment */
sump = ipagep;
- bcopy(&summary, sump, sizeof(SEGSUM));
+ memmove(sump, &summary, sizeof(SEGSUM));
sump += sizeof(SEGSUM);
/* Now, add the ifile */
file_info.fi_nblocks = block_array_size;
file_info.fi_version = 1;
+ file_info.fi_lastlength = lfsp->lfs_bsize;
file_info.fi_ino = LFS_IFILE_INUM;
- bcopy(&file_info, sump, sizeof(FINFO) - sizeof(u_long));
+ memmove(sump, &file_info, sizeof(FINFO) - sizeof(u_long));
sump += sizeof(FINFO) - sizeof(u_long);
- bcopy(block_array, sump, sizeof(u_long) * file_info.fi_nblocks);
+ memmove(sump, block_array, sizeof(u_long) * file_info.fi_nblocks);
sump += sizeof(u_long) * file_info.fi_nblocks;
/* Now, add the root directory */
file_info.fi_nblocks = 1;
file_info.fi_version = 1;
+ file_info.fi_lastlength = lfsp->lfs_bsize;
file_info.fi_ino = ROOTINO;
file_info.fi_blocks[0] = 0;
- bcopy(&file_info, sump, sizeof(FINFO));
+ memmove(sump, &file_info, sizeof(FINFO));
sump += sizeof(FINFO);
/* Now, add the lost and found */
file_info.fi_ino = LOSTFOUNDINO;
- bcopy(&file_info, sump, sizeof(FINFO));
+ memmove(sump, &file_info, sizeof(FINFO));
((daddr_t *)ipagep)[LFS_SUMMARY_SIZE / sizeof(daddr_t) - 1] =
lfsp->lfs_idaddr;
@@ -547,6 +562,7 @@ make_lfs(fd, lp, partp, minfree, block_size, seg_size)
sp->ss_nfinfo = 0;
sp->ss_ninos = 0;
sp->ss_datasum = 0;
+ sp->ss_magic = SS_MAGIC;
/* Now write the summary block for the next partial so it's invalid */
lfsp->lfs_tstamp = 0;
@@ -605,10 +621,6 @@ put(fd, off, p, len)
* directory.
*/
- u_long d_ino; /* inode 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 with length <= MAXNAMLEN */
void
lfsinit()
{}
@@ -627,10 +639,8 @@ make_dinode(ino, dip, nblocks, saddr, lfsp)
dip->di_blocks = nblocks << lfsp->lfs_fsbtodb;
dip->di_size = (nblocks << lfsp->lfs_bshift);
- dip->di_atime.ts_sec = dip->di_mtime.ts_sec =
- dip->di_ctime.ts_sec = lfsp->lfs_tstamp;
- dip->di_atime.ts_nsec = dip->di_mtime.ts_nsec =
- dip->di_ctime.ts_nsec = 0;
+ dip->di_atime = dip->di_mtime = dip->di_ctime = lfsp->lfs_tstamp;
+ dip->di_atimensec = dip->di_mtimensec = dip->di_ctimensec = 0;
dip->di_inumber = ino;
#define SEGERR \
@@ -663,11 +673,11 @@ make_dir(bufp, protodir, entries)
spcleft = DIRBLKSIZ;
for (cp = bufp, i = 0; i < entries - 1; i++) {
protodir[i].d_reclen = DIRSIZ(NEWDIRFMT, &protodir[i]);
- bcopy(&protodir[i], cp, protodir[i].d_reclen);
+ memmove(cp, &protodir[i], protodir[i].d_reclen);
cp += protodir[i].d_reclen;
if ((spcleft -= protodir[i].d_reclen) < 0)
fatal("%s: %s", special, "directory too big");
}
protodir[i].d_reclen = spcleft;
- bcopy(&protodir[i], cp, DIRSIZ(NEWDIRFMT, &protodir[i]));
+ memmove(cp, &protodir[i], DIRSIZ(NEWDIRFMT, &protodir[i]));
}
diff --git a/sbin/newlfs/newfs.c b/sbin/newlfs/newfs.c
index 25ac7f0..88ca638 100644
--- a/sbin/newlfs/newfs.c
+++ b/sbin/newlfs/newfs.c
@@ -38,7 +38,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)newfs.c 8.3 (Berkeley) 4/22/94";
+static char sccsid[] = "@(#)newfs.c 8.5 (Berkeley) 5/24/95";
#endif /* not lint */
/*
@@ -127,7 +127,7 @@ main(argc, argv)
int debug, lfs, fsi, fso, segsize;
char *cp, *opstring;
- if (progname = rindex(*argv, '/'))
+ if (progname = strrchr(*argv, '/'))
++progname;
else
progname = *argv;
@@ -269,7 +269,7 @@ main(argc, argv)
* prefix, try /dev/r%s and then /dev/%s.
*/
special = argv[0];
- if (index(special, '/') == NULL) {
+ if (strchr(special, '/') == NULL) {
(void)sprintf(device, "%sr%s", _PATH_DEV, special);
if (stat(device, &st) == -1)
(void)sprintf(device, "%s%s", _PATH_DEV, special);
@@ -293,7 +293,7 @@ main(argc, argv)
if (!debug && !mfs && !S_ISCHR(st.st_mode))
(void)printf("%s: %s: not a character-special device\n",
progname, special);
- cp = index(argv[0], '\0') - 1;
+ cp = strchr(argv[0], '\0') - 1;
if (!debug && (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)))
fatal("%s: can't figure out file system partition", argv[0]);
@@ -314,7 +314,7 @@ main(argc, argv)
fatal("%s: `%c' partition is unavailable", argv[0], *cp);
/* If we're making a LFS, we break out here */
- exit(make_lfs(fso, lp, pp, minfree, bsize, segsize));
+ exit(make_lfs(fso, lp, pp, minfree, bsize, fsize, segsize));
}
#ifdef COMPAT
@@ -401,7 +401,7 @@ rewritelabel(s, fd, lp)
cfd = open(specname, O_WRONLY);
if (cfd < 0)
fatal("%s: %s", specname, strerror(errno));
- bzero(blk, sizeof(blk));
+ memset(blk, 0, sizeof(blk));
*(struct disklabel *)(blk + LABELOFFSET) = *lp;
alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
diff --git a/sbin/nfsd/nfsd.8 b/sbin/nfsd/nfsd.8
index 4ee6c4b..e98aa13 100644
--- a/sbin/nfsd/nfsd.8
+++ b/sbin/nfsd/nfsd.8
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)nfsd.8 8.3 (Berkeley) 2/22/94
+.\" @(#)nfsd.8 8.4 (Berkeley) 3/29/95
.\"
-.Dd February 22, 1994
+.Dd March 29, 1995
.Dt NFSD 8
.Os
.Sh NAME
@@ -98,7 +98,8 @@ listens for service requests at the port indicated in the
.Tn NFS
server specification; see
.%T "Network File System Protocol Specification" ,
-RFC1094.
+RFC1094 and
+.%T "NFS: Network File System Version 3 Protocol Specification" .
.Pp
The
.Nm nfsd
diff --git a/sbin/nfsd/nfsd.c b/sbin/nfsd/nfsd.c
index 63f4f00..164e08c 100644
--- a/sbin/nfsd/nfsd.c
+++ b/sbin/nfsd/nfsd.c
@@ -41,7 +41,7 @@ static char copyright[] =
#endif not lint
#ifndef lint
-static char sccsid[] = "@(#)nfsd.c 8.7 (Berkeley) 2/22/94";
+static char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95";
#endif not lint
#include <sys/param.h>
@@ -63,10 +63,10 @@ static char sccsid[] = "@(#)nfsd.c 8.7 (Berkeley) 2/22/94";
#include <netiso/iso.h>
#endif
#include <nfs/rpcv2.h>
-#include <nfs/nfsv2.h>
+#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
-#ifdef KERBEROS
+#ifdef NFSKERB
#include <kerberosIV/des.h>
#include <kerberosIV/krb.h>
#endif
@@ -94,11 +94,16 @@ struct nfsd_srvargs nsd;
char **Argv = NULL; /* pointer to argument vector */
char *LastArg = NULL; /* end of argv */
-#ifdef KERBEROS
+#ifdef NFSKERB
char lnam[ANAME_SZ];
KTEXT_ST kt;
-AUTH_DAT auth;
+AUTH_DAT kauth;
char inst[INST_SZ];
+struct nfsrpc_fullblock kin, kout;
+struct nfsrpc_fullverf kverf;
+NFSKERBKEY_T kivec;
+struct timeval ktv;
+NFSKERBKEYSCHED_T kerb_keysched;
#endif
void nonfs __P((int));
@@ -139,6 +144,7 @@ main(argc, argv, envp)
#ifdef ISO
struct sockaddr_iso isoaddr, isopeer;
#endif
+ struct timeval ktv;
fd_set ready, sockbits;
int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock;
int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock;
@@ -229,10 +235,12 @@ main(argc, argv, envp)
if (reregister) {
if (udpflag &&
- !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT))
+ (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) ||
+ !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)))
err(1, "can't register with portmap for UDP.");
if (tcpflag &&
- !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT))
+ (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) ||
+ !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT)))
err(1, "can't register with portmap for TCP.");
exit(0);
}
@@ -249,11 +257,17 @@ main(argc, argv, envp)
continue;
}
- setproctitle("nfsd-srv");
+ setproctitle("server");
nfssvc_flag = NFSSVC_NFSD;
nsd.nsd_nfsd = NULL;
-#ifdef KERBEROS
- nsd.nsd_authstr = (char *)kt.dat;
+#ifdef NFSKERB
+ if (sizeof (struct nfsrpc_fullverf) != RPCX_FULLVERF ||
+ sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK)
+ syslog(LOG_ERR, "Yikes NFSKERB structs not packed!");
+ nsd.nsd_authstr = (u_char *)&kt;
+ nsd.nsd_authlen = sizeof (kt);
+ nsd.nsd_verfstr = (u_char *)&kverf;
+ nsd.nsd_verflen = sizeof (kverf);
#endif
while (nfssvc(nfssvc_flag, &nsd) < 0) {
if (errno != ENEEDAUTH) {
@@ -261,14 +275,27 @@ main(argc, argv, envp)
exit(1);
}
nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL;
-#ifdef KERBEROS
- kt.length = nsd.nsd_authlen;
- kt.mbz = 0;
- (void)strcpy(inst, "*");
- if (krb_rd_req(&kt, "rcmd",
- inst, nsd.nsd_haddr, &auth, "") == RD_AP_OK &&
- krb_kntoln(&auth, lnam) == KSUCCESS &&
- (pwd = getpwnam(lnam)) != NULL) {
+#ifdef NFSKERB
+ /*
+ * Get the Kerberos ticket out of the authenticator
+ * verify it and convert the principal name to a user
+ * name. The user name is then converted to a set of
+ * user credentials via the password and group file.
+ * Finally, decrypt the timestamp and validate it.
+ * For more info see the IETF Draft "Authentication
+ * in ONC RPC".
+ */
+ kt.length = ntohl(kt.length);
+ if (gettimeofday(&ktv, (struct timezone *)0) == 0 &&
+ kt.length > 0 && kt.length <=
+ (RPCAUTH_MAXSIZ - 3 * NFSX_UNSIGNED)) {
+ kin.w1 = NFS_KERBW1(kt);
+ kt.mbz = 0;
+ (void)strcpy(inst, "*");
+ if (krb_rd_req(&kt, NFS_KERBSRV,
+ inst, nsd.nsd_haddr, &kauth, "") == RD_AP_OK &&
+ krb_kntoln(&kauth, lnam) == KSUCCESS &&
+ (pwd = getpwnam(lnam)) != NULL) {
cr = &nsd.nsd_cr;
cr->cr_uid = pwd->pw_uid;
cr->cr_groups[0] = pwd->pw_gid;
@@ -289,9 +316,34 @@ main(argc, argv, envp)
break;
}
endgrent();
- nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN;
+
+ /*
+ * Get the timestamp verifier out of the
+ * authenticator and verifier strings.
+ */
+ kin.t1 = kverf.t1;
+ kin.t2 = kverf.t2;
+ kin.w2 = kverf.w2;
+ bzero((caddr_t)kivec, sizeof (kivec));
+ bcopy((caddr_t)kauth.session,
+ (caddr_t)nsd.nsd_key,sizeof(kauth.session));
+
+ /*
+ * Decrypt the timestamp verifier in CBC mode.
+ */
+ XXX
+
+ /*
+ * Validate the timestamp verifier, to
+ * check that the session key is ok.
+ */
+ nsd.nsd_timestamp.tv_sec = ntohl(kout.t1);
+ nsd.nsd_timestamp.tv_usec = ntohl(kout.t2);
+ nsd.nsd_ttl = ntohl(kout.w1);
+ if ((nsd.nsd_ttl - 1) == ntohl(kout.w2))
+ nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN;
}
-#endif /* KERBEROS */
+#endif /* NFSKERB */
}
exit(0);
}
@@ -311,7 +363,8 @@ main(argc, argv, envp)
syslog(LOG_ERR, "can't bind udp addr");
exit(1);
}
- if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) {
+ if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) ||
+ !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)) {
syslog(LOG_ERR, "can't register with udp portmap");
exit(1);
}
@@ -391,7 +444,8 @@ main(argc, argv, envp)
syslog(LOG_ERR, "listen failed");
exit(1);
}
- if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
+ if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) ||
+ !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT)) {
syslog(LOG_ERR, "can't register tcp with portmap");
exit(1);
}
@@ -480,7 +534,7 @@ main(argc, argv, envp)
if (connect_type_cnt == 0)
exit(0);
- setproctitle("nfsd-master");
+ setproctitle("master");
/*
* Loop forever accepting connections and passing the sockets
@@ -554,7 +608,7 @@ main(argc, argv, envp)
void
usage()
{
- (void)fprintf(stderr, "nfsd %s\n", USAGE);
+ (void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
exit(1);
}
@@ -570,7 +624,7 @@ reapchild(signo)
int signo;
{
- while (wait3(NULL, WNOHANG, NULL));
+ while (wait3(NULL, WNOHANG, NULL) > 0);
}
void
@@ -581,9 +635,9 @@ setproctitle(a)
char buf[80];
cp = Argv[0];
- (void)snprintf(buf, sizeof(buf), "%s", a);
+ (void)snprintf(buf, sizeof(buf), "nfsd-%s", a);
(void)strncpy(cp, buf, LastArg - cp);
cp += strlen(cp);
while (cp < LastArg)
- *cp++ = ' ';
+ *cp++ = '\0';
}
diff --git a/sbin/nfsiod/nfsiod.c b/sbin/nfsiod/nfsiod.c
index b742fdc..1e3d748 100644
--- a/sbin/nfsiod/nfsiod.c
+++ b/sbin/nfsiod/nfsiod.c
@@ -41,7 +41,7 @@ static char copyright[] =
#endif not lint
#ifndef lint
-static char sccsid[] = "@(#)nfsiod.c 8.3 (Berkeley) 2/22/94";
+static char sccsid[] = "@(#)nfsiod.c 8.4 (Berkeley) 5/3/95";
#endif not lint
#include <sys/param.h>
@@ -50,7 +50,10 @@ static char sccsid[] = "@(#)nfsiod.c 8.3 (Berkeley) 2/22/94";
#include <sys/ucred.h>
#include <sys/wait.h>
-#include <nfs/nfsv2.h>
+#include <sys/mount.h>
+#include <sys/time.h>
+#include <nfs/rpcv2.h>
+#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
#include <err.h>
diff --git a/sbin/quotacheck/quotacheck.c b/sbin/quotacheck/quotacheck.c
index 1ee9e87..31c94d1 100644
--- a/sbin/quotacheck/quotacheck.c
+++ b/sbin/quotacheck/quotacheck.c
@@ -41,7 +41,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)quotacheck.c 8.3 (Berkeley) 1/29/94";
+static char sccsid[] = "@(#)quotacheck.c 8.6 (Berkeley) 4/28/95";
#endif /* not lint */
/*
@@ -49,6 +49,7 @@ static char sccsid[] = "@(#)quotacheck.c 8.3 (Berkeley) 1/29/94";
*/
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/queue.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/quota.h>
@@ -63,6 +64,7 @@ static char sccsid[] = "@(#)quotacheck.c 8.3 (Berkeley) 1/29/94";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <err.h>
char *qfname = QUOTAFILENAME;
char *qfextension[] = INITQFNAMES;
@@ -73,7 +75,7 @@ union {
char dummy[MAXBSIZE];
} un;
#define sblock un.sblk
-long dev_bsize = 1;
+long dev_bsize;
long maxino;
struct quotaname {
@@ -107,7 +109,6 @@ struct fileusage *
char *blockcheck __P((char *));
void bread __P((daddr_t, char *, long));
int chkquota __P((char *, char *, struct quotaname *));
-void err __P((const char *, ...));
void freeinodebuf __P((void));
struct dinode *
getnextinode __P((ino_t));
@@ -179,7 +180,7 @@ main(argc, argv)
if (aflag)
exit(checkfstab(1, maxrun, needchk, chkquota));
if (setfsent() == 0)
- err("%s: can't open", FSTAB);
+ err(1, "%s: can't open", FSTAB);
while ((fs = getfsent()) != NULL) {
if (((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
(argnum = oneof(fs->fs_spec, argv, argc)) >= 0) &&
@@ -217,7 +218,7 @@ needchk(fs)
strcmp(fs->fs_type, FSTAB_RW))
return (NULL);
if ((qnp = malloc(sizeof(*qnp))) == NULL)
- err("%s", strerror(errno));
+ err(1, "%s", strerror(errno));
qnp->flags = 0;
if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) {
strcpy(qnp->grpqfname, qfnp);
@@ -260,6 +261,7 @@ chkquota(fsname, mntpt, qnp)
(void)printf(" quotas for %s (%s)\n", fsname, mntpt);
}
sync();
+ dev_bsize = 1;
bread(SBOFF, (char *)&sblock, (long)SBSIZE);
dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
maxino = sblock.fs_ncg * sblock.fs_ipg;
@@ -446,7 +448,7 @@ hasquota(fs, type, qfnamep)
}
strcpy(buf, fs->fs_mntops);
for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
- if (cp = index(opt, '='))
+ if (cp = strchr(opt, '='))
*cp++ = '\0';
if (type == USRQUOTA && strcmp(opt, usrname) == 0)
break;
@@ -502,7 +504,7 @@ addid(id, type, name)
else
len = 10;
if ((fup = calloc(1, sizeof(*fup) + len)) == NULL)
- err("%s", strerror(errno));
+ err(1, "%s", strerror(errno));
fhp = &fuhead[type][id & (FUHASH - 1)];
fup->fu_next = *fhp;
*fhp = fup;
@@ -510,7 +512,7 @@ addid(id, type, name)
if (id > highid[type])
highid[type] = id;
if (name)
- bcopy(name, fup->fu_name, len + 1);
+ memmove(fup->fu_name, name, len + 1);
else
(void)sprintf(fup->fu_name, "%u", id);
return (fup);
@@ -534,7 +536,7 @@ getnextinode(inumber)
static struct dinode *dp;
if (inumber != nextino++ || inumber > maxino)
- err("bad inode number %d to nextinode", inumber);
+ err(1, "bad inode number %d to nextinode", inumber);
if (inumber >= lastinum) {
readcnt++;
dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
@@ -574,7 +576,7 @@ resetinodebuf()
}
if (inodebuf == NULL &&
(inodebuf = malloc((u_int)inobufsize)) == NULL)
- err("%s", strerror(errno));
+ err(1, "%s", strerror(errno));
while (nextino < ROOTINO)
getnextinode(nextino);
}
@@ -603,34 +605,5 @@ bread(bno, buf, cnt)
if (lseek(fi, (off_t)bno * dev_bsize, SEEK_SET) < 0 ||
read(fi, buf, cnt) != cnt)
- err("block %ld", bno);
-}
-
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-void
-#if __STDC__
-err(const char *fmt, ...)
-#else
-err(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- (void)fprintf(stderr, "quotacheck: ");
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- (void)fprintf(stderr, "\n");
- exit(1);
- /* NOTREACHED */
+ err(1, "block %ld", bno);
}
diff --git a/sbin/restore/dirs.c b/sbin/restore/dirs.c
index 5a2651c..d6c12d3 100644
--- a/sbin/restore/dirs.c
+++ b/sbin/restore/dirs.c
@@ -37,7 +37,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)dirs.c 8.2 (Berkeley) 1/21/94";
+static char sccsid[] = "@(#)dirs.c 8.7 (Berkeley) 5/1/95";
#endif /* not lint */
#include <sys/param.h>
@@ -45,9 +45,9 @@ static char sccsid[] = "@(#)dirs.c 8.2 (Berkeley) 1/21/94";
#include <sys/stat.h>
#include <sys/time.h>
-#include <ufs/ffs/fs.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
+#include <ufs/ffs/fs.h>
#include <protocols/dumprestore.h>
#include <errno.h>
@@ -56,6 +56,8 @@ static char sccsid[] = "@(#)dirs.c 8.2 (Berkeley) 1/21/94";
#include <string.h>
#include <unistd.h>
+#include <machine/endian.h>
+
#include "pathnames.h"
#include "restore.h"
#include "extern.h"
@@ -79,9 +81,10 @@ static struct inotab *inotab[HASHSIZE];
struct modeinfo {
ino_t ino;
struct timeval timep[2];
- short mode;
- short uid;
- short gid;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+ int flags;
};
/*
@@ -256,7 +259,7 @@ treescan(pname, ino, todo)
/*
* a zero inode signals end of directory
*/
- while (dp != NULL && dp->d_ino != 0) {
+ while (dp != NULL) {
locname[namelen] = '\0';
if (namelen + dp->d_namlen >= MAXPATHLEN) {
fprintf(stderr, "%s%s: name exceeds %d char\n",
@@ -269,8 +272,6 @@ treescan(pname, ino, todo)
dp = rst_readdir(dirp);
bpt = rst_telldir(dirp);
}
- if (dp == NULL)
- fprintf(stderr, "corrupted directory: %s.\n", locname);
}
/*
@@ -318,7 +319,7 @@ searchdir(inum, name)
len = strlen(name);
do {
dp = rst_readdir(dirp);
- if (dp == NULL || dp->d_ino == 0)
+ if (dp == NULL)
return (NULL);
} while (dp->d_namlen != len || strncmp(dp->d_name, name, len) != 0);
return (dp);
@@ -348,14 +349,17 @@ putdir(buf, size)
} else {
for (loc = 0; loc < size; ) {
dp = (struct direct *)(buf + loc);
- if (oldinofmt) {
- if (Bcvt) {
- swabst((u_char *)"l2s", (u_char *) dp);
- }
- } else {
- if (Bcvt) {
- swabst((u_char *)"ls", (u_char *) dp);
- }
+ if (Bcvt)
+ swabst((u_char *)"ls", (u_char *) dp);
+ if (oldinofmt && dp->d_ino != 0) {
+# if BYTE_ORDER == BIG_ENDIAN
+ if (Bcvt)
+ dp->d_namlen = dp->d_type;
+# else
+ if (!Bcvt)
+ dp->d_namlen = dp->d_type;
+# endif
+ dp->d_type = DT_UNKNOWN;
}
i = DIRBLKSIZ - (loc & (DIRBLKSIZ - 1));
if ((dp->d_reclen & 0x3) != 0 ||
@@ -407,7 +411,7 @@ putent(dp)
(void) fwrite(dirbuf, 1, DIRBLKSIZ, df);
dirloc = 0;
}
- bcopy((char *)dp, dirbuf + dirloc, (long)dp->d_reclen);
+ memmove(dirbuf + dirloc, dp, (long)dp->d_reclen);
prev = dirloc;
dirloc += dp->d_reclen;
}
@@ -430,7 +434,7 @@ dcvt(odp, ndp)
register struct direct *ndp;
{
- bzero((char *)ndp, (long)(sizeof *ndp));
+ memset(ndp, 0, (long)(sizeof *ndp));
ndp->d_ino = odp->d_ino;
ndp->d_type = DT_UNKNOWN;
(void) strncpy(ndp->d_name, odp->d_name, ODIRSIZ);
@@ -492,8 +496,8 @@ rst_readdir(dirp)
return (NULL);
}
dirp->dd_loc += dp->d_reclen;
- if (dp->d_ino == 0 && strcmp(dp->d_name, "/") != 0)
- continue;
+ if (dp->d_ino == 0 && strcmp(dp->d_name, "/") == 0)
+ return (NULL);
if (dp->d_ino >= maxino) {
dprintf(stderr, "corrupted directory: bad inum %d\n",
dp->d_ino);
@@ -612,6 +616,7 @@ setdirmodes(flags)
cp = myname(ep);
(void) chown(cp, node.uid, node.gid);
(void) chmod(cp, node.mode);
+ (void) chflags(cp, node.flags);
utimes(cp, node.timep);
ep->e_flags &= ~NEW;
}
@@ -636,7 +641,7 @@ genliteraldir(name, ino)
itp = inotablookup(ino);
if (itp == NULL)
panic("Cannot find directory inode %d named %s\n", ino, name);
- if ((ofile = creat(name, 0666)) < 0) {
+ if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
fprintf(stderr, "%s: ", name);
(void) fflush(stderr);
fprintf(stderr, "cannot create file: %s\n", strerror(errno));
@@ -704,11 +709,12 @@ allocinotab(ino, dip, seekpt)
if (mf == NULL)
return (itp);
node.ino = ino;
- node.timep[0].tv_sec = dip->di_atime.ts_sec;
- node.timep[0].tv_usec = dip->di_atime.ts_nsec / 1000;
- node.timep[1].tv_sec = dip->di_mtime.ts_sec;
- node.timep[1].tv_usec = dip->di_mtime.ts_nsec / 1000;
+ node.timep[0].tv_sec = dip->di_atime;
+ node.timep[0].tv_usec = dip->di_atimensec / 1000;
+ node.timep[1].tv_sec = dip->di_mtime;
+ node.timep[1].tv_usec = dip->di_mtimensec / 1000;
node.mode = dip->di_mode;
+ node.flags = dip->di_flags;
node.uid = dip->di_uid;
node.gid = dip->di_gid;
(void) fwrite((char *)&node, 1, sizeof(struct modeinfo), mf);
diff --git a/sbin/restore/interactive.c b/sbin/restore/interactive.c
index 1b9616c..76aa74f 100644
--- a/sbin/restore/interactive.c
+++ b/sbin/restore/interactive.c
@@ -32,16 +32,16 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)interactive.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)interactive.c 8.5 (Berkeley) 5/1/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <sys/stat.h>
-#include <ufs/ffs/fs.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
+#include <ufs/ffs/fs.h>
#include <protocols/dumprestore.h>
#include <setjmp.h>
@@ -85,7 +85,7 @@ static void formatf __P((struct afile *, int));
static void getcmd __P((char *, char *, char *, struct arglist *));
struct dirent *glob_readdir __P((RST_DIR *dirp));
static int glob_stat __P((const char *, struct stat *));
-static void mkentry __P((struct direct *, struct afile *));
+static void mkentry __P((char *, struct direct *, struct afile *));
static void printlist __P((char *, char *));
/*
@@ -496,15 +496,17 @@ printlist(name, basename)
register struct direct *dp;
struct afile single;
RST_DIR *dirp;
- int entries, len;
+ int entries, len, namelen;
+ char locname[MAXPATHLEN + 1];
dp = pathsearch(name);
- if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0))
+ if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) ||
+ (!vflag && dp->d_ino == WINO))
return;
if ((dirp = rst_opendir(name)) == NULL) {
entries = 1;
list = &single;
- mkentry(dp, list);
+ mkentry(name, dp, list);
len = strlen(basename) + 1;
if (strlen(name) - len > single.len) {
freename(single.fname);
@@ -526,17 +528,28 @@ printlist(name, basename)
fprintf(stderr, "%s:\n", name);
entries = 0;
listp = list;
+ (void) strncpy(locname, name, MAXPATHLEN);
+ (void) strncat(locname, "/", MAXPATHLEN);
+ namelen = strlen(locname);
while (dp = rst_readdir(dirp)) {
- if (dp == NULL || dp->d_ino == 0)
+ if (dp == NULL)
break;
if (!dflag && TSTINO(dp->d_ino, dumpmap) == 0)
continue;
- if (vflag == 0 &&
- (strcmp(dp->d_name, ".") == 0 ||
+ if (!vflag && (dp->d_ino == WINO ||
+ strcmp(dp->d_name, ".") == 0 ||
strcmp(dp->d_name, "..") == 0))
continue;
- mkentry(dp, listp++);
- entries++;
+ locname[namelen] = '\0';
+ if (namelen + dp->d_namlen >= MAXPATHLEN) {
+ fprintf(stderr, "%s%s: name exceeds %d char\n",
+ locname, dp->d_name, MAXPATHLEN);
+ } else {
+ (void) strncat(locname, dp->d_name,
+ (int)dp->d_namlen);
+ mkentry(locname, dp, listp++);
+ entries++;
+ }
}
rst_closedir(dirp);
if (entries == 0) {
@@ -559,7 +572,8 @@ printlist(name, basename)
* Read the contents of a directory.
*/
static void
-mkentry(dp, fp)
+mkentry(name, dp, fp)
+ char *name;
struct direct *dp;
register struct afile *fp;
{
@@ -574,7 +588,7 @@ mkentry(dp, fp)
fp->len = cp - fp->fname;
if (dflag && TSTINO(fp->fnum, dumpmap) == 0)
fp->prefix = '^';
- else if ((np = lookupino(fp->fnum)) != NULL && (np->e_flags & NEW))
+ else if ((np = lookupname(name)) != NULL && (np->e_flags & NEW))
fp->prefix = '*';
else
fp->prefix = ' ';
@@ -602,6 +616,10 @@ mkentry(dp, fp)
fp->postfix = '#';
break;
+ case DT_WHT:
+ fp->postfix = '%';
+ break;
+
case DT_UNKNOWN:
case DT_DIR:
if (inodetype(dp->d_ino) == NODE)
@@ -697,7 +715,7 @@ glob_readdir(dirp)
static struct dirent adirent;
while ((dp = rst_readdir(dirp)) != NULL) {
- if (dp->d_ino == 0)
+ if (!vflag && dp->d_ino == WINO)
continue;
if (dflag || TSTINO(dp->d_ino, dumpmap))
break;
@@ -706,7 +724,7 @@ glob_readdir(dirp)
return (NULL);
adirent.d_fileno = dp->d_ino;
adirent.d_namlen = dp->d_namlen;
- bcopy(dp->d_name, adirent.d_name, dp->d_namlen + 1);
+ memmove(adirent.d_name, dp->d_name, dp->d_namlen + 1);
return (&adirent);
}
@@ -721,7 +739,8 @@ glob_stat(name, stp)
register struct direct *dp;
dp = pathsearch(name);
- if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0))
+ if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) ||
+ (!vflag && dp->d_ino == WINO))
return (-1);
if (inodetype(dp->d_ino) == NODE)
stp->st_mode = IFDIR;
diff --git a/sbin/restore/main.c b/sbin/restore/main.c
index e2d8eeb..57620fe 100644
--- a/sbin/restore/main.c
+++ b/sbin/restore/main.c
@@ -38,14 +38,14 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/7/94";
+static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/4/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
-#include <ufs/ffs/fs.h>
#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
#include <protocols/dumprestore.h>
#include <err.h>
@@ -54,6 +54,7 @@ static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/7/94";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "pathnames.h"
#include "restore.h"
@@ -66,7 +67,7 @@ long dumpnum = 1;
long volno = 0;
long ntrec;
char *dumpmap;
-char *clrimap;
+char *usedinomap;
ino_t maxino;
time_t dumptime;
time_t dumpdate;
@@ -271,12 +272,12 @@ main(argc, argv)
static void
usage()
{
- (void)fprintf(stderr, "usage:\t%s%s%s%s%s",
- "restore tfhsvy [file ...]\n",
- "\trestore xfhmsvy [file ...]\n",
- "\trestore ifhmsvy\n",
- "\trestore rfsvy\n",
- "\trestore Rfsvy\n");
+ (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n",
+ "restore -i [-chmvy] [-b blocksize] [-f file] [-s fileno]",
+ "restore -r [-cvy] [-b blocksize] [-f file] [-s fileno]",
+ "restore -R [-cvy] [-b blocksize] [-f file] [-s fileno]",
+ "restore -x [-chmvy] [-b blocksize] [-f file] [-s fileno] [file ...]",
+ "restore -t [-chvy] [-b blocksize] [-f file] [-s fileno] [file ...]");
done(1);
}
@@ -311,17 +312,20 @@ obsolete(argcp, argvp)
argv += 2;
for (flags = 0; *ap; ++ap) {
- switch(*ap) {
+ switch (*ap) {
case 'b':
case 'f':
case 's':
+ if (*argv == NULL) {
+ warnx("option requires an argument -- %c", *ap);
+ 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);
- if (*argv != NULL)
- ++argv;
+ ++argv;
++nargv;
break;
default:
@@ -342,4 +346,7 @@ obsolete(argcp, argvp)
/* Copy remaining arguments. */
while (*nargv++ = *argv++);
+
+ /* Update argument count. */
+ *argcp = nargv - *argvp - 1;
}
diff --git a/sbin/restore/restore.8 b/sbin/restore/restore.8
index dfe7d68..6ad1b46 100644
--- a/sbin/restore/restore.8
+++ b/sbin/restore/restore.8
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)restore.8 8.2 (Berkeley) 12/11/93
+.\" @(#)restore.8 8.4 (Berkeley) 5/1/95
.\"
-.Dd December 11, 1993
+.Dd May 1, 1995
.Dt RESTORE 8
.Os BSD 4
.Sh NAME
@@ -39,8 +39,43 @@
.Nd "restore files or file systems from backups made with dump"
.Sh SYNOPSIS
.Nm restore
-.Ar key
-.Op Ar name Ar ...
+.Fl i
+.Op Fl chmvy
+.Op Fl b Ar blocksize
+.Op Fl f Ar file
+.Op Fl s Ar fileno
+.Nm restore
+.Fl R
+.Op Fl cvy
+.Op Fl b Ar blocksize
+.Op Fl f Ar file
+.Op Fl s Ar fileno
+.Nm restore
+.Fl r
+.Op Fl cvy
+.Op Fl b Ar blocksize
+.Op Fl f Ar file
+.Op Fl s Ar fileno
+.Nm restore
+.Fl t
+.Op Fl chvy
+.Op Fl b Ar blocksize
+.Op Fl f Ar file
+.Op Fl s Ar fileno
+.Op file ...
+.Nm restore
+.Fl x
+.Op Fl chmvy
+.Op Fl b Ar blocksize
+.Op Fl f Ar file
+.Op Fl s Ar fileno
+.Op file ...
+.Pp
+.in -\\n(iSu
+(The
+.Bx 4.3
+option syntax is implemented for backward compatibility, but
+is not documented here.)
.Sh DESCRIPTION
The
.Nm restore
@@ -56,109 +91,17 @@ works across a network;
to do this see the
.Fl f
flag described below.
-The actions
-of
-.Nm restore
-are controlled by the given
-.Cm key ,
-which
-is a string of characters containing
-at most one function letter and possibly
-one or more function modifiers.
Other arguments to the command are file or directory
names specifying the files that are to be restored.
Unless the
-.Cm h
-key is specified (see below),
+.Fl h
+flag is specified (see below),
the appearance of a directory name refers to
the files and (recursively) subdirectories of that directory.
.Pp
-The function portion of
-the key is specified by one of the following letters:
+Exactly one of the following flags is required:
.Bl -tag -width Ds
-.It Cm r
-Restore (rebuild a file system).
-The target file system should be made pristine with
-.Xr newfs 8 ,
-mounted and the
-user
-.Xr cd Ns 'd
-into the pristine file system
-before starting the restoration of the initial level 0 backup. If the
-level 0 restores successfully, the
-.Cm r
-key may be used to restore
-any necessary incremental backups on top of the level 0.
-The
-.Cm r
-key precludes an interactive file extraction and can be
-detrimental to one's health if not used carefully (not to mention
-the disk). An example:
-.Bd -literal -offset indent
-newfs /dev/rrp0g eagle
-mount /dev/rp0g /mnt
-cd /mnt
-
-restore rf /dev/rst8
-.Ed
-.Pp
-Note that
-.Nm restore
-leaves a file
-.Pa restoresymtable
-in the root directory to pass information between incremental
-restore passes.
-This file should be removed when the last incremental has been
-restored.
-.Pp
-.Nm Restore ,
-in conjunction with
-.Xr newfs 8
-and
-.Xr dump 8 ,
-may be used to modify file system parameters
-such as size or block size.
-.It Cm R
-.Nm Restore
-requests a particular tape of a multi volume set on which to restart
-a full restore
-(see the
-.Cm r
-key above).
-This is useful if the restore has been interrupted.
-.It Cm x
-The named files are read from the given media.
-If a named file matches a directory whose contents
-are on the backup
-and the
-.Cm h
-key is not specified,
-the directory is recursively extracted.
-The owner, modification time,
-and mode are restored (if possible).
-If no file argument is given,
-then the root directory is extracted,
-which results in the entire content of the
-backup being extracted,
-unless the
-.Cm h
-key has been specified.
-.It Cm t
-The names of the specified files are listed if they occur
-on the backup.
-If no file argument is given,
-then the root directory is listed,
-which results in the entire content of the
-backup being listed,
-unless the
-.Cm h
-key has been specified.
-Note that the
-.Cm t
-key replaces the function of the old
-.Xr dumpdir 8
-program.
-.It Cm i
+.It Fl i
This mode allows interactive restoration of files from a dump.
After reading in the directory information from the dump,
.Nm restore
@@ -174,8 +117,8 @@ files to be extracted.
If a directory is specified, then it and all its descendents are
added to the extraction list
(unless the
-.Cm h
-key is specified on the command line).
+.Fl h
+flag is specified on the command line).
Files that are on the extraction list are prepended with a ``*''
when they are listed by
.Ic ls .
@@ -187,8 +130,8 @@ files to be extracted.
If a directory is specified, then it and all its descendents are
deleted from the extraction list
(unless the
-.Cm h
-key is specified on the command line).
+.Fl h
+flag is specified on the command line).
The most expedient way to extract most of the files from a directory
is to add the directory to the extraction list and then delete
those files that are not needed.
@@ -205,7 +148,8 @@ List a summary of the available commands.
List the current or specified directory.
Entries that are directories are appended with a ``/''.
Entries that have been marked for extraction are prepended with a ``*''.
-If the verbose key is set the inode number of each entry is also listed.
+If the verbose
+flag is set the inode number of each entry is also listed.
.It Ic pwd
Print the full pathname of the current working directory.
.It Ic quit
@@ -218,93 +162,170 @@ nothing is extracted from the dump.
This is useful for cleaning up after a restore has been prematurely aborted.
.It Ic verbose
The sense of the
-.Cm v
-key is toggled.
-When set, the verbose key causes the
+.Fl v
+flag is toggled.
+When set, the verbose flag causes the
.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
+.Fl r
+flag below).
+This is useful if the restore has been interrupted.
+.It Fl r
+Restore (rebuild a file system).
+The target file system should be made pristine with
+.Xr newfs 8 ,
+mounted and the user
+.Xr cd Ns 'd
+into the pristine file system
+before starting the restoration of the initial level 0 backup. If the
+level 0 restores successfully, the
+.Fl r
+flag may be used to restore
+any necessary incremental backups on top of the level 0.
+The
+.Fl r
+flag precludes an interactive file extraction and can be
+detrimental to one's health if not used carefully (not to mention
+the disk). An example:
+.Bd -literal -offset indent
+newfs /dev/rrp0g eagle
+mount /dev/rp0g /mnt
+cd /mnt
+
+restore rf /dev/rst8
+.Ed
+.Pp
+Note that
+.Nm restore
+leaves a file
+.Pa restoresymtable
+in the root directory to pass information between incremental
+restore passes.
+This file should be removed when the last incremental has been
+restored.
+.Pp
+.Nm Restore ,
+in conjunction with
+.Xr newfs 8
+and
+.Xr dump 8 ,
+may be used to modify file system parameters
+such as size or block size.
+.It Fl t
+The names of the specified files are listed if they occur
+on the backup.
+If no file argument is given,
+then the root directory is listed,
+which results in the entire content of the
+backup being listed,
+unless the
+.Fl h
+flag has been specified.
+Note that the
+.Fl t
+flag replaces the function of the old
+.Xr dumpdir 8
+program.
+.ne 1i
+.It Fl x
+The named files are read from the given media.
+If a named file matches a directory whose contents
+are on the backup
+and the
+.Fl h
+flag is not specified,
+the directory is recursively extracted.
+The owner, modification time,
+and mode are restored (if possible).
+If no file argument is given,
+then the root directory is extracted,
+which results in the entire content of the
+backup being extracted,
+unless the
+.Fl h
+flag has been specified.
.El
.Pp
-The following characters may be used in addition to the letter
-that selects the function desired.
+The following additional options may be specified:
.Bl -tag -width Ds
-.It Cm b
-The next argument to
-.Nm restore
-is used as the block size of the media (in kilobytes).
+.It Fl b Ar blocksize
+The number of kilobytes per dump record.
If the
.Fl b
option is not specified,
.Nm restore
-tries to determine the media block size dynamically.
-.It Cm f
-The next argument to
+tries to determine the block size dynamically.
+.It Fl c
+Normally,
.Nm restore
-is used as the name of the archive instead
-of
-.Pa /dev/rmt? .
+will try to determine dynamically whether the dump was made from an
+old (pre-4.4) or new format file sytem. The
+.Fl c
+flag disables this check, and only allows reading a dump in the old
+format.
+.It Fl f Ar file
+Read the backup from
+.Ar file ;
+.Ar file
+may be a special device file
+like
+.Pa /dev/rmt12
+(a tape drive),
+.Pa /dev/rsd1c
+(a disk drive),
+an ordinary file,
+or
+.Ql Fl
+(the standard input).
If the name of the file is of the form
.Dq host:file ,
+or
+.Dq user@host:file ,
.Nm restore
reads from the named file on the remote host using
.Xr rmt 8 .
-If the name of the file is
-.Ql Fl ,
-.Nm restore
-reads from standard input.
-Thus,
-.Xr dump 8
-and
-.Nm restore
-can be used in a pipeline to dump and restore a file system
-with the command
-.Bd -literal -offset indent
-dump 0f - /usr | (cd /mnt; restore xf -)
-.Ed
.Pp
-.It Cm h
-.Nm Restore
-extracts the actual directory,
+.It Fl h
+Extract the actual directory,
rather than the files that it references.
This prevents hierarchical restoration of complete subtrees
from the dump.
-.It Cm m
-.Nm Restore
-will extract by inode numbers rather than by file name.
+.It Fl m
+Extract by inode numbers rather than by file name.
This is useful if only a few files are being extracted,
and one wants to avoid regenerating the complete pathname
to the file.
-.It Cm s
-The next argument to
-.Nm restore
-is a number which
-selects the file on a multi-file dump tape. File numbering
-starts at 1.
-.It Cm v
+.It Fl s Ar fileno
+Read from the specified
+.Ar fileno
+on a multi-file tape.
+File numbering starts at 1.
+.It Fl v
Normally
.Nm restore
does its work silently.
The
-.Cm v
+.Fl v
(verbose)
-key causes it to type the name of each file it treats
+flag causes it to type the name of each file it treats
preceded by its file type.
-.It Cm y
-.Nm Restore
-will not ask whether it should abort the restore if it gets an error.
-It will always try to skip over the bad block(s) and continue as
-best it can.
+.It Fl y
+Do not ask the user whether to abort the restore in the event of an error.
+Always try to skip over the bad block(s) and continue.
.El
.Sh DIAGNOSTICS
-Complaints about bad key characters.
-.Pp
Complaints if it gets a read error.
If
-.Cm y
+.Fl y
has been specified, or the user responds
.Ql y ,
.Nm restore
@@ -314,10 +335,10 @@ 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
-.Cm x
+.Fl x
or
-.Cm i
-key has been specified,
+.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
@@ -390,12 +411,12 @@ information passed between incremental restores.
.Sh BUGS
.Nm Restore
can get confused when doing incremental restores from
-dump that were made on active file systems.
+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 restore must be done to get a new set of directories
+thus a full dump must be done to get a new set of directories
reflecting the new inode numbering,
even though the contents of the files is unchanged.
.Sh HISTORY
diff --git a/sbin/restore/restore.c b/sbin/restore/restore.c
index dea964c..b628997 100644
--- a/sbin/restore/restore.c
+++ b/sbin/restore/restore.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)restore.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)restore.c 8.3 (Berkeley) 9/13/94";
#endif /* not lint */
#include <sys/types.h>
@@ -85,6 +85,8 @@ addfile(name, ino, type)
dprintf(stdout, "%s: not on the tape\n", name);
return (descend);
}
+ if (ino == WINO && command == 'i' && !vflag)
+ return (descend);
if (!mflag) {
(void) sprintf(buf, "./%u", ino);
name = buf;
@@ -124,9 +126,13 @@ deletefile(name, ino, type)
if (TSTINO(ino, dumpmap) == 0)
return (descend);
- ep = lookupino(ino);
- if (ep != NULL)
+ ep = lookupname(name);
+ if (ep != NULL) {
ep->e_flags &= ~NEW;
+ ep->e_flags |= REMOVED;
+ if (ep->e_type != NODE)
+ freeentry(ep);
+ }
return (descend);
}
@@ -146,21 +152,38 @@ deletefile(name, ino, type)
static struct entry *removelist;
/*
+ * Remove invalid whiteouts from the old tree.
* Remove unneeded leaves from the old tree.
* Remove directories from the lookup chains.
*/
void
removeoldleaves()
{
- register struct entry *ep;
- register ino_t i;
+ register struct entry *ep, *nextep;
+ register ino_t i, mydirino;
vprintf(stdout, "Mark entries to be removed.\n");
+ if (ep = lookupino(WINO)) {
+ vprintf(stdout, "Delete whiteouts\n");
+ for ( ; ep != NULL; ep = nextep) {
+ nextep = ep->e_links;
+ mydirino = ep->e_parent->e_ino;
+ /*
+ * We remove all whiteouts that are in directories
+ * that have been removed or that have been dumped.
+ */
+ if (TSTINO(mydirino, usedinomap) &&
+ !TSTINO(mydirino, dumpmap))
+ continue;
+ delwhiteout(ep);
+ freeentry(ep);
+ }
+ }
for (i = ROOTINO + 1; i < maxino; i++) {
ep = lookupino(i);
if (ep == NULL)
continue;
- if (TSTINO(i, clrimap))
+ if (TSTINO(i, usedinomap))
continue;
for ( ; ep != NULL; ep = ep->e_links) {
dprintf(stdout, "%s: REMOVE\n", myname(ep));
@@ -745,6 +768,15 @@ createlinks()
register ino_t i;
char name[BUFSIZ];
+ if (ep = lookupino(WINO)) {
+ vprintf(stdout, "Add whiteouts\n");
+ for ( ; ep != NULL; ep = ep->e_links) {
+ if ((ep->e_flags & NEW) == 0)
+ continue;
+ (void) addwhiteout(myname(ep));
+ ep->e_flags &= ~NEW;
+ }
+ }
vprintf(stdout, "Add links\n");
for (i = ROOTINO; i < maxino; i++) {
ep = lookupino(i);
@@ -776,7 +808,7 @@ checkrestore()
register ino_t i;
vprintf(stdout, "Check the symbol table.\n");
- for (i = ROOTINO; i < maxino; i++) {
+ for (i = WINO; i < maxino; i++) {
for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {
ep->e_flags &= ~KEEP;
if (ep->e_type == NODE)
diff --git a/sbin/restore/restore.h b/sbin/restore/restore.h
index 2202ccd..8dbcee8 100644
--- a/sbin/restore/restore.h
+++ b/sbin/restore/restore.h
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)restore.h 8.2 (Berkeley) 1/21/94
+ * @(#)restore.h 8.3 (Berkeley) 9/13/94
*/
/*
@@ -53,7 +53,7 @@ extern int yflag; /* always try to recover from tape errors */
* Global variables
*/
extern char *dumpmap; /* map of inodes on this dump tape */
-extern char *clrimap; /* map of inodes to be deleted */
+extern char *usedinomap; /* map of inodes that are in use on this fs */
extern ino_t maxino; /* highest numbered inode in this file system */
extern long dumpnum; /* location of the dump on this tape */
extern long volno; /* current volume being read */
@@ -129,6 +129,8 @@ typedef struct rstdirdesc RST_DIR;
*/
#define TSTINO(ino, map) \
(map[(u_int)((ino) - 1) / NBBY] & (1 << ((u_int)((ino) - 1) % NBBY)))
+#define SETINO(ino, map) \
+ map[(u_int)((ino) - 1) / NBBY] |= 1 << ((u_int)((ino) - 1) % NBBY)
#define dprintf if (dflag) fprintf
#define vprintf if (vflag) fprintf
diff --git a/sbin/restore/symtab.c b/sbin/restore/symtab.c
index 3895ec0..16b1d84 100644
--- a/sbin/restore/symtab.c
+++ b/sbin/restore/symtab.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)symtab.c 8.1 (Berkeley) 6/5/93";
+static char sccsid[] = "@(#)symtab.c 8.3 (Berkeley) 4/28/95";
#endif /* not lint */
/*
@@ -83,7 +83,7 @@ lookupino(inum)
{
register struct entry *ep;
- if (inum < ROOTINO || inum >= maxino)
+ if (inum < WINO || inum >= maxino)
return (NULL);
for (ep = entry[inum % entrytblsize]; ep != NULL; ep = ep->e_next)
if (ep->e_ino == inum)
@@ -101,7 +101,7 @@ addino(inum, np)
{
struct entry **epp;
- if (inum < ROOTINO || inum >= maxino)
+ if (inum < WINO || inum >= maxino)
panic("addino: out of range %d\n", inum);
epp = &entry[inum % entrytblsize];
np->e_ino = inum;
@@ -123,7 +123,7 @@ deleteino(inum)
register struct entry *next;
struct entry **prev;
- if (inum < ROOTINO || inum >= maxino)
+ if (inum < WINO || inum >= maxino)
panic("deleteino: out of range %d\n", inum);
prev = &entry[inum % entrytblsize];
for (next = *prev; next != NULL; next = next->e_next) {
@@ -174,7 +174,7 @@ lookupparent(name)
struct entry *ep;
char *tailindex;
- tailindex = rindex(name, '/');
+ tailindex = strrchr(name, '/');
if (tailindex == NULL)
return (NULL);
*tailindex = '\0';
@@ -199,7 +199,7 @@ myname(ep)
for (cp = &namebuf[MAXPATHLEN - 2]; cp > &namebuf[ep->e_namlen]; ) {
cp -= ep->e_namlen;
- bcopy(ep->e_name, cp, (long)ep->e_namlen);
+ memmove(cp, ep->e_name, (long)ep->e_namlen);
if (ep == lookupino(ROOTINO))
return (cp);
*(--cp) = '/';
@@ -229,7 +229,7 @@ addentry(name, inum, type)
if (freelist != NULL) {
np = freelist;
freelist = np->e_next;
- bzero((char *)np, (long)sizeof(struct entry));
+ memset(np, 0, (long)sizeof(struct entry));
} else {
np = (struct entry *)calloc(1, sizeof(struct entry));
if (np == NULL)
@@ -246,7 +246,7 @@ addentry(name, inum, type)
addino(ROOTINO, np);
return (np);
}
- np->e_name = savename(rindex(name, '/') + 1);
+ np->e_name = savename(strrchr(name, '/') + 1);
np->e_namlen = strlen(np->e_name);
np->e_parent = ep;
np->e_sibling = ep->e_entries;
@@ -330,7 +330,7 @@ moveentry(ep, newname)
ep->e_sibling = np->e_entries;
np->e_entries = ep;
}
- cp = rindex(newname, '/') + 1;
+ cp = strrchr(newname, '/') + 1;
freename(ep->e_name);
ep->e_name = savename(cp);
ep->e_namlen = strlen(cp);
@@ -470,7 +470,7 @@ dumpsymtable(filename, checkpt)
* Assign indicies to each entry
* Write out the string entries
*/
- for (i = ROOTINO; i < maxino; i++) {
+ for (i = WINO; i <= maxino; i++) {
for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {
ep->e_index = mynum++;
(void) fwrite(ep->e_name, sizeof(char),
@@ -482,10 +482,9 @@ dumpsymtable(filename, checkpt)
*/
tep = &temp;
stroff = 0;
- for (i = ROOTINO; i < maxino; i++) {
+ for (i = WINO; i <= maxino; i++) {
for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {
- bcopy((char *)ep, (char *)tep,
- (long)sizeof(struct entry));
+ memmove(tep, ep, (long)sizeof(struct entry));
tep->e_name = (char *)stroff;
stroff += allocsize(ep->e_namlen);
tep->e_parent = (struct entry *)ep->e_parent->e_index;
diff --git a/sbin/restore/tape.c b/sbin/restore/tape.c
index 368c59c..a8d833f 100644
--- a/sbin/restore/tape.c
+++ b/sbin/restore/tape.c
@@ -37,7 +37,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)tape.c 8.3 (Berkeley) 4/1/94";
+static char sccsid[] = "@(#)tape.c 8.9 (Berkeley) 5/1/95";
#endif /* not lint */
#include <sys/param.h>
@@ -119,9 +119,9 @@ setinput(source)
terminal = stdin;
#ifdef RRESTORE
- if (index(source, ':')) {
+ if (strchr(source, ':')) {
host = source;
- source = index(host, ':');
+ source = strchr(host, ':');
*source++ = '\0';
if (rmthost(host) == 0)
done(1);
@@ -250,8 +250,8 @@ setup()
dprintf(stdout, "maxino = %d\n", maxino);
map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
if (map == NULL)
- panic("no memory for file removal list\n");
- clrimap = map;
+ panic("no memory for active inode map\n");
+ usedinomap = map;
curfile.action = USING;
getfile(xtrmap, xtrmapskip);
if (spcl.c_type != TS_BITS) {
@@ -264,6 +264,13 @@ setup()
dumpmap = map;
curfile.action = USING;
getfile(xtrmap, xtrmapskip);
+ /*
+ * If there may be whiteout entries on the tape, pretend that the
+ * whiteout inode exists, so that the whiteout entries can be
+ * extracted.
+ */
+ if (oldinofmt == 0)
+ SETINO(WINO, dumpmap);
}
/*
@@ -500,17 +507,19 @@ int
extractfile(name)
char *name;
{
- int mode;
+ int flags;
+ mode_t mode;
struct timeval timep[2];
struct entry *ep;
curfile.name = name;
curfile.action = USING;
- 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;
+ timep[0].tv_sec = curfile.dip->di_atime;
+ timep[0].tv_usec = curfile.dip->di_atimensec / 1000;
+ timep[1].tv_sec = curfile.dip->di_mtime;
+ timep[1].tv_usec = curfile.dip->di_mtimensec / 1000;
mode = curfile.dip->di_mode;
+ flags = curfile.dip->di_flags;
switch (mode & IFMT) {
default:
@@ -560,6 +569,26 @@ extractfile(name)
}
(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);
@@ -570,7 +599,8 @@ extractfile(name)
skipfile();
return (GOOD);
}
- if ((ofile = creat(name, 0666)) < 0) {
+ if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC,
+ 0666)) < 0) {
fprintf(stderr, "%s: cannot create file: %s\n",
name, strerror(errno));
skipfile();
@@ -578,6 +608,7 @@ extractfile(name)
}
(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);
@@ -621,7 +652,7 @@ getfile(fill, skip)
{
register int i;
int curblk = 0;
- long size = spcl.c_dinode.di_size;
+ quad_t size = spcl.c_dinode.di_size;
static char clearedbuf[MAXBSIZE];
char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
char junk[TP_BSIZE];
@@ -638,20 +669,19 @@ loop:
if (spcl.c_addr[i]) {
readtape(&buf[curblk++][0]);
if (curblk == fssize / TP_BSIZE) {
- (*fill)((char *)buf, size > TP_BSIZE ?
- (long) (fssize) :
- (curblk - 1) * TP_BSIZE + size);
+ (*fill)((char *)buf, (long)(size > TP_BSIZE ?
+ fssize : (curblk - 1) * TP_BSIZE + size));
curblk = 0;
}
} else {
if (curblk > 0) {
- (*fill)((char *)buf, size > TP_BSIZE ?
- (long) (curblk * TP_BSIZE) :
- (curblk - 1) * TP_BSIZE + size);
+ (*fill)((char *)buf, (long)(size > TP_BSIZE ?
+ curblk * TP_BSIZE :
+ (curblk - 1) * TP_BSIZE + size));
curblk = 0;
}
- (*skip)(clearedbuf, size > TP_BSIZE ?
- (long) TP_BSIZE : size);
+ (*skip)(clearedbuf, (long)(size > TP_BSIZE ?
+ TP_BSIZE : size));
}
if ((size -= TP_BSIZE) <= 0) {
for (i++; i < spcl.c_count; i++)
@@ -668,7 +698,7 @@ loop:
curfile.name, blksread);
}
if (curblk > 0)
- (*fill)((char *)buf, (curblk * TP_BSIZE) + size);
+ (*fill)((char *)buf, (long)((curblk * TP_BSIZE) + size));
findinode(&spcl);
gettingfile = 0;
}
@@ -752,7 +782,7 @@ xtrmap(buf, size)
long size;
{
- bcopy(buf, map, size);
+ memmove(map, buf, size);
map += size;
}
@@ -795,7 +825,7 @@ readtape(buf)
int cnt, seek_failed;
if (blkcnt < numtrec) {
- bcopy(&tapebuf[(blkcnt++ * TP_BSIZE)], buf, (long)TP_BSIZE);
+ memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
blksread++;
tpblksread++;
return;
@@ -867,7 +897,7 @@ getmore:
if (!yflag && !reply("continue"))
done(1);
i = ntrec * TP_BSIZE;
- bzero(tapebuf, i);
+ memset(tapebuf, 0, i);
#ifdef RRESTORE
if (host)
seek_failed = (rmtseek(i, 1) < 0);
@@ -898,10 +928,10 @@ getmore:
panic("partial block read: %d should be %d\n",
rd, ntrec * TP_BSIZE);
terminateinput();
- bcopy((char *)&endoftapemark, &tapebuf[rd], (long)TP_BSIZE);
+ memmove(&tapebuf[rd], &endoftapemark, (long)TP_BSIZE);
}
blkcnt = 0;
- bcopy(&tapebuf[(blkcnt++ * TP_BSIZE)], buf, (long)TP_BSIZE);
+ memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
blksread++;
tpblksread++;
}
@@ -1009,7 +1039,7 @@ gethead(buf)
goto good;
}
readtape((char *)(&u_ospcl.s_ospcl));
- bzero((char *)buf, (long)TP_BSIZE);
+ memset(buf, 0, (long)TP_BSIZE);
buf->c_type = u_ospcl.s_ospcl.c_type;
buf->c_date = u_ospcl.s_ospcl.c_date;
buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
@@ -1024,11 +1054,11 @@ 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.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_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_count = u_ospcl.s_ospcl.c_count;
- bcopy(u_ospcl.s_ospcl.c_addr, buf->c_addr, (long)256);
+ memmove(buf->c_addr, u_ospcl.s_ospcl.c_addr, (long)256);
if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
return(FAIL);
@@ -1119,10 +1149,10 @@ accthdr(header)
goto newcalc;
switch (prevtype) {
case TS_BITS:
- fprintf(stderr, "Dump mask header");
+ fprintf(stderr, "Dumped inodes map header");
break;
case TS_CLRI:
- fprintf(stderr, "Remove mask header");
+ fprintf(stderr, "Used inodes map header");
break;
case TS_INODE:
fprintf(stderr, "File header, ino %d", previno);
diff --git a/sbin/restore/utilities.c b/sbin/restore/utilities.c
index 31fd11c..29ac8bd 100644
--- a/sbin/restore/utilities.c
+++ b/sbin/restore/utilities.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)utilities.c 8.2 (Berkeley) 3/25/94";
+static char sccsid[] = "@(#)utilities.c 8.5 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
@@ -61,7 +61,7 @@ pathcheck(name)
struct entry *ep;
char *start;
- start = index(name, '/');
+ start = strchr(name, '/');
if (start == 0)
return;
for (cp = start; *cp != '\0'; cp++) {
@@ -230,6 +230,45 @@ linkit(existing, new, type)
}
/*
+ * Create a whiteout.
+ */
+int
+addwhiteout(name)
+ char *name;
+{
+
+ if (!Nflag && mknod(name, S_IFWHT, 0) < 0) {
+ fprintf(stderr, "warning: cannot create whiteout %s: %s\n",
+ name, strerror(errno));
+ return (FAIL);
+ }
+ vprintf(stdout, "Create whiteout %s\n", name);
+ return (GOOD);
+}
+
+/*
+ * Delete a whiteout.
+ */
+void
+delwhiteout(ep)
+ register struct entry *ep;
+{
+ char *name;
+
+ if (ep->e_type != LEAF)
+ badentry(ep, "delwhiteout: not a leaf");
+ ep->e_flags |= REMOVED;
+ ep->e_flags &= ~TMPNAME;
+ name = myname(ep);
+ if (!Nflag && undelete(name) < 0) {
+ fprintf(stderr, "warning: cannot delete whiteout %s: %s\n",
+ name, strerror(errno));
+ return;
+ }
+ vprintf(stdout, "Delete whiteout %s\n", name);
+}
+
+/*
* find lowest number file (above "start") that needs to be extracted
*/
ino_t
diff --git a/sbin/umount/Makefile b/sbin/umount/Makefile
index 9665a59..2df8718 100644
--- a/sbin/umount/Makefile
+++ b/sbin/umount/Makefile
@@ -1,7 +1,13 @@
-# @(#)Makefile 8.2 (Berkeley) 2/20/94
+# @(#)Makefile 8.4 (Berkeley) 6/22/95
PROG= umount
+SRCS= umount.c vfslist.c
+MAN8= umount.0
DPADD= ${LIBRPC}
LDADD= -lrpc
+MOUNT= ${.CURDIR}/../../sbin/mount
+CFLAGS+= -I${MOUNT}
+.PATH: ${MOUNT}
+
.include <bsd.prog.mk>
diff --git a/sbin/umount/umount.8 b/sbin/umount/umount.8
index 234eb8f..0ef2852 100644
--- a/sbin/umount/umount.8
+++ b/sbin/umount/umount.8
@@ -29,23 +29,23 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)umount.8 8.1 (Berkeley) 2/20/94
+.\" @(#)umount.8 8.2 (Berkeley) 5/8/95
.\"
-.Dd February 20, 1994
+.Dd May 8, 1995
.Dt UMOUNT 8
.Os BSD 4
.Sh NAME
.Nm umount
-.Nd unmount file systems
+.Nd unmount filesystems
.Sh SYNOPSIS
.Nm umount
.Op Fl fv
.Ar special | node
.Nm umount
-.Fl a
+.Fl a | A
.Op Fl fv
.Op Fl h Ar host
-.Op Fl t Ar ufs | lfs | external_type
+.Op Fl t Ar type
.Sh DESCRIPTION
The
.Nm umount
@@ -54,7 +54,7 @@ calls the
.Xr unmount 2
system call to remove a
.Ar "special device"
-or the remote node (rhost:path) from the file system tree at the point
+or the remote node (rhost:path) from the filesystem tree at the point
.Ar node .
If either
.Ar special
@@ -67,23 +67,26 @@ file.
The options are as follows:
.Bl -tag -width indent
.It Fl a
-All of the file systems described in
+All the filesystems described in
.Xr fstab 5
are unmounted.
+.It Fl A
+All the currently mounted filesystems except
+the root are unmounted.
.It Fl f
-The file system is forcibly unmounted.
+The filesystem is forcibly unmounted.
Active special devices continue to work,
but all other files return errors if further accesses are attempted.
-The root file system cannot be forcibly unmounted.
+The root filesystem cannot be forcibly unmounted.
.It Fl h Ar host
Only filesystems mounted from the specified host will be
unmounted.
This option is implies the
-.Fl a
+.Fl A
option and, unless otherwise specified with the
.Fl t
option, will only unmount NFS filesystems.
-.It Fl t Ar "ufs \\*(Ba lfs \\*(Ba external type"
+.It Fl t Ar type
Is used to indicate the actions should only be taken on
filesystems of the specified type.
More than one type may be specified in a comma separated list.
@@ -104,13 +107,13 @@ umounts all filesystems of the type
and
.Tn MFS .
.It Fl v
-Verbose, additional information is printed out as each file system
+Verbose, additional information is printed out as each filesystem
is unmounted.
.El
.Sh FILES
.Bl -tag -width /etc/fstab -compact
.It Pa /etc/fstab
-file system table
+filesystem table
.El
.Sh SEE ALSO
.Xr unmount 2 ,
diff --git a/sbin/umount/umount.c b/sbin/umount/umount.c
index 56660de..09cb0b8 100644
--- a/sbin/umount/umount.c
+++ b/sbin/umount/umount.c
@@ -38,7 +38,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)umount.c 8.3 (Berkeley) 2/20/94";
+static char sccsid[] = "@(#)umount.c 8.8 (Berkeley) 5/8/95";
#endif /* not lint */
#include <sys/param.h>
@@ -63,16 +63,16 @@ static char sccsid[] = "@(#)umount.c 8.3 (Berkeley) 2/20/94";
typedef enum { MNTON, MNTFROM } mntwhat;
-int fake, fflag, vflag, *typelist;
+int fake, fflag, vflag;
char *nfshost;
-int fsnametotype __P((char *));
-char *getmntname __P((char *, mntwhat, int *));
-void maketypelist __P((char *));
+int checkvfsname __P((const char *, char **));
+char *getmntname __P((char *, mntwhat, char **));
+char **makevfslist __P((char *));
int selected __P((int));
int namematch __P((struct hostent *));
-int umountall __P((void));
-int umountfs __P((char *));
+int umountall __P((char **));
+int umountfs __P((char *, char **));
void usage __P((void));
int xdr_dir __P((XDR *, char *));
@@ -81,14 +81,19 @@ main(argc, argv)
int argc;
char *argv[];
{
- int all, ch, errs;
+ int all, ch, errs, mnts;
+ char **typelist = NULL;
+ struct statfs *mntbuf;
/* Start disks transferring immediately. */
sync();
all = 0;
- while ((ch = getopt(argc, argv, "aFfh:t:v")) != EOF)
+ while ((ch = getopt(argc, argv, "AaFfh:t:v")) != EOF)
switch (ch) {
+ case 'A':
+ all = 2;
+ break;
case 'a':
all = 1;
break;
@@ -98,12 +103,14 @@ main(argc, argv)
case 'f':
fflag = MNT_FORCE;
break;
- case 'h': /* -h implies -a. */
- all = 1;
+ case 'h': /* -h implies -A. */
+ all = 2;
nfshost = optarg;
break;
case 't':
- maketypelist(optarg);
+ if (typelist != NULL)
+ errx(1, "only one -t option may be specified.");
+ typelist = makevfslist(optarg);
break;
case 'v':
vflag = 1;
@@ -120,25 +127,44 @@ main(argc, argv)
/* -h implies "-t nfs" if no -t flag. */
if ((nfshost != NULL) && (typelist == NULL))
- maketypelist("nfs");
+ typelist = makevfslist("nfs");
- if (all) {
+ switch (all) {
+ case 2:
+ if ((mnts = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
+ warn("getmntinfo");
+ errs = 1;
+ break;
+ }
+ for (errs = 0, mnts--; mnts > 0; mnts--) {
+ if (checkvfsname(mntbuf[mnts].f_fstypename, typelist))
+ continue;
+ if (umountfs(mntbuf[mnts].f_mntonname, typelist) != 0)
+ errs = 1;
+ }
+ break;
+ case 1:
if (setfsent() == 0)
err(1, "%s", _PATH_FSTAB);
- errs = umountall();
- } else
+ errs = umountall(typelist);
+ break;
+ case 0:
for (errs = 0; *argv != NULL; ++argv)
- if (umountfs(*argv) == 0)
+ if (umountfs(*argv, typelist) != 0)
errs = 1;
+ break;
+ }
exit(errs);
}
int
-umountall()
+umountall(typelist)
+ char **typelist;
{
struct fstab *fs;
int rval, type;
char *cp;
+ struct vfsconf vfc;
while ((fs = getfsent()) != NULL) {
/* Ignore the root. */
@@ -153,11 +179,11 @@ umountall()
strcmp(fs->fs_type, FSTAB_RQ))
continue;
/* If an unknown file system type, complain. */
- if ((type = fsnametotype(fs->fs_vfstype)) == MOUNT_NONE) {
+ if (getvfsbyname(fs->fs_vfstype, &vfc) < 0) {
warnx("%s: unknown mount type", fs->fs_vfstype);
continue;
}
- if (!selected(type))
+ if (checkvfsname(fs->fs_vfstype, typelist))
continue;
/*
@@ -168,15 +194,16 @@ umountall()
if ((cp = malloc((size_t)strlen(fs->fs_file) + 1)) == NULL)
err(1, NULL);
(void)strcpy(cp, fs->fs_file);
- rval = umountall();
- return (umountfs(cp) || rval);
+ rval = umountall(typelist);
+ return (umountfs(cp, typelist) || rval);
}
return (0);
}
int
-umountfs(name)
+umountfs(name, typelist)
char *name;
+ char **typelist;
{
enum clnt_stat clnt_stat;
struct hostent *hp;
@@ -184,12 +211,12 @@ umountfs(name)
struct stat sb;
struct timeval pertry, try;
CLIENT *clp;
- int so, type;
- char *delimp, *hostp, *mntpt, rname[MAXPATHLEN];
+ int so;
+ char *type, *delimp, *hostp, *mntpt, rname[MAXPATHLEN];
if (realpath(name, rname) == NULL) {
warn("%s", rname);
- return (0);
+ return (1);
}
name = rname;
@@ -216,24 +243,27 @@ umountfs(name)
return (1);
}
- if (!selected(type))
- return (0);
+ if (checkvfsname(type, typelist))
+ return (1);
+
+ hp = NULL;
+ if (!strcmp(type, "nfs")) {
+ if ((delimp = strchr(name, '@')) != NULL) {
+ hostp = delimp + 1;
+ *delimp = '\0';
+ hp = gethostbyname(hostp);
+ *delimp = '@';
+ } else if ((delimp = strchr(name, ':')) != NULL) {
+ *delimp = '\0';
+ hostp = name;
+ hp = gethostbyname(hostp);
+ name = delimp + 1;
+ *delimp = ':';
+ }
+ }
- if ((delimp = strchr(name, '@')) != NULL) {
- hostp = delimp + 1;
- *delimp = '\0';
- hp = gethostbyname(hostp);
- *delimp = '@';
- } else if ((delimp = strchr(name, ':')) != NULL) {
- *delimp = '\0';
- hostp = name;
- hp = gethostbyname(hostp);
- name = delimp + 1;
- *delimp = ':';
- } else
- hp = NULL;
if (!namematch(hp))
- return (0);
+ return (1);
if (vflag)
(void)printf("%s: unmount from %s\n", name, mntpt);
@@ -278,98 +308,32 @@ char *
getmntname(name, what, type)
char *name;
mntwhat what;
- int *type;
+ char **type;
{
- struct statfs *mntbuf;
- int i, mntsize;
+ static struct statfs *mntbuf;
+ static int mntsize;
+ int i;
- if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
+ if (mntbuf == NULL &&
+ (mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
warn("getmntinfo");
return (NULL);
}
for (i = 0; i < mntsize; i++) {
if ((what == MNTON) && !strcmp(mntbuf[i].f_mntfromname, name)) {
if (type)
- *type = mntbuf[i].f_type;
+ *type = mntbuf[i].f_fstypename;
return (mntbuf[i].f_mntonname);
}
if ((what == MNTFROM) && !strcmp(mntbuf[i].f_mntonname, name)) {
if (type)
- *type = mntbuf[i].f_type;
+ *type = mntbuf[i].f_fstypename;
return (mntbuf[i].f_mntfromname);
}
}
return (NULL);
}
-static enum { IN_LIST, NOT_IN_LIST } which;
-
-int
-selected(type)
- int type;
-{
- /* If no type specified, it's always selected. */
- if (typelist == NULL)
- return (1);
- for (; *typelist != MOUNT_NONE; ++typelist)
- if (type == *typelist)
- return (which == IN_LIST ? 1 : 0);
- return (which == IN_LIST ? 0 : 1);
-}
-
-void
-maketypelist(fslist)
- char *fslist;
-{
- int *av, i;
- char *nextcp;
-
- if ((fslist == NULL) || (fslist[0] == '\0'))
- errx(1, "empty type list");
-
- /*
- * XXX
- * Note: the syntax is "noxxx,yyy" for no xxx's and
- * no yyy's, not the more intuitive "noyyy,noyyy".
- */
- if (fslist[0] == 'n' && fslist[1] == 'o') {
- fslist += 2;
- which = NOT_IN_LIST;
- } else
- which = IN_LIST;
-
- /* Count the number of types. */
- for (i = 0, nextcp = fslist; *nextcp != NULL; ++nextcp)
- if (*nextcp == ',')
- i++;
-
- /* Build an array of that many types. */
- if ((av = typelist = malloc((i + 2) * sizeof(int))) == NULL)
- err(1, NULL);
- for (i = 0; fslist != NULL; fslist = nextcp, ++i) {
- if ((nextcp = strchr(fslist, ',')) != NULL)
- *nextcp++ = '\0';
- av[i] = fsnametotype(fslist);
- if (av[i] == MOUNT_NONE)
- errx(1, "%s: unknown mount type", fslist);
- }
- /* Terminate the array. */
- av[i++] = MOUNT_NONE;
-}
-
-int
-fsnametotype(name)
- char *name;
-{
- static char const *namelist[] = INITMOUNTNAMES;
- char const **cp;
-
- for (cp = namelist; *cp; ++cp)
- if (strcmp(name, *cp) == 0)
- return (cp - namelist);
- return (MOUNT_NONE);
-}
-
int
namematch(hp)
struct hostent *hp;
OpenPOWER on IntegriCloud