aboutsummaryrefslogtreecommitdiff
path: root/sbin/bsdlabel
diff options
context:
space:
mode:
authorRodney W. Grimes <rgrimes@FreeBSD.org>1994-05-26 06:35:07 +0000
committerRodney W. Grimes <rgrimes@FreeBSD.org>1994-05-26 06:35:07 +0000
commit8fae3551ec46402adf7ab034cf9e02bcbc7ca8ee (patch)
treeb01471c3d6b141c37639a14b7a25f0433d926a99 /sbin/bsdlabel
parent4b88c807ea9c629dc5691abc7e3cac9ea0d776dd (diff)
downloadsrc-8fae3551ec46402adf7ab034cf9e02bcbc7ca8ee.tar.gz
src-8fae3551ec46402adf7ab034cf9e02bcbc7ca8ee.zip
BSD 4.4 Lite sbin Sources
Note: XNSrouted and routed NOT imported here, they shall be imported with usr.sbin.
Notes
Notes: svn path=/head/; revision=1558
Diffstat (limited to 'sbin/bsdlabel')
-rw-r--r--sbin/bsdlabel/Makefile14
-rw-r--r--sbin/bsdlabel/bsdlabel.8343
-rw-r--r--sbin/bsdlabel/bsdlabel.c1314
-rw-r--r--sbin/bsdlabel/disklabel.5.5384
-rw-r--r--sbin/bsdlabel/dkcksum.c53
-rw-r--r--sbin/bsdlabel/pathnames.h40
6 files changed, 2148 insertions, 0 deletions
diff --git a/sbin/bsdlabel/Makefile b/sbin/bsdlabel/Makefile
new file mode 100644
index 000000000000..3f4749c70f09
--- /dev/null
+++ b/sbin/bsdlabel/Makefile
@@ -0,0 +1,14 @@
+# @(#)Makefile 8.2 (Berkeley) 3/17/94
+
+PROG= disklabel
+SRCS= disklabel.c dkcksum.c
+MAN8= disklabel.0
+CLEANFILES=disklabel.5.0
+
+all: ${PROG} disklabel.5.0 ${MAN8}
+
+beforeinstall:
+ install -c -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} disklabel.5.0 \
+ ${DESTDIR}${MANDIR}5/disklabel.0
+
+.include <bsd.prog.mk>
diff --git a/sbin/bsdlabel/bsdlabel.8 b/sbin/bsdlabel/bsdlabel.8
new file mode 100644
index 000000000000..bf14e0f23b04
--- /dev/null
+++ b/sbin/bsdlabel/bsdlabel.8
@@ -0,0 +1,343 @@
+.\" Copyright (c) 1987, 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Symmetric Computer Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)disklabel.8 8.2 (Berkeley) 4/19/94
+.\"
+.Dd "April 19, 1994"
+.Dt DISKLABEL 8
+.Os BSD 4.2
+.Sh NAME
+.Nm disklabel
+.Nd read and write disk pack label
+.Sh SYNOPSIS
+.Nm disklabel
+.Op Fl r
+.Ar disk
+.Nm disklabel
+.Fl w
+.Op Fl r
+.Ar disk Ar disktype
+.Oo Ar packid Oc
+.Nm disklabel
+.Fl e
+.Op Fl r
+.Ar disk
+.Nm disklabel
+.Fl R
+.Op Fl r
+.Ar disk Ar protofile
+.Nm disklabel
+.Op Fl NW
+.Ar disk
+.sp
+.Nm disklabel
+.Fl B
+.Oo
+.Fl b Ar boot1
+.Op Fl s Ar boot2
+.Oc
+.Ar disk
+.Oo Ar disktype Oc
+.Nm disklabel
+.Fl w
+.Fl B
+.Oo
+.Fl b Ar boot1
+.Op Fl s Ar boot2
+.Oc
+.Ar disk Ar disktype
+.Oo Ar packid Oc
+.Nm disklabel
+.Fl R
+.Fl B
+.Oo
+.Fl b Ar boot1
+.Op Fl s Ar boot2
+.Oc
+.Ar disk Ar protofile
+.Oo Ar disktype Oc
+.Sh DESCRIPTION
+.Nm Disklabel
+can be used to install, examine or modify the label on a disk drive or pack.
+When writing the label, it can be used
+to change the drive identification,
+the disk partitions on the drive,
+or to replace a damaged label.
+On some systems,
+.Nm disklabel
+can be used to install bootstrap code as well.
+There are several forms of the command that read (display), install or edit
+the label on a disk.
+Each form has an additional option,
+.Fl r ,
+which causes the label to be read from or written to the disk directly,
+rather than going through the system's in-core copy of the label.
+This option may allow a label to be installed on a disk
+without kernel support for a label, such as when labels are first installed
+on a system; it must be used when first installing a label on a disk.
+The specific effect of
+.Fl r
+is described under each command.
+The read and install forms also support the
+.Fl B
+option to install bootstrap code.
+These variants are described later.
+.Pp
+The first form of the command (read) is used to examine the label on the named
+disk drive (e.g. sd0 or /dev/rsd0c).
+It will display all of the parameters associated with the drive
+and its partition layout.
+Unless the
+.Fl r
+flag is given,
+the kernel's in-core copy of the label is displayed;
+if the disk has no label, or the partition types on the disk are incorrect,
+the kernel may have constructed or modified the label.
+If the
+.Fl r
+flag is given, the label from the raw disk will be displayed rather
+than the in-core label.
+.Pp
+The second form of the command, with the
+.Fl w
+flag, is used to write a standard label on the designated drive.
+The required arguments to
+.Nm disklabel
+are the drive to be labelled (e.g. sd0), and
+the drive type as described in the
+.Xr disktab 5
+file.
+The drive parameters and partitions are taken from that file.
+If different disks of the same physical type are to have different
+partitions, it will be necessary to have separate disktab entries
+describing each, or to edit the label after installation as described below.
+The optional argument is a pack identification string,
+up to 16 characters long.
+The pack id must be quoted if it contains blanks.
+If the
+.Fl r
+flag is given, the disk sectors containing the label and bootstrap
+will be written directly.
+A side-effect of this is that any existing bootstrap code will be overwritten
+and the disk rendered unbootable.
+If
+.Fl r
+is not specified,
+the existing label will be updated via the in-core copy and any bootstrap
+code will be unaffected.
+If the disk does not already have a label, the
+.Fl r
+flag must be used.
+In either case, the kernel's in-core label is replaced.
+.Pp
+An existing disk label may be edited by using the
+.Fl e
+flag.
+The label is read from the in-core kernel copy,
+or directly from the disk if the
+.Fl r
+flag is also given.
+The label is formatted and then supplied to an editor for changes.
+If no editor is specified in an
+.Ev EDITOR
+environment variable,
+.Xr vi 1
+is used.
+When the editor terminates, the formatted label is reread
+and used to rewrite the disk label.
+Existing bootstrap code is unchanged regardless of whether
+.Fl r
+was specified.
+.Pp
+With the
+.Fl R
+flag,
+.Nm disklabel
+is capable of restoring a disk label that was formatted
+in a prior operation and saved in an ascii file.
+The prototype file used to create the label should be in the same format
+as that produced when reading or editing a label.
+Comments are delimited by
+.Ar \&#
+and newline.
+As with
+.Fl w ,
+any existing bootstrap code will be clobbered if
+.Fl r
+is specified and will be unaffected otherwise.
+.Pp
+The
+.Fl NW
+flags for
+.Nm disklabel
+explicitly disallow and
+allow, respectively, writing of the pack label area on the selected disk.
+.Pp
+The final three forms of
+.Nm disklabel
+are used to install boostrap code on machines where the bootstrap is part
+of the label.
+The bootstrap code is comprised of one or two boot programs depending on
+the machine.
+The
+.Fl B
+option is used to denote that bootstrap code is to be installed.
+The
+.Fl r
+flag is implied by
+.Fl B
+and never needs to be specified.
+The name of the boot program(s) to be installed can be selected in a
+variety of ways.
+First, the names can be specified explicitly via the
+.Fl b
+and
+.Fl s
+flags.
+On machines with only a single level of boot program,
+.Fl b
+is the name of that program.
+For machines with a two-level bootstrap,
+.Fl b
+indicates the primary boot program and
+.Fl s
+the secondary boot program.
+If the names are not explicitly given, standard boot programs will be used.
+The boot programs are located in
+.Pa /usr/mdec .
+The names of the programs are taken from the ``b0'' and ``b1'' parameters
+of the
+.Xr disktab 5
+entry for the disk if
+.Ar disktype
+was given and its disktab entry exists and includes those parameters.
+Otherwise, boot program names are derived from the name of the disk.
+These names are of the form
+.Pa basename Ns boot
+for the primary (or only) bootstrap, and
+.Pf boot Pa basename
+for the secondary bootstrap;
+for example,
+.Pa /usr/mdec/sdboot
+and
+.Pa /usr/mdec/bootsd
+if the disk device is
+.Em sd0 .
+.Pp
+The first of the three boot-installation forms is used to install
+bootstrap code without changing the existing label.
+It is essentially a read command with respect to the disk label
+itself and all options are related to the specification of the boot
+program as described previously.
+The final two forms are analogous to the basic write and restore versions
+except that they will install bootstrap code in addition to a new label.
+.Sh FILES
+.Bl -tag -width Pa -compact
+.It Pa /etc/disktab
+.It Pa /usr/mdec/ Ns Em xx Ns boot
+.It Pa /usr/mdec/boot Ns Em xx
+.El
+.Sh EXAMPLES
+.Dl disklabel sd0
+.Pp
+Display the in-core label for sd0 as obtained via
+.Pa /dev/rsd0c .
+.Pp
+.Dl disklabel -w -r /dev/rsd0c sd2212 foo
+.Pp
+Create a label for sd0 based on information for ``sd2212'' found in
+.Pa /etc/disktab .
+Any existing bootstrap code will be clobbered.
+.Pp
+.Dl disklabel -e -r sd0
+.Pp
+Read the on-disk label for sd0, edit it and reinstall in-core as well
+as on-disk.
+Existing bootstrap code is unaffected.
+.Pp
+.Dl disklabel -R sd0 mylabel
+.Pp
+Restore the on-disk and in-core label for sd0 from information in
+.Pa mylabel .
+Existing bootstrap code is unaffected.
+.Pp
+.Dl disklabel -B sd0
+.Pp
+Install a new bootstrap on sd0.
+The boot code comes from
+.Pa /usr/mdec/sdboot
+and possibly
+.Pa /usr/mdec/bootsd .
+On-disk and in-core labels are unchanged.
+.Pp
+.Dl disklabel -w -B /dev/rsd0c -b newboot sd2212
+.Pp
+Install a new label and bootstrap.
+The label is derived from disktab information for ``sd2212'' and
+installed both in-core and on-disk.
+The bootstrap code comes from the file
+.Pa /usr/mdec/newboot .
+.Sh SEE ALSO
+.Xr disktab 5 ,
+.Xr disklabel 5
+.Sh DIAGNOSTICS
+The kernel device drivers will not allow the size of a disk partition
+to be decreased or the offset of a partition to be changed while it is open.
+Some device drivers create a label containing only a single large partition
+if a disk is unlabeled; thus, the label must be written to the ``a''
+partition of the disk while it is open.
+This sometimes requires the desired label to be set in two steps,
+the first one creating at least one other partition,
+and the second setting the label on the new partition
+while shrinking the ``a'' partition.
+.Pp
+On some machines the bootstrap code may not fit entirely in the area
+allocated for it by some filesystems.
+As a result, it may not be possible to have filesystems on some partitions
+of a ``bootable'' disk.
+When installing bootstrap code,
+.Nm disklabel
+checks for these cases.
+If the installed boot code would overlap a partition of type FS_UNUSED
+it is marked as type FS_BOOT.
+The
+.Xr newfs 8
+utility will disallow creation of filesystems on FS_BOOT partitions.
+Conversely, if a partition has a type other than FS_UNUSED or FS_BOOT,
+.Nm disklabel
+will not install bootstrap code that overlaps it.
+.Sh BUGS
+When a disk name is given without a full pathname,
+the constructed device name uses the ``a'' partition on the tahoe,
+the ``c'' partition on all others.
diff --git a/sbin/bsdlabel/bsdlabel.c b/sbin/bsdlabel/bsdlabel.c
new file mode 100644
index 000000000000..4a2934078584
--- /dev/null
+++ b/sbin/bsdlabel/bsdlabel.c
@@ -0,0 +1,1314 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Symmetric Computer Systems.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1987, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)disklabel.c 8.2 (Berkeley) 1/7/94";
+/* from static char sccsid[] = "@(#)disklabel.c 1.2 (Symmetric) 11/28/85"; */
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/signal.h>
+#include <sys/errno.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#define DKTYPENAMES
+#include <sys/disklabel.h>
+#include <ufs/ffs/fs.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "pathnames.h"
+
+/*
+ * Disklabel: read and write disklabels.
+ * The label is usually placed on one of the first sectors of the disk.
+ * Many machines also place a bootstrap in the same area,
+ * in which case the label is embedded in the bootstrap.
+ * The bootstrap source must leave space at the proper offset
+ * for the label on such machines.
+ */
+
+#ifdef tahoe
+#define RAWPARTITION 'a'
+#else
+#define RAWPARTITION 'c'
+#endif
+
+#ifndef BBSIZE
+#define BBSIZE 8192 /* size of boot area, with label */
+#endif
+
+#ifdef tahoe
+#define NUMBOOT 0
+#else
+#if defined(hp300) || defined(hp800)
+#define NUMBOOT 1
+#else
+#define NUMBOOT 2
+#endif
+#endif
+
+#define DEFEDITOR _PATH_VI
+#define streq(a,b) (strcmp(a,b) == 0)
+
+char *dkname;
+char *specname;
+char tmpfil[] = _PATH_TMP;
+
+extern int errno;
+char namebuf[BBSIZE], *np = namebuf;
+struct disklabel lab;
+struct disklabel *readlabel(), *makebootarea();
+char bootarea[BBSIZE];
+
+#if NUMBOOT > 0
+int installboot; /* non-zero if we should install a boot program */
+char *bootbuf; /* pointer to buffer with remainder of boot prog */
+int bootsize; /* size of remaining boot program */
+char *xxboot; /* primary boot */
+char *bootxx; /* secondary boot */
+char boot0[MAXPATHLEN];
+char boot1[MAXPATHLEN];
+#endif
+
+enum {
+ UNSPEC, EDIT, NOWRITE, READ, RESTORE, WRITE, WRITEABLE, WRITEBOOT
+} op = UNSPEC;
+
+int rflag;
+
+#ifdef DEBUG
+int debug;
+#define OPTIONS "BNRWb:ders:w"
+#else
+#define OPTIONS "BNRWb:ers:w"
+#endif
+
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ register struct disklabel *lp;
+ FILE *t;
+ int ch, f, flag, error = 0;
+ char *name = 0;
+
+ while ((ch = getopt(argc, argv, OPTIONS)) != EOF)
+ switch (ch) {
+#if NUMBOOT > 0
+ case 'B':
+ ++installboot;
+ break;
+ case 'b':
+ xxboot = optarg;
+ break;
+#if NUMBOOT > 1
+ case 's':
+ bootxx = optarg;
+ break;
+#endif
+#endif
+ case 'N':
+ if (op != UNSPEC)
+ usage();
+ op = NOWRITE;
+ break;
+ case 'R':
+ if (op != UNSPEC)
+ usage();
+ op = RESTORE;
+ break;
+ case 'W':
+ if (op != UNSPEC)
+ usage();
+ op = WRITEABLE;
+ break;
+ case 'e':
+ if (op != UNSPEC)
+ usage();
+ op = EDIT;
+ break;
+ case 'r':
+ ++rflag;
+ break;
+ case 'w':
+ if (op != UNSPEC)
+ usage();
+ op = WRITE;
+ break;
+#ifdef DEBUG
+ case 'd':
+ debug++;
+ break;
+#endif
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+#if NUMBOOT > 0
+ if (installboot) {
+ rflag++;
+ if (op == UNSPEC)
+ op = WRITEBOOT;
+ } else {
+ if (op == UNSPEC)
+ op = READ;
+ xxboot = bootxx = 0;
+ }
+#else
+ if (op == UNSPEC)
+ op = READ;
+#endif
+ if (argc < 1)
+ usage();
+
+ dkname = argv[0];
+ if (dkname[0] != '/') {
+ (void)sprintf(np, "%sr%s%c", _PATH_DEV, dkname, RAWPARTITION);
+ specname = np;
+ np += strlen(specname) + 1;
+ } else
+ specname = dkname;
+ f = open(specname, op == READ ? O_RDONLY : O_RDWR);
+ if (f < 0 && errno == ENOENT && dkname[0] != '/') {
+ (void)sprintf(specname, "%sr%s", _PATH_DEV, dkname);
+ np = namebuf + strlen(specname) + 1;
+ f = open(specname, op == READ ? O_RDONLY : O_RDWR);
+ }
+ if (f < 0)
+ Perror(specname);
+
+ switch(op) {
+
+ case EDIT:
+ if (argc != 1)
+ usage();
+ lp = readlabel(f);
+ error = edit(lp, f);
+ break;
+
+ case NOWRITE:
+ flag = 0;
+ if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0)
+ Perror("ioctl DIOCWLABEL");
+ break;
+
+ case READ:
+ if (argc != 1)
+ usage();
+ lp = readlabel(f);
+ display(stdout, lp);
+ error = checklabel(lp);
+ break;
+
+ case RESTORE:
+#if NUMBOOT > 0
+ if (installboot && argc == 3) {
+ makelabel(argv[2], 0, &lab);
+ argc--;
+ }
+#endif
+ if (argc != 2)
+ usage();
+ lp = makebootarea(bootarea, &lab, f);
+ if (!(t = fopen(argv[1], "r")))
+ Perror(argv[1]);
+ if (getasciilabel(t, lp))
+ error = writelabel(f, bootarea, lp);
+ break;
+
+ case WRITE:
+ if (argc == 3) {
+ name = argv[2];
+ argc--;
+ }
+ if (argc != 2)
+ usage();
+ makelabel(argv[1], name, &lab);
+ lp = makebootarea(bootarea, &lab, f);
+ *lp = lab;
+ if (checklabel(lp) == 0)
+ error = writelabel(f, bootarea, lp);
+ break;
+
+ case WRITEABLE:
+ flag = 1;
+ if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0)
+ Perror("ioctl DIOCWLABEL");
+ break;
+
+#if NUMBOOT > 0
+ case WRITEBOOT:
+ {
+ struct disklabel tlab;
+
+ lp = readlabel(f);
+ tlab = *lp;
+ if (argc == 2)
+ makelabel(argv[1], 0, &lab);
+ lp = makebootarea(bootarea, &lab, f);
+ *lp = tlab;
+ if (checklabel(lp) == 0)
+ error = writelabel(f, bootarea, lp);
+ break;
+ }
+#endif
+ }
+ exit(error);
+}
+
+/*
+ * Construct a prototype disklabel from /etc/disktab. As a side
+ * effect, set the names of the primary and secondary boot files
+ * if specified.
+ */
+makelabel(type, name, lp)
+ char *type, *name;
+ register struct disklabel *lp;
+{
+ register struct disklabel *dp;
+ char *strcpy();
+
+ dp = getdiskbyname(type);
+ if (dp == NULL) {
+ fprintf(stderr, "%s: unknown disk type\n", type);
+ exit(1);
+ }
+ *lp = *dp;
+#if NUMBOOT > 0
+ /*
+ * Set bootstrap name(s).
+ * 1. If set from command line, use those,
+ * 2. otherwise, check if disktab specifies them (b0 or b1),
+ * 3. otherwise, makebootarea() will choose ones based on the name
+ * of the disk special file. E.g. /dev/ra0 -> raboot, bootra
+ */
+ if (!xxboot && lp->d_boot0) {
+ if (*lp->d_boot0 != '/')
+ (void)sprintf(boot0, "%s/%s",
+ _PATH_BOOTDIR, lp->d_boot0);
+ else
+ (void)strcpy(boot0, lp->d_boot0);
+ xxboot = boot0;
+ }
+#if NUMBOOT > 1
+ if (!bootxx && lp->d_boot1) {
+ if (*lp->d_boot1 != '/')
+ (void)sprintf(boot1, "%s/%s",
+ _PATH_BOOTDIR, lp->d_boot1);
+ else
+ (void)strcpy(boot1, lp->d_boot1);
+ bootxx = boot1;
+ }
+#endif
+#endif
+ /* d_packname is union d_boot[01], so zero */
+ bzero(lp->d_packname, sizeof(lp->d_packname));
+ if (name)
+ (void)strncpy(lp->d_packname, name, sizeof(lp->d_packname));
+}
+
+writelabel(f, boot, lp)
+ int f;
+ char *boot;
+ register struct disklabel *lp;
+{
+ register int i;
+ int flag;
+
+ setbootflag(lp);
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+ if (rflag) {
+ /*
+ * First set the kernel disk label,
+ * then write a label to the raw disk.
+ * If the SDINFO ioctl fails because it is unimplemented,
+ * keep going; otherwise, the kernel consistency checks
+ * may prevent us from changing the current (in-core)
+ * label.
+ */
+ if (ioctl(f, DIOCSDINFO, lp) < 0 &&
+ errno != ENODEV && errno != ENOTTY) {
+ l_perror("ioctl DIOCSDINFO");
+ return (1);
+ }
+ (void)lseek(f, (off_t)0, SEEK_SET);
+ /*
+ * write enable label sector before write (if necessary),
+ * disable after writing.
+ */
+ flag = 1;
+ if (ioctl(f, DIOCWLABEL, &flag) < 0)
+ perror("ioctl DIOCWLABEL");
+ if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) {
+ perror("write");
+ return (1);
+ }
+#if NUMBOOT > 0
+ /*
+ * Output the remainder of the disklabel
+ */
+ if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {
+ perror("write");
+ return(1);
+ }
+#endif
+ flag = 0;
+ (void) ioctl(f, DIOCWLABEL, &flag);
+ } else if (ioctl(f, DIOCWDINFO, lp) < 0) {
+ l_perror("ioctl DIOCWDINFO");
+ return (1);
+ }
+#ifdef vax
+ if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) {
+ daddr_t alt;
+
+ alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
+ for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
+ (void)lseek(f, (off_t)((alt + i) * lp->d_secsize),
+ SEEK_SET);
+ if (write(f, boot, lp->d_secsize) < lp->d_secsize) {
+ int oerrno = errno;
+ fprintf(stderr, "alternate label %d ", i/2);
+ errno = oerrno;
+ perror("write");
+ }
+ }
+ }
+#endif
+ return (0);
+}
+
+l_perror(s)
+ char *s;
+{
+ int saverrno = errno;
+
+ fprintf(stderr, "disklabel: %s: ", s);
+
+ switch (saverrno) {
+
+ case ESRCH:
+ fprintf(stderr, "No disk label on disk;\n");
+ fprintf(stderr,
+ "use \"disklabel -r\" to install initial label\n");
+ break;
+
+ case EINVAL:
+ fprintf(stderr, "Label magic number or checksum is wrong!\n");
+ fprintf(stderr, "(disklabel or kernel is out of date?)\n");
+ break;
+
+ case EBUSY:
+ fprintf(stderr, "Open partition would move or shrink\n");
+ break;
+
+ case EXDEV:
+ fprintf(stderr,
+ "Labeled partition or 'a' partition must start at beginning of disk\n");
+ break;
+
+ default:
+ errno = saverrno;
+ perror((char *)NULL);
+ break;
+ }
+}
+
+/*
+ * Fetch disklabel for disk.
+ * Use ioctl to get label unless -r flag is given.
+ */
+struct disklabel *
+readlabel(f)
+ int f;
+{
+ register struct disklabel *lp;
+
+ if (rflag) {
+ if (read(f, bootarea, BBSIZE) < BBSIZE)
+ Perror(specname);
+ for (lp = (struct disklabel *)bootarea;
+ lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp));
+ lp = (struct disklabel *)((char *)lp + 16))
+ if (lp->d_magic == DISKMAGIC &&
+ lp->d_magic2 == DISKMAGIC)
+ break;
+ if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) ||
+ lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
+ dkcksum(lp) != 0) {
+ fprintf(stderr,
+ "Bad pack magic number (label is damaged, or pack is unlabeled)\n");
+ /* lp = (struct disklabel *)(bootarea + LABELOFFSET); */
+ exit (1);
+ }
+ } else {
+ lp = &lab;
+ if (ioctl(f, DIOCGDINFO, lp) < 0)
+ Perror("ioctl DIOCGDINFO");
+ }
+ return (lp);
+}
+
+/*
+ * Construct a bootarea (d_bbsize bytes) in the specified buffer ``boot''
+ * Returns a pointer to the disklabel portion of the bootarea.
+ */
+struct disklabel *
+makebootarea(boot, dp, f)
+ char *boot;
+ register struct disklabel *dp;
+ int f;
+{
+ struct disklabel *lp;
+ register char *p;
+ int b;
+#if NUMBOOT > 0
+ char *dkbasename;
+ struct stat sb;
+#endif
+
+ /* XXX */
+ if (dp->d_secsize == 0) {
+ dp->d_secsize = DEV_BSIZE;
+ dp->d_bbsize = BBSIZE;
+ }
+ lp = (struct disklabel *)
+ (boot + (LABELSECTOR * dp->d_secsize) + LABELOFFSET);
+ bzero((char *)lp, sizeof *lp);
+#if NUMBOOT > 0
+ /*
+ * If we are not installing a boot program but we are installing a
+ * label on disk then we must read the current bootarea so we don't
+ * clobber the existing boot.
+ */
+ if (!installboot) {
+ if (rflag) {
+ if (read(f, boot, BBSIZE) < BBSIZE)
+ Perror(specname);
+ bzero((char *)lp, sizeof *lp);
+ }
+ return (lp);
+ }
+ /*
+ * We are installing a boot program. Determine the name(s) and
+ * read them into the appropriate places in the boot area.
+ */
+ if (!xxboot || !bootxx) {
+ dkbasename = np;
+ if ((p = rindex(dkname, '/')) == NULL)
+ p = dkname;
+ else
+ p++;
+ while (*p && !isdigit(*p))
+ *np++ = *p++;
+ *np++ = '\0';
+
+ if (!xxboot) {
+ (void)sprintf(np, "%s/%sboot",
+ _PATH_BOOTDIR, dkbasename);
+ if (access(np, F_OK) < 0 && dkbasename[0] == 'r')
+ dkbasename++;
+ xxboot = np;
+ (void)sprintf(xxboot, "%s/%sboot",
+ _PATH_BOOTDIR, dkbasename);
+ np += strlen(xxboot) + 1;
+ }
+#if NUMBOOT > 1
+ if (!bootxx) {
+ (void)sprintf(np, "%s/boot%s",
+ _PATH_BOOTDIR, dkbasename);
+ if (access(np, F_OK) < 0 && dkbasename[0] == 'r')
+ dkbasename++;
+ bootxx = np;
+ (void)sprintf(bootxx, "%s/boot%s",
+ _PATH_BOOTDIR, dkbasename);
+ np += strlen(bootxx) + 1;
+ }
+#endif
+ }
+#ifdef DEBUG
+ if (debug)
+ fprintf(stderr, "bootstraps: xxboot = %s, bootxx = %s\n",
+ xxboot, bootxx ? bootxx : "NONE");
+#endif
+
+ /*
+ * Strange rules:
+ * 1. One-piece bootstrap (hp300/hp800)
+ * up to d_bbsize bytes of ``xxboot'' go in bootarea, the rest
+ * is remembered and written later following the bootarea.
+ * 2. Two-piece bootstraps (vax/i386?/mips?)
+ * up to d_secsize bytes of ``xxboot'' go in first d_secsize
+ * bytes of bootarea, remaining d_bbsize-d_secsize filled
+ * from ``bootxx''.
+ */
+ b = open(xxboot, O_RDONLY);
+ if (b < 0)
+ Perror(xxboot);
+#if NUMBOOT > 1
+ if (read(b, boot, (int)dp->d_secsize) < 0)
+ Perror(xxboot);
+ (void)close(b);
+ b = open(bootxx, O_RDONLY);
+ if (b < 0)
+ Perror(bootxx);
+ if (read(b, &boot[dp->d_secsize], (int)(dp->d_bbsize-dp->d_secsize)) < 0)
+ Perror(bootxx);
+#else
+ if (read(b, boot, (int)dp->d_bbsize) < 0)
+ Perror(xxboot);
+ (void)fstat(b, &sb);
+ bootsize = (int)sb.st_size - dp->d_bbsize;
+ if (bootsize > 0) {
+ /* XXX assume d_secsize is a power of two */
+ bootsize = (bootsize + dp->d_secsize-1) & ~(dp->d_secsize-1);
+ bootbuf = (char *)malloc((size_t)bootsize);
+ if (bootbuf == 0)
+ Perror(xxboot);
+ if (read(b, bootbuf, bootsize) < 0) {
+ free(bootbuf);
+ Perror(xxboot);
+ }
+ }
+#endif
+ (void)close(b);
+#endif
+ /*
+ * Make sure no part of the bootstrap is written in the area
+ * reserved for the label.
+ */
+ for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++)
+ if (*p) {
+ fprintf(stderr,
+ "Bootstrap doesn't leave room for disk label\n");
+ exit(2);
+ }
+ return (lp);
+}
+
+display(f, lp)
+ FILE *f;
+ register struct disklabel *lp;
+{
+ register int i, j;
+ register struct partition *pp;
+
+ fprintf(f, "# %s:\n", specname);
+ if ((unsigned) lp->d_type < DKMAXTYPES)
+ fprintf(f, "type: %s\n", dktypenames[lp->d_type]);
+ else
+ fprintf(f, "type: %d\n", lp->d_type);
+ fprintf(f, "disk: %.*s\n", sizeof(lp->d_typename), lp->d_typename);
+ fprintf(f, "label: %.*s\n", sizeof(lp->d_packname), lp->d_packname);
+ fprintf(f, "flags:");
+ if (lp->d_flags & D_REMOVABLE)
+ fprintf(f, " removeable");
+ if (lp->d_flags & D_ECC)
+ fprintf(f, " ecc");
+ if (lp->d_flags & D_BADSECT)
+ fprintf(f, " badsect");
+ fprintf(f, "\n");
+ fprintf(f, "bytes/sector: %d\n", lp->d_secsize);
+ fprintf(f, "sectors/track: %d\n", lp->d_nsectors);
+ fprintf(f, "tracks/cylinder: %d\n", lp->d_ntracks);
+ fprintf(f, "sectors/cylinder: %d\n", lp->d_secpercyl);
+ fprintf(f, "cylinders: %d\n", lp->d_ncylinders);
+ fprintf(f, "rpm: %d\n", lp->d_rpm);
+ fprintf(f, "interleave: %d\n", lp->d_interleave);
+ fprintf(f, "trackskew: %d\n", lp->d_trackskew);
+ fprintf(f, "cylinderskew: %d\n", lp->d_cylskew);
+ fprintf(f, "headswitch: %d\t\t# milliseconds\n", lp->d_headswitch);
+ fprintf(f, "track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek);
+ fprintf(f, "drivedata: ");
+ for (i = NDDATA - 1; i >= 0; i--)
+ if (lp->d_drivedata[i])
+ break;
+ if (i < 0)
+ i = 0;
+ for (j = 0; j <= i; j++)
+ fprintf(f, "%d ", lp->d_drivedata[j]);
+ fprintf(f, "\n\n%d partitions:\n", lp->d_npartitions);
+ fprintf(f,
+ "# size offset fstype [fsize bsize cpg]\n");
+ pp = lp->d_partitions;
+ for (i = 0; i < lp->d_npartitions; i++, pp++) {
+ if (pp->p_size) {
+ fprintf(f, " %c: %8d %8d ", 'a' + i,
+ pp->p_size, pp->p_offset);
+ if ((unsigned) pp->p_fstype < FSMAXTYPES)
+ fprintf(f, "%8.8s", fstypenames[pp->p_fstype]);
+ else
+ fprintf(f, "%8d", pp->p_fstype);
+ switch (pp->p_fstype) {
+
+ case FS_UNUSED: /* XXX */
+ fprintf(f, " %5d %5d %5.5s ",
+ pp->p_fsize, pp->p_fsize * pp->p_frag, "");
+ break;
+
+ case FS_BSDFFS:
+ fprintf(f, " %5d %5d %5d ",
+ pp->p_fsize, pp->p_fsize * pp->p_frag,
+ pp->p_cpg);
+ break;
+
+ default:
+ fprintf(f, "%20.20s", "");
+ break;
+ }
+ fprintf(f, "\t# (Cyl. %4d",
+ pp->p_offset / lp->d_secpercyl);
+ if (pp->p_offset % lp->d_secpercyl)
+ putc('*', f);
+ else
+ putc(' ', f);
+ fprintf(f, "- %d",
+ (pp->p_offset +
+ pp->p_size + lp->d_secpercyl - 1) /
+ lp->d_secpercyl - 1);
+ if (pp->p_size % lp->d_secpercyl)
+ putc('*', f);
+ fprintf(f, ")\n");
+ }
+ }
+ fflush(f);
+}
+
+edit(lp, f)
+ struct disklabel *lp;
+ int f;
+{
+ register int c;
+ struct disklabel label;
+ FILE *fd;
+ char *mktemp();
+
+ (void) mktemp(tmpfil);
+ fd = fopen(tmpfil, "w");
+ if (fd == NULL) {
+ fprintf(stderr, "%s: Can't create\n", tmpfil);
+ return (1);
+ }
+ (void)fchmod(fileno(fd), 0600);
+ display(fd, lp);
+ fclose(fd);
+ for (;;) {
+ if (!editit())
+ break;
+ fd = fopen(tmpfil, "r");
+ if (fd == NULL) {
+ fprintf(stderr, "%s: Can't reopen for reading\n",
+ tmpfil);
+ break;
+ }
+ bzero((char *)&label, sizeof(label));
+ if (getasciilabel(fd, &label)) {
+ *lp = label;
+ if (writelabel(f, bootarea, lp) == 0) {
+ (void) unlink(tmpfil);
+ return (0);
+ }
+ }
+ printf("re-edit the label? [y]: "); fflush(stdout);
+ c = getchar();
+ if (c != EOF && c != (int)'\n')
+ while (getchar() != (int)'\n')
+ ;
+ if (c == (int)'n')
+ break;
+ }
+ (void) unlink(tmpfil);
+ return (1);
+}
+
+editit()
+{
+ register int pid, xpid;
+ int stat, omask;
+ extern char *getenv();
+
+ omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
+ while ((pid = fork()) < 0) {
+ extern int errno;
+
+ if (errno == EPROCLIM) {
+ fprintf(stderr, "You have too many processes\n");
+ return(0);
+ }
+ if (errno != EAGAIN) {
+ perror("fork");
+ return(0);
+ }
+ sleep(1);
+ }
+ if (pid == 0) {
+ register char *ed;
+
+ sigsetmask(omask);
+ setgid(getgid());
+ setuid(getuid());
+ if ((ed = getenv("EDITOR")) == (char *)0)
+ ed = DEFEDITOR;
+ execlp(ed, ed, tmpfil, 0);
+ perror(ed);
+ exit(1);
+ }
+ while ((xpid = wait(&stat)) >= 0)
+ if (xpid == pid)
+ break;
+ sigsetmask(omask);
+ return(!stat);
+}
+
+char *
+skip(cp)
+ register char *cp;
+{
+
+ while (*cp != '\0' && isspace(*cp))
+ cp++;
+ if (*cp == '\0' || *cp == '#')
+ return ((char *)NULL);
+ return (cp);
+}
+
+char *
+word(cp)
+ register char *cp;
+{
+ register char c;
+
+ while (*cp != '\0' && !isspace(*cp) && *cp != '#')
+ cp++;
+ if ((c = *cp) != '\0') {
+ *cp++ = '\0';
+ if (c != '#')
+ return (skip(cp));
+ }
+ return ((char *)NULL);
+}
+
+/*
+ * Read an ascii label in from fd f,
+ * in the same format as that put out by display(),
+ * and fill in lp.
+ */
+getasciilabel(f, lp)
+ FILE *f;
+ register struct disklabel *lp;
+{
+ register char **cpp, *cp;
+ register struct partition *pp;
+ char *tp, *s, line[BUFSIZ];
+ int v, lineno = 0, errors = 0;
+
+ lp->d_bbsize = BBSIZE; /* XXX */
+ lp->d_sbsize = SBSIZE; /* XXX */
+ while (fgets(line, sizeof(line) - 1, f)) {
+ lineno++;
+ if (cp = index(line,'\n'))
+ *cp = '\0';
+ cp = skip(line);
+ if (cp == NULL)
+ continue;
+ tp = index(cp, ':');
+ if (tp == NULL) {
+ fprintf(stderr, "line %d: syntax error\n", lineno);
+ errors++;
+ continue;
+ }
+ *tp++ = '\0', tp = skip(tp);
+ if (streq(cp, "type")) {
+ if (tp == NULL)
+ tp = "unknown";
+ cpp = dktypenames;
+ for (; cpp < &dktypenames[DKMAXTYPES]; cpp++)
+ if ((s = *cpp) && streq(s, tp)) {
+ lp->d_type = cpp - dktypenames;
+ goto next;
+ }
+ v = atoi(tp);
+ if ((unsigned)v >= DKMAXTYPES)
+ fprintf(stderr, "line %d:%s %d\n", lineno,
+ "Warning, unknown disk type", v);
+ lp->d_type = v;
+ continue;
+ }
+ if (streq(cp, "flags")) {
+ for (v = 0; (cp = tp) && *cp != '\0';) {
+ tp = word(cp);
+ if (streq(cp, "removeable"))
+ v |= D_REMOVABLE;
+ else if (streq(cp, "ecc"))
+ v |= D_ECC;
+ else if (streq(cp, "badsect"))
+ v |= D_BADSECT;
+ else {
+ fprintf(stderr,
+ "line %d: %s: bad flag\n",
+ lineno, cp);
+ errors++;
+ }
+ }
+ lp->d_flags = v;
+ continue;
+ }
+ if (streq(cp, "drivedata")) {
+ register int i;
+
+ for (i = 0; (cp = tp) && *cp != '\0' && i < NDDATA;) {
+ lp->d_drivedata[i++] = atoi(cp);
+ tp = word(cp);
+ }
+ continue;
+ }
+ if (sscanf(cp, "%d partitions", &v) == 1) {
+ if (v == 0 || (unsigned)v > MAXPARTITIONS) {
+ fprintf(stderr,
+ "line %d: bad # of partitions\n", lineno);
+ lp->d_npartitions = MAXPARTITIONS;
+ errors++;
+ } else
+ lp->d_npartitions = v;
+ continue;
+ }
+ if (tp == NULL)
+ tp = "";
+ if (streq(cp, "disk")) {
+ strncpy(lp->d_typename, tp, sizeof (lp->d_typename));
+ continue;
+ }
+ if (streq(cp, "label")) {
+ strncpy(lp->d_packname, tp, sizeof (lp->d_packname));
+ continue;
+ }
+ if (streq(cp, "bytes/sector")) {
+ v = atoi(tp);
+ if (v <= 0 || (v % 512) != 0) {
+ fprintf(stderr,
+ "line %d: %s: bad sector size\n",
+ lineno, tp);
+ errors++;
+ } else
+ lp->d_secsize = v;
+ continue;
+ }
+ if (streq(cp, "sectors/track")) {
+ v = atoi(tp);
+ if (v <= 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_nsectors = v;
+ continue;
+ }
+ if (streq(cp, "sectors/cylinder")) {
+ v = atoi(tp);
+ if (v <= 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_secpercyl = v;
+ continue;
+ }
+ if (streq(cp, "tracks/cylinder")) {
+ v = atoi(tp);
+ if (v <= 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_ntracks = v;
+ continue;
+ }
+ if (streq(cp, "cylinders")) {
+ v = atoi(tp);
+ if (v <= 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_ncylinders = v;
+ continue;
+ }
+ if (streq(cp, "rpm")) {
+ v = atoi(tp);
+ if (v <= 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_rpm = v;
+ continue;
+ }
+ if (streq(cp, "interleave")) {
+ v = atoi(tp);
+ if (v <= 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_interleave = v;
+ continue;
+ }
+ if (streq(cp, "trackskew")) {
+ v = atoi(tp);
+ if (v < 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_trackskew = v;
+ continue;
+ }
+ if (streq(cp, "cylinderskew")) {
+ v = atoi(tp);
+ if (v < 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_cylskew = v;
+ continue;
+ }
+ if (streq(cp, "headswitch")) {
+ v = atoi(tp);
+ if (v < 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_headswitch = v;
+ continue;
+ }
+ if (streq(cp, "track-to-track seek")) {
+ v = atoi(tp);
+ if (v < 0) {
+ fprintf(stderr, "line %d: %s: bad %s\n",
+ lineno, tp, cp);
+ errors++;
+ } else
+ lp->d_trkseek = v;
+ continue;
+ }
+ if ('a' <= *cp && *cp <= 'z' && cp[1] == '\0') {
+ unsigned part = *cp - 'a';
+
+ if (part > lp->d_npartitions) {
+ fprintf(stderr,
+ "line %d: bad partition name\n", lineno);
+ errors++;
+ continue;
+ }
+ pp = &lp->d_partitions[part];
+#define NXTNUM(n) { \
+ cp = tp, tp = word(cp); \
+ if (tp == NULL) \
+ tp = cp; \
+ (n) = atoi(cp); \
+ }
+
+ NXTNUM(v);
+ if (v < 0) {
+ fprintf(stderr,
+ "line %d: %s: bad partition size\n",
+ lineno, cp);
+ errors++;
+ } else
+ pp->p_size = v;
+ NXTNUM(v);
+ if (v < 0) {
+ fprintf(stderr,
+ "line %d: %s: bad partition offset\n",
+ lineno, cp);
+ errors++;
+ } else
+ pp->p_offset = v;
+ cp = tp, tp = word(cp);
+ cpp = fstypenames;
+ for (; cpp < &fstypenames[FSMAXTYPES]; cpp++)
+ if ((s = *cpp) && streq(s, cp)) {
+ pp->p_fstype = cpp - fstypenames;
+ goto gottype;
+ }
+ if (isdigit(*cp))
+ v = atoi(cp);
+ else
+ v = FSMAXTYPES;
+ if ((unsigned)v >= FSMAXTYPES) {
+ fprintf(stderr, "line %d: %s %s\n", lineno,
+ "Warning, unknown filesystem type", cp);
+ v = FS_UNUSED;
+ }
+ pp->p_fstype = v;
+ gottype:
+
+ switch (pp->p_fstype) {
+
+ case FS_UNUSED: /* XXX */
+ NXTNUM(pp->p_fsize);
+ if (pp->p_fsize == 0)
+ break;
+ NXTNUM(v);
+ pp->p_frag = v / pp->p_fsize;
+ break;
+
+ case FS_BSDFFS:
+ NXTNUM(pp->p_fsize);
+ if (pp->p_fsize == 0)
+ break;
+ NXTNUM(v);
+ pp->p_frag = v / pp->p_fsize;
+ NXTNUM(pp->p_cpg);
+ break;
+
+ default:
+ break;
+ }
+ continue;
+ }
+ fprintf(stderr, "line %d: %s: Unknown disklabel field\n",
+ lineno, cp);
+ errors++;
+ next:
+ ;
+ }
+ errors += checklabel(lp);
+ return (errors == 0);
+}
+
+/*
+ * Check disklabel for errors and fill in
+ * derived fields according to supplied values.
+ */
+checklabel(lp)
+ register struct disklabel *lp;
+{
+ register struct partition *pp;
+ int i, errors = 0;
+ char part;
+
+ if (lp->d_secsize == 0) {
+ fprintf(stderr, "sector size %d\n", lp->d_secsize);
+ return (1);
+ }
+ if (lp->d_nsectors == 0) {
+ fprintf(stderr, "sectors/track %d\n", lp->d_nsectors);
+ return (1);
+ }
+ if (lp->d_ntracks == 0) {
+ fprintf(stderr, "tracks/cylinder %d\n", lp->d_ntracks);
+ return (1);
+ }
+ if (lp->d_ncylinders == 0) {
+ fprintf(stderr, "cylinders/unit %d\n", lp->d_ncylinders);
+ errors++;
+ }
+ if (lp->d_rpm == 0)
+ Warning("revolutions/minute %d", lp->d_rpm);
+ if (lp->d_secpercyl == 0)
+ lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+ if (lp->d_secperunit == 0)
+ lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders;
+ if (lp->d_bbsize == 0) {
+ fprintf(stderr, "boot block size %d\n", lp->d_bbsize);
+ errors++;
+ } else if (lp->d_bbsize % lp->d_secsize)
+ Warning("boot block size %% sector-size != 0");
+ if (lp->d_sbsize == 0) {
+ fprintf(stderr, "super block size %d\n", lp->d_sbsize);
+ errors++;
+ } else if (lp->d_sbsize % lp->d_secsize)
+ Warning("super block size %% sector-size != 0");
+ if (lp->d_npartitions > MAXPARTITIONS)
+ Warning("number of partitions (%d) > MAXPARTITIONS (%d)",
+ lp->d_npartitions, MAXPARTITIONS);
+ for (i = 0; i < lp->d_npartitions; i++) {
+ part = 'a' + i;
+ pp = &lp->d_partitions[i];
+ if (pp->p_size == 0 && pp->p_offset != 0)
+ Warning("partition %c: size 0, but offset %d",
+ part, pp->p_offset);
+#ifdef notdef
+ if (pp->p_size % lp->d_secpercyl)
+ Warning("partition %c: size %% cylinder-size != 0",
+ part);
+ if (pp->p_offset % lp->d_secpercyl)
+ Warning("partition %c: offset %% cylinder-size != 0",
+ part);
+#endif
+ if (pp->p_offset > lp->d_secperunit) {
+ fprintf(stderr,
+ "partition %c: offset past end of unit\n", part);
+ errors++;
+ }
+ if (pp->p_offset + pp->p_size > lp->d_secperunit) {
+ fprintf(stderr,
+ "partition %c: partition extends past end of unit\n",
+ part);
+ errors++;
+ }
+ }
+ for (; i < MAXPARTITIONS; i++) {
+ part = 'a' + i;
+ pp = &lp->d_partitions[i];
+ if (pp->p_size || pp->p_offset)
+ Warning("unused partition %c: size %d offset %d",
+ 'a' + i, pp->p_size, pp->p_offset);
+ }
+ return (errors);
+}
+
+/*
+ * If we are installing a boot program that doesn't fit in d_bbsize
+ * we need to mark those partitions that the boot overflows into.
+ * This allows newfs to prevent creation of a filesystem where it might
+ * clobber bootstrap code.
+ */
+setbootflag(lp)
+ register struct disklabel *lp;
+{
+ register struct partition *pp;
+ int i, errors = 0;
+ char part;
+ u_long boffset;
+
+ if (bootbuf == 0)
+ return;
+ boffset = bootsize / lp->d_secsize;
+ for (i = 0; i < lp->d_npartitions; i++) {
+ part = 'a' + i;
+ pp = &lp->d_partitions[i];
+ if (pp->p_size == 0)
+ continue;
+ if (boffset <= pp->p_offset) {
+ if (pp->p_fstype == FS_BOOT)
+ pp->p_fstype = FS_UNUSED;
+ } else if (pp->p_fstype != FS_BOOT) {
+ if (pp->p_fstype != FS_UNUSED) {
+ fprintf(stderr,
+ "boot overlaps used partition %c\n",
+ part);
+ errors++;
+ } else {
+ pp->p_fstype = FS_BOOT;
+ Warning("boot overlaps partition %c, %s",
+ part, "marked as FS_BOOT");
+ }
+ }
+ }
+ if (errors) {
+ fprintf(stderr, "Cannot install boot program\n");
+ exit(4);
+ }
+}
+
+/*VARARGS1*/
+Warning(fmt, a1, a2, a3, a4, a5)
+ char *fmt;
+{
+
+ fprintf(stderr, "Warning, ");
+ fprintf(stderr, fmt, a1, a2, a3, a4, a5);
+ fprintf(stderr, "\n");
+}
+
+Perror(str)
+ char *str;
+{
+ fputs("disklabel: ", stderr); perror(str);
+ exit(4);
+}
+
+usage()
+{
+#if NUMBOOT > 0
+ fprintf(stderr,
+"%s\n\t%s\n%s\n\t%s\n%s\n\t%s\n%s\n\t%s\n%s\n\t%s\n%s\n\t%s\n%s\n\t%s\n%s\n\t%s\n",
+"usage: disklabel [-r] disk",
+ "(to read label)",
+"or disklabel -w [-r] disk type [ packid ]",
+ "(to write label with existing boot program)",
+"or disklabel -e [-r] disk",
+ "(to edit label)",
+"or disklabel -R [-r] disk protofile",
+ "(to restore label with existing boot program)",
+#if NUMBOOT > 1
+"or disklabel -B [ -b boot1 [ -s boot2 ] ] disk [ type ]",
+ "(to install boot program with existing label)",
+"or disklabel -w -B [ -b boot1 [ -s boot2 ] ] disk type [ packid ]",
+ "(to write label and boot program)",
+"or disklabel -R -B [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]",
+ "(to restore label and boot program)",
+#else
+"or disklabel -B [ -b bootprog ] disk [ type ]",
+ "(to install boot program with existing on-disk label)",
+"or disklabel -w -B [ -b bootprog ] disk type [ packid ]",
+ "(to write label and install boot program)",
+"or disklabel -R -B [ -b bootprog ] disk protofile [ type ]",
+ "(to restore label and install boot program)",
+#endif
+"or disklabel [-NW] disk",
+ "(to write disable/enable label)");
+#else
+ fprintf(stderr, "%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n",
+"usage: disklabel [-r] disk", "(to read label)",
+"or disklabel -w [-r] disk type [ packid ]", "(to write label)",
+"or disklabel -e [-r] disk", "(to edit label)",
+"or disklabel -R [-r] disk protofile", "(to restore label)",
+"or disklabel [-NW] disk", "(to write disable/enable label)");
+#endif
+ exit(1);
+}
diff --git a/sbin/bsdlabel/disklabel.5.5 b/sbin/bsdlabel/disklabel.5.5
new file mode 100644
index 000000000000..fb6f6cd14d58
--- /dev/null
+++ b/sbin/bsdlabel/disklabel.5.5
@@ -0,0 +1,384 @@
+.\" Copyright (c) 1987, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Symmetric Computer Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)disklabel.5.5 8.1 (Berkeley) 6/5/93
+.\"
+.Dd June 5, 1993
+.Dt DISKLABEL 5
+.Os
+.Sh NAME
+.Nm disklabel
+.Nd disk pack label
+.Sh SYNOPSIS
+.Fd #include <sys/disklabel.h>
+.Sh DESCRIPTION
+Each disk or disk pack on a system may contain a disk label
+which provides detailed information
+about the geometry of the disk and the partitions into which the disk
+is divided.
+It should be initialized when the disk is formatted,
+and may be changed later with the
+.Xr disklabel 8
+program.
+This information is used by the system disk driver and by the bootstrap
+program to determine how to program the drive
+and where to find the filesystems on the disk partitions.
+Additional information is used by the filesystem in order
+to use the disk most efficiently and to locate important filesystem information.
+The description of each partition contains an identifier for the partition
+type (standard filesystem, swap area, etc.).
+The filesystem updates the in-core copy of the label if it contains
+incomplete information about the filesystem.
+.Pp
+The label is located in sector number
+.Dv LABELSECTOR
+of the drive, usually sector 0 where it may be found
+without any information about the disk geometry.
+It is at an offset
+.Dv LABELOFFSET
+from the beginning of the sector, to allow room for the initial bootstrap.
+The disk sector containing the label is normally made read-only
+so that it is not accidentally overwritten by pack-to-pack copies
+or swap operations;
+the
+.Dv DIOCWLABEL
+.Xr ioctl 2 ,
+which is done as needed by the
+.Xr disklabel
+program.
+.Pp
+A copy of the in-core label for a disk can be obtained with the
+.Dv DIOCGDINFO
+.Xr ioctl ;
+this works with a file descriptor for a block or character (``raw'') device
+for any partition of the disk.
+The in-core copy of the label is set by the
+.Dv DIOCSDINFO
+.Xr ioctl .
+The offset of a partition cannot generally be changed while it is open,
+nor can it be made smaller while it is open.
+One exception is that any change is allowed if no label was found
+on the disk, and the driver was able to construct only a skeletal label
+without partition information.
+Finally, the
+.Dv DIOCWDINFO
+.Xr ioctl
+operation sets the in-core label and then updates the on-disk label;
+there must be an existing label on the disk for this operation to succeed.
+Thus, the initial label for a disk or disk pack must be installed
+by writing to the raw disk.
+All of these operations are normally done using
+.Xr disklabel .
+.Pp
+The format of the disk label, as specified in
+.Aw Pa sys/disklabel.h ,
+is
+.Bd -literal
+/*
+* Disk description table, see disktab(5)
+*/
+#define DISKTAB "/etc/disktab"
+
+/*
+* Each disk has a label which includes information about the hardware
+* disk geometry, filesystem partitions, and drive specific information.
+* The label is in block 0 or 1, possibly offset from the beginning
+* to leave room for a bootstrap, etc.
+*/
+
+#ifndef LABELSECTOR
+#define LABELSECTOR 0 /* sector containing label */
+#endif
+
+#ifndef LABELOFFSET
+#define LABELOFFSET 64 /* offset of label in sector */
+#endif
+
+#define DISKMAGIC ((u_long) 0x82564557) /* The disk magic number */
+#ifndef MAXPARTITIONS
+#define MAXPARTITIONS 8
+#endif
+
+#ifndef LOCORE
+struct disklabel {
+ u_long d_magic; /* the magic number */
+ short d_type; /* drive type */
+ short d_subtype; /* controller/d_type specific */
+ char d_typename[16]; /* type name, e.g. "eagle" */
+ /*
+ * d_packname contains the pack identifier and is returned when
+ * the disklabel is read off the disk or in-core copy.
+ * d_boot0 and d_boot1 are the (optional) names of the
+ * primary (block 0) and secondary (block 1-15) bootstraps
+ * as found in /usr/mdec. These are returned when using
+ * getdiskbyname(3)
+ to retrieve the values from /etc/disktab.
+ */
+#if defined(KERNEL) || defined(STANDALONE)
+ char d_packname[16]; /* pack identifier */
+#else
+ union {
+ char un_d_packname[16]; /* pack identifier */
+ struct {
+ char *un_d_boot0; /* primary bootstrap name */
+ char *un_d_boot1; /* secondary bootstrap name */
+ } un_b;
+ } d_un;
+
+#define d_packname d_un.un_d_packname
+#define d_boot0 d_un.un_b.un_d_boot0
+#define d_boot1 d_un.un_b.un_d_boot1
+#endif /* ! KERNEL or STANDALONE */
+
+ /* disk geometry: */
+ u_long d_secsize; /* # of bytes per sector */
+ u_long d_nsectors; /* # of data sectors per track */
+ u_long d_ntracks; /* # of tracks per cylinder */
+ u_long d_ncylinders; /* # of data cylinders per unit */
+ u_long d_secpercyl; /* # of data sectors per cylinder */
+ u_long d_secperunit; /* # of data sectors per unit */
+ /*
+ * Spares (bad sector replacements) below
+ * are not counted in d_nsectors or d_secpercyl.
+ * Spare sectors are assumed to be physical sectors
+ * which occupy space at the end of each track and/or cylinder.
+ */
+ u_short d_sparespertrack; /* # of spare sectors per track */
+ u_short d_sparespercyl; /* # of spare sectors per cylinder */
+ /*
+ * Alternate cylinders include maintenance, replacement,
+ * configuration description areas, etc.
+ */
+ u_long d_acylinders; /* # of alt. cylinders per unit */
+
+ /* hardware characteristics: */
+ /*
+ * d_interleave, d_trackskew and d_cylskew describe perturbations
+ * in the media format used to compensate for a slow controller.
+ * Interleave is physical sector interleave, set up by the formatter
+ * or controller when formatting. When interleaving is in use,
+ * logically adjacent sectors are not physically contiguous,
+ * but instead are separated by some number of sectors.
+ * It is specified as the ratio of physical sectors traversed
+ * per logical sector. Thus an interleave of 1:1 implies contiguous
+ * layout, while 2:1 implies that logical sector 0 is separated
+ * by one sector from logical sector 1.
+ * d_trackskew is the offset of sector 0 on track N
+ * relative to sector 0 on track N-1 on the same cylinder.
+ * Finally, d_cylskew is the offset of sector 0 on cylinder N
+ * relative to sector 0 on cylinder N-1.
+ */
+ u_short d_rpm; /* rotational speed */
+ u_short d_interleave; /* hardware sector interleave */
+ u_short d_trackskew; /* sector 0 skew, per track */
+ u_short d_cylskew; /* sector 0 skew, per cylinder */
+ u_long d_headswitch; /* head switch time, usec */
+ u_long d_trkseek; /* track-to-track seek, usec */
+ u_long d_flags; /* generic flags */
+#define NDDATA 5
+ u_long d_drivedata[NDDATA]; /* drive-type specific information */
+#define NSPARE 5
+ u_long d_spare[NSPARE]; /* reserved for future use */
+ u_long d_magic2; /* the magic number (again) */
+ u_short d_checksum; /* xor of data incl. partitions */
+
+ /* filesystem and partition information: */
+ u_short d_npartitions; /* number of partitions in following */
+ u_long d_bbsize; /* size of boot area at sn0, bytes */
+ u_long d_sbsize; /* max size of fs superblock, bytes */
+ struct partition { /* the partition table */
+ u_long p_size; /* number of sectors in partition */
+ u_long p_offset; /* starting sector */
+ u_long p_fsize; /* filesystem basic fragment size */
+ u_char p_fstype; /* filesystem type, see below */
+ u_char p_frag; /* filesystem fragments per block */
+ union {
+ u_short cpg; /* UFS: FS cylinders per group */
+ u_short sgs; /* LFS: FS segment shift */
+ } __partition_u1;
+#define p_cpg __partition_u1.cpg
+#define p_sgs __partition_u1.sgs
+ u_short p_cpg; /* filesystem cylinders per group */
+ } d_partitions[MAXPARTITIONS]; /* actually may be more */
+};
+
+/* d_type values: */
+#define DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */
+#define DTYPE_MSCP 2 /* MSCP */
+#define DTYPE_DEC 3 /* other DEC (rk, rl) */
+#define DTYPE_SCSI 4 /* SCSI */
+#define DTYPE_ESDI 5 /* ESDI interface */
+#define DTYPE_ST506 6 /* ST506 etc. */
+#define DTYPE_HPIB 7 /* CS/80 on HP-IB */
+#define DTYPE_HPFL 8 /* HP Fiber-link */
+#define DTYPE_FLOPPY 10 /* floppy */
+
+#ifdef DKTYPENAMES
+static char *dktypenames[] = {
+ "unknown",
+ "SMD",
+ "MSCP",
+ "old DEC",
+ "SCSI",
+ "ESDI",
+ "ST506",
+ "HP-IB",
+ "HP-FL",
+ "type 9",
+ "floppy",
+ 0
+};
+#define DKMAXTYPES (sizeof(dktypenames) / sizeof(dktypenames[0]) - 1)
+#endif
+
+/*
+* Filesystem type and version.
+* Used to interpret other filesystem-specific
+* per-partition information.
+*/
+#define FS_UNUSED 0 /* unused */
+#define FS_SWAP 1 /* swap */
+#define FS_V6 2 /* Sixth Edition */
+#define FS_V7 3 /* Seventh Edition */
+#define FS_SYSV 4 /* System V */
+#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */
+#define FS_V8 6 /* Eighth Edition, 4K blocks */
+#define FS_BSDFFS 7 /* 4.2BSD fast file system */
+#define FS_MSDOS 8 /* MSDOS file system */
+#define FS_BSDLFS 9 /* 4.4BSD log-structured file system */
+#define FS_OTHER 10 /* in use, but unknown/unsupported */
+#define FS_HPFS 11 /* OS/2 high-performance file system */
+#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */
+#define FS_BOOT 13 /* partition contains bootstrap */
+
+#ifdef DKTYPENAMES
+static char *fstypenames[] = {
+ "unused",
+ "swap",
+ "Version 6",
+ "Version 7",
+ "System V",
+ "4.1BSD",
+ "Eighth Edition",
+ "4.2BSD",
+ "MSDOS",
+ "4.4LFS",
+ "unknown",
+ "HPFS",
+ "ISO9660",
+ "boot",
+ 0
+};
+#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1)
+#endif
+
+/*
+* flags shared by various drives:
+*/
+#define D_REMOVABLE 0x01 /* removable media */
+#define D_ECC 0x02 /* supports ECC */
+#define D_BADSECT 0x04 /* supports bad sector forw. */
+#define D_RAMDISK 0x08 /* disk emulator */
+#define D_CHAIN 0x10 /* can do back-back transfers */
+
+/*
+* Drive data for SMD.
+*/
+
+#define d_smdflags d_drivedata[0]
+#define D_SSE 0x1 /* supports skip sectoring */
+#define d_mindist d_drivedata[1]
+#define d_maxdist d_drivedata[2]
+#define d_sdist d_drivedata[3]
+
+/*
+* Drive data for ST506.
+*/
+#define d_precompcyl d_drivedata[0]
+#define d_gap3 d_drivedata[1] /* used only when formatting */
+
+/*
+ * Drive data for SCSI.
+ */
+#define d_blind d_drivedata[0]
+
+#ifndef LOCORE
+/*
+* Structure used to perform a format
+* or other raw operation, returning data
+* and/or register values.
+* Register identification and format
+* are device- and driver-dependent.
+*/
+struct format_op {
+ char *df_buf;
+ int df_count; /* value-result */
+ daddr_t df_startblk;
+ int df_reg[8]; /* result */
+};
+
+/*
+* Structure used internally to retrieve
+* information about a partition on a disk.
+*/
+struct partinfo {
+ struct disklabel *disklab;
+ struct partition *part;
+};
+
+/*
+* Disk-specific ioctls.
+*/
+ /* get and set disklabel; DIOCGPART used internally */
+#define DIOCGDINFO _IOR('d', 101, struct disklabel) /* get */
+#define DIOCSDINFO _IOW('d', 102, struct disklabel) /* set */
+#define DIOCWDINFO _IOW('d', 103, struct disklabel) /* set, update disk */
+#define DIOCGPART _IOW('d', 104, struct partinfo) /* get partition */
+
+/* do format operation, read or write */
+#define DIOCRFORMAT _IOWR('d', 105, struct format_op)
+#define DIOCWFORMAT _IOWR('d', 106, struct format_op)
+
+#define DIOCSSTEP _IOW('d', 107, int) /* set step rate */
+#define DIOCSRETRIES _IOW('d', 108, int) /* set # of retries */
+#define DIOCWLABEL _IOW('d', 109, int) /* write en/disable label */
+
+#define DIOCSBAD _IOW('d', 110, struct dkbad) /* set kernel dkbad */
+
+#endif LOCORE
+.Ed
+.Sh SEE ALSO
+.Xr disktab 5 ,
+.Xr disklabel 8
+.Sh HISTORY
diff --git a/sbin/bsdlabel/dkcksum.c b/sbin/bsdlabel/dkcksum.c
new file mode 100644
index 000000000000..f7a1e4917df6
--- /dev/null
+++ b/sbin/bsdlabel/dkcksum.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dkcksum.c 8.1 (Berkeley) 6/5/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/disklabel.h>
+
+u_short
+dkcksum(lp)
+ register struct disklabel *lp;
+{
+ register u_short *start, *end;
+ register u_short sum = 0;
+
+ start = (u_short *)lp;
+ end = (u_short *)&lp->d_partitions[lp->d_npartitions];
+ while (start < end)
+ sum ^= *start++;
+ return (sum);
+}
diff --git a/sbin/bsdlabel/pathnames.h b/sbin/bsdlabel/pathnames.h
new file mode 100644
index 000000000000..def3297d205e
--- /dev/null
+++ b/sbin/bsdlabel/pathnames.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/5/93
+ */
+
+#include <paths.h>
+
+#define _PATH_BOOTDIR "/usr/mdec"
+#undef _PATH_TMP
+#define _PATH_TMP "/tmp/EdDk.aXXXXXX"