aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/bsdlabel/bsdlabel.c37
-rw-r--r--sbin/fdisk/Makefile4
-rw-r--r--sbin/fdisk/fdisk.c48
-rw-r--r--sbin/fdisk/fdisk_mbr_enc.c77
-rw-r--r--sbin/fdisk/fdisk_mbr_enc.h34
-rw-r--r--sbin/sunlabel/Makefile4
-rw-r--r--sbin/sunlabel/sun_disklabel.h125
-rw-r--r--sbin/sunlabel/sunlabel.c3
-rw-r--r--sbin/sunlabel/sunlabel_enc.c184
9 files changed, 436 insertions, 80 deletions
diff --git a/sbin/bsdlabel/bsdlabel.c b/sbin/bsdlabel/bsdlabel.c
index f013cde3ef09..943f37207fc2 100644
--- a/sbin/bsdlabel/bsdlabel.c
+++ b/sbin/bsdlabel/bsdlabel.c
@@ -381,8 +381,6 @@ static int
writelabel(void)
{
int i, fd, serrno;
- struct gctl_req *grq;
- char const *errstr;
struct disklabel *lp = &lab;
if (disable_write) {
@@ -423,39 +421,8 @@ writelabel(void)
return (1);
}
- /* Give up if GEOM_BSD is not available. */
- if (geom_class_available("BSD") == 0) {
- warnc(serrno, "%s", specname);
- return (1);
- }
-
- grq = gctl_get_handle();
- gctl_ro_param(grq, "verb", -1, "write label");
- gctl_ro_param(grq, "class", -1, "BSD");
- gctl_ro_param(grq, "geom", -1, pname);
- gctl_ro_param(grq, "label", 148+16*8,
- bootarea + labeloffset + labelsoffset * lab.d_secsize);
- errstr = gctl_issue(grq);
- if (errstr != NULL) {
- warnx("%s", errstr);
- gctl_free(grq);
- return(1);
- }
- gctl_free(grq);
- if (installboot) {
- grq = gctl_get_handle();
- gctl_ro_param(grq, "verb", -1, "write bootcode");
- gctl_ro_param(grq, "class", -1, "BSD");
- gctl_ro_param(grq, "geom", -1, pname);
- gctl_ro_param(grq, "bootcode", BBSIZE, bootarea);
- errstr = gctl_issue(grq);
- if (errstr != NULL) {
- warnx("%s", errstr);
- gctl_free(grq);
- return (1);
- }
- gctl_free(grq);
- }
+ warnc(serrno, "%s", specname);
+ return (1);
} else {
if (write(fd, bootarea, bbsize) != bbsize) {
warn("write %s", specname);
diff --git a/sbin/fdisk/Makefile b/sbin/fdisk/Makefile
index 410f268a39d1..eaed0aea04aa 100644
--- a/sbin/fdisk/Makefile
+++ b/sbin/fdisk/Makefile
@@ -2,12 +2,10 @@
PACKAGE=runtime
PROG= fdisk
-SRCS= fdisk.c geom_mbr_enc.c
+SRCS= fdisk.c fdisk_mbr_enc.c
WARNS?= 4
MAN= fdisk.8
-.PATH: ${SRCTOP}/sys/geom
-
LIBADD= geom
.include <bsd.prog.mk>
diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c
index 3e4ef3cba3f3..a9afd50ed441 100644
--- a/sbin/fdisk/fdisk.c
+++ b/sbin/fdisk/fdisk.c
@@ -47,6 +47,8 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
+#include "fdisk_mbr_enc.h"
+
static int iotest;
#define NO_DISK_SECTORS ((u_int32_t)-1)
@@ -786,47 +788,17 @@ geom_class_available(const char *name)
static int
write_disk(off_t sector, void *buf)
{
- struct gctl_req *grq;
- const char *errmsg;
- char *pname;
- int error;
-
- /* Check that GEOM_MBR is available */
- if (geom_class_available("MBR") != 0) {
- grq = gctl_get_handle();
- gctl_ro_param(grq, "verb", -1, "write MBR");
- gctl_ro_param(grq, "class", -1, "MBR");
- pname = g_providername(fd);
- if (pname == NULL) {
- warn("Error getting providername for %s", disk);
- return (-1);
- }
- gctl_ro_param(grq, "geom", -1, pname);
- gctl_ro_param(grq, "data", secsize, buf);
- errmsg = gctl_issue(grq);
- free(pname);
- if (errmsg == NULL) {
- gctl_free(grq);
- return(0);
- }
- if (!q_flag)
- warnx("GEOM_MBR: %s", errmsg);
- gctl_free(grq);
- } else {
- /*
- * Try to write MBR directly. This may help when disk
- * is not in use.
- * XXX: hardcoded sectorsize
- */
- error = pwrite(fd, buf, secsize, (sector * 512));
- if (error == secsize)
- return (0);
- }
+ ssize_t wr;
/*
- * GEOM_MBR is not available or failed to write MBR.
- * Now check that we have GEOM_PART and recommend to use gpart (8).
+ * Try to write MBR directly. This may help when disk
+ * is not in use.
+ * XXX: hardcoded sectorsize
*/
+ wr = pwrite(fd, buf, secsize, (sector * 512));
+ if (wr == secsize)
+ return (0);
+
if (geom_class_available("PART") != 0)
warnx("Failed to write MBR. Try to use gpart(8).");
else
diff --git a/sbin/fdisk/fdisk_mbr_enc.c b/sbin/fdisk/fdisk_mbr_enc.c
new file mode 100644
index 000000000000..1202896276c6
--- /dev/null
+++ b/sbin/fdisk/fdisk_mbr_enc.c
@@ -0,0 +1,77 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2003 Poul-Henning Kamp
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+/* Functions to encode or decode struct dos_partition into a bytestream
+ * of correct endianness and packing. These functions do no validation
+ * or sanity checking, they only pack/unpack the fields correctly.
+ *
+ * NB! This file must be usable both in kernel and userland.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/diskmbr.h>
+#include <sys/endian.h>
+
+#include "fdisk_mbr_enc.h"
+
+void
+dos_partition_dec(void const *pp, struct dos_partition *d)
+{
+ unsigned char const *p = pp;
+
+ d->dp_flag = p[0];
+ d->dp_shd = p[1];
+ d->dp_ssect = p[2];
+ d->dp_scyl = p[3];
+ d->dp_typ = p[4];
+ d->dp_ehd = p[5];
+ d->dp_esect = p[6];
+ d->dp_ecyl = p[7];
+ d->dp_start = le32dec(p + 8);
+ d->dp_size = le32dec(p + 12);
+}
+
+void
+dos_partition_enc(void *pp, struct dos_partition *d)
+{
+ unsigned char *p = pp;
+
+ p[0] = d->dp_flag;
+ p[1] = d->dp_shd;
+ p[2] = d->dp_ssect;
+ p[3] = d->dp_scyl;
+ p[4] = d->dp_typ;
+ p[5] = d->dp_ehd;
+ p[6] = d->dp_esect;
+ p[7] = d->dp_ecyl;
+ le32enc(p + 8, d->dp_start);
+ le32enc(p + 12, d->dp_size);
+}
diff --git a/sbin/fdisk/fdisk_mbr_enc.h b/sbin/fdisk/fdisk_mbr_enc.h
new file mode 100644
index 000000000000..5a1a6bf70fce
--- /dev/null
+++ b/sbin/fdisk/fdisk_mbr_enc.h
@@ -0,0 +1,34 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2019 Conrad Meyer <cem@FreeBSD.org>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#pragma once
+
+struct dos_partition;
+void dos_partition_dec(void const *pp, struct dos_partition *d);
+void dos_partition_enc(void *pp, struct dos_partition *d);
diff --git a/sbin/sunlabel/Makefile b/sbin/sunlabel/Makefile
index 0cf449743ec8..05ae28c0da20 100644
--- a/sbin/sunlabel/Makefile
+++ b/sbin/sunlabel/Makefile
@@ -1,9 +1,7 @@
# $FreeBSD$
-.PATH: ${SRCTOP}/sys/geom
-
PROG= sunlabel
-SRCS= sunlabel.c geom_sunlabel_enc.c
+SRCS= sunlabel.c sunlabel_enc.c
MAN= sunlabel.8
.if ${MACHINE_CPUARCH} == "sparc64"
diff --git a/sbin/sunlabel/sun_disklabel.h b/sbin/sunlabel/sun_disklabel.h
new file mode 100644
index 000000000000..942e1d3d11c2
--- /dev/null
+++ b/sbin/sunlabel/sun_disklabel.h
@@ -0,0 +1,125 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2004,2005 Joerg Wunsch
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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. 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.
+ *
+ * @(#)sun_disklabel.h 8.1 (Berkeley) 6/11/93
+ * $NetBSD: disklabel.h,v 1.2 1998/08/22 14:55:28 mrg Exp $
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_SUN_DISKLABEL_H_
+#define _SYS_SUN_DISKLABEL_H_
+
+/*
+ * SunOS/Solaris disk label layout (partial).
+ *
+ * Suns disk label format contains a lot of historical baggage which we
+ * ignore entirely. The structure below contains the relevant bits and the
+ * _enc/_dec functions encode/decode only these fields.
+ */
+
+#define SUN_DKMAGIC 55998
+#define SUN_NPART 8
+#define SUN_RAWPART 2
+#define SUN_SIZE 512
+#define SUN_VTOC_VERSION 1
+#define SUN_VTOC_SANE 0x600DDEEE /* SVR4-compatible VTOC is "sane". */
+#define SUN_VOLNAME_LEN 8
+/*
+ * XXX: I am actually not sure if this should be "16 sectors" or "8192 bytes".
+ * XXX: Considering that Sun went to the effort of getting 512 byte compatible
+ * XXX: CDROM drives produced my guess is that Sun computers stand little or
+ * XXX: even no chance of running, much less booting on !=512 byte media.
+ * XXX: Define this is in terms of bytes since that is easier for us.
+ */
+#define SUN_BOOTSIZE 8192
+
+/* partition info */
+struct sun_dkpart {
+ u_int32_t sdkp_cyloffset; /* starting cylinder */
+ u_int32_t sdkp_nsectors; /* number of sectors */
+};
+
+struct sun_vtoc_info {
+ u_int16_t svtoc_tag; /* partition tag */
+ u_int16_t svtoc_flag; /* partition flags */
+};
+
+/* known partition tag values */
+#define VTOC_UNASSIGNED 0x00
+#define VTOC_BOOT 0x01
+#define VTOC_ROOT 0x02
+#define VTOC_SWAP 0x03
+#define VTOC_USR 0x04
+#define VTOC_BACKUP 0x05 /* "c" partition, covers entire disk */
+#define VTOC_STAND 0x06
+#define VTOC_VAR 0x07
+#define VTOC_HOME 0x08
+#define VTOC_ALTSCTR 0x09 /* alternate sector partition */
+#define VTOC_CACHE 0x0a /* Solaris cachefs partition */
+#define VTOC_VXVM_PUB 0x0e /* VxVM public region */
+#define VTOC_VXVM_PRIV 0x0f /* VxVM private region */
+
+/* VTOC partition flags */
+#define VTOC_UNMNT 0x01 /* unmountable partition */
+#define VTOC_RONLY 0x10 /* partition is read/only */
+
+struct sun_disklabel {
+ char sl_text[128];
+
+ /* SVR4 VTOC information */
+ u_int32_t sl_vtoc_vers; /* == SUN_VTOC_VERSION */
+ char sl_vtoc_volname[SUN_VOLNAME_LEN];
+ u_int16_t sl_vtoc_nparts; /* == SUN_NPART */
+ struct sun_vtoc_info sl_vtoc_map[SUN_NPART]; /* partition tag/flag */
+ u_int32_t sl_vtoc_sane; /* == SUN_VTOC_SANE */
+
+ /* Sun label information */
+ u_int16_t sl_rpm; /* rotational speed */
+ u_int16_t sl_pcylinders; /* number of physical cyls */
+ u_int16_t sl_sparespercyl; /* spare sectors per cylinder */
+ u_int16_t sl_interleave; /* interleave factor */
+ u_int16_t sl_ncylinders; /* data cylinders */
+ u_int16_t sl_acylinders; /* alternate cylinders */
+ u_int16_t sl_ntracks; /* tracks per cylinder */
+ u_int16_t sl_nsectors; /* sectors per track */
+ struct sun_dkpart sl_part[SUN_NPART]; /* partition layout */
+ u_int16_t sl_magic; /* == SUN_DKMAGIC */
+};
+
+int sunlabel_dec(void const *pp, struct sun_disklabel *sl);
+void sunlabel_enc(void *pp, struct sun_disklabel *sl);
+
+#endif /* _SYS_SUN_DISKLABEL_H_ */
diff --git a/sbin/sunlabel/sunlabel.c b/sbin/sunlabel/sunlabel.c
index d1d5cea42d45..c4f59b1170c6 100644
--- a/sbin/sunlabel/sunlabel.c
+++ b/sbin/sunlabel/sunlabel.c
@@ -75,7 +75,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/disk.h>
#include <sys/ioctl.h>
-#include <sys/sun_disklabel.h>
#include <sys/wait.h>
#include <ctype.h>
@@ -89,6 +88,8 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
+#include "sun_disklabel.h"
+
#define _PATH_TMPFILE "/tmp/EdDk.XXXXXXXXXX"
#define _PATH_BOOT "/boot/boot1"
diff --git a/sbin/sunlabel/sunlabel_enc.c b/sbin/sunlabel/sunlabel_enc.c
new file mode 100644
index 000000000000..4146442589e5
--- /dev/null
+++ b/sbin/sunlabel/sunlabel_enc.c
@@ -0,0 +1,184 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2003 Jake Burkholder
+ * Copyright (c) 2003 Poul-Henning Kamp
+ * Copyright (c) 2004,2005 Joerg Wunsch
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+/* Functions to encode or decode struct sun_disklabel into a bytestream
+ * of correct endianness and packing.
+ *
+ * NB! This file must be usable both in kernel and userland.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/endian.h>
+#include <sys/errno.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#else
+#include <string.h>
+#endif
+#include "sun_disklabel.h"
+
+#define SL_TEXT 0x0
+#define SL_TEXT_SIZEOF 0x80
+#define SL_VTOC_VERS 0x80
+#define SL_VTOC_VOLNAME 0x84
+#define SL_VTOC_NPART 0x8c
+#define SL_VTOC_MAP 0x8e
+#define SL_VTOC_SANITY 0xbc
+#define SL_RPM 0x1a4
+#define SL_PCYLINDERS 0x1a6
+#define SL_SPARESPERCYL 0x1a8
+#define SL_INTERLEAVE 0x1ae
+#define SL_NCYLINDERS 0x1b0
+#define SL_ACYLINDERS 0x1b2
+#define SL_NTRACKS 0x1b4
+#define SL_NSECTORS 0x1b6
+#define SL_PART 0x1bc
+#define SL_MAGIC 0x1fc
+#define SL_CKSUM 0x1fe
+
+#define SDKP_CYLOFFSET 0
+#define SDKP_NSECTORS 0x4
+#define SDKP_SIZEOF 0x8 /* size of a partition entry */
+
+#define SVTOC_TAG 0
+#define SVTOC_FLAG 0x2
+#define SVTOC_SIZEOF 0x4 /* size of a VTOC tag/flag entry */
+
+/*
+ * Decode the relevant fields of a sun disk label, and return zero if the
+ * magic and checksum works out OK.
+ */
+int
+sunlabel_dec(void const *pp, struct sun_disklabel *sl)
+{
+ const uint8_t *p;
+ size_t i;
+ u_int u;
+ uint32_t vtocsane;
+ uint16_t npart;
+
+ p = pp;
+ for (i = 0; i < sizeof(sl->sl_text); i++)
+ sl->sl_text[i] = p[SL_TEXT + i];
+ sl->sl_rpm = be16dec(p + SL_RPM);
+ sl->sl_pcylinders = be16dec(p + SL_PCYLINDERS);
+ sl->sl_sparespercyl = be16dec(p + SL_SPARESPERCYL);
+ sl->sl_interleave = be16dec(p + SL_INTERLEAVE);
+ sl->sl_ncylinders = be16dec(p + SL_NCYLINDERS);
+ sl->sl_acylinders = be16dec(p + SL_ACYLINDERS);
+ sl->sl_ntracks = be16dec(p + SL_NTRACKS);
+ sl->sl_nsectors = be16dec(p + SL_NSECTORS);
+ for (i = 0; i < SUN_NPART; i++) {
+ sl->sl_part[i].sdkp_cyloffset = be32dec(p + SL_PART +
+ (i * SDKP_SIZEOF) + SDKP_CYLOFFSET);
+ sl->sl_part[i].sdkp_nsectors = be32dec(p + SL_PART +
+ (i * SDKP_SIZEOF) + SDKP_NSECTORS);
+ }
+ sl->sl_magic = be16dec(p + SL_MAGIC);
+ vtocsane = be32dec(p + SL_VTOC_SANITY);
+ npart = be16dec(p + SL_VTOC_NPART);
+ if (vtocsane == SUN_VTOC_SANE && npart == SUN_NPART) {
+ /*
+ * Seems we've got SVR4-compatible VTOC information
+ * as well, decode it.
+ */
+ sl->sl_vtoc_sane = vtocsane;
+ sl->sl_vtoc_vers = be32dec(p + SL_VTOC_VERS);
+ memcpy(sl->sl_vtoc_volname, p + SL_VTOC_VOLNAME,
+ SUN_VOLNAME_LEN);
+ sl->sl_vtoc_nparts = SUN_NPART;
+ for (i = 0; i < SUN_NPART; i++) {
+ sl->sl_vtoc_map[i].svtoc_tag = be16dec(p +
+ SL_VTOC_MAP + (i * SVTOC_SIZEOF) + SVTOC_TAG);
+ sl->sl_vtoc_map[i].svtoc_flag = be16dec(p +
+ SL_VTOC_MAP + (i * SVTOC_SIZEOF) + SVTOC_FLAG);
+ }
+ }
+ for (i = u = 0; i < SUN_SIZE; i += 2)
+ u ^= be16dec(p + i);
+ if (u == 0 && sl->sl_magic == SUN_DKMAGIC)
+ return (0);
+ else
+ return (EINVAL);
+}
+
+/*
+ * Encode the relevant fields into a sun disklabel, compute new checksum.
+ */
+void
+sunlabel_enc(void *pp, struct sun_disklabel *sl)
+{
+ uint8_t *p;
+ size_t i;
+ u_int u;
+
+ p = pp;
+ for (i = 0; i < SL_TEXT_SIZEOF; i++)
+ p[SL_TEXT + i] = sl->sl_text[i];
+ be16enc(p + SL_RPM, sl->sl_rpm);
+ be16enc(p + SL_PCYLINDERS, sl->sl_pcylinders);
+ be16enc(p + SL_SPARESPERCYL, sl->sl_sparespercyl);
+ be16enc(p + SL_INTERLEAVE, sl->sl_interleave);
+ be16enc(p + SL_NCYLINDERS, sl->sl_ncylinders);
+ be16enc(p + SL_ACYLINDERS, sl->sl_acylinders);
+ be16enc(p + SL_NTRACKS, sl->sl_ntracks);
+ be16enc(p + SL_NSECTORS, sl->sl_nsectors);
+ for (i = 0; i < SUN_NPART; i++) {
+ be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_CYLOFFSET,
+ sl->sl_part[i].sdkp_cyloffset);
+ be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_NSECTORS,
+ sl->sl_part[i].sdkp_nsectors);
+ }
+ be16enc(p + SL_MAGIC, sl->sl_magic);
+ if (sl->sl_vtoc_sane == SUN_VTOC_SANE
+ && sl->sl_vtoc_nparts == SUN_NPART) {
+ /*
+ * Write SVR4-compatible VTOC elements.
+ */
+ be32enc(p + SL_VTOC_VERS, sl->sl_vtoc_vers);
+ be32enc(p + SL_VTOC_SANITY, SUN_VTOC_SANE);
+ memcpy(p + SL_VTOC_VOLNAME, sl->sl_vtoc_volname,
+ SUN_VOLNAME_LEN);
+ be16enc(p + SL_VTOC_NPART, SUN_NPART);
+ for (i = 0; i < SUN_NPART; i++) {
+ be16enc(p + SL_VTOC_MAP + (i * SVTOC_SIZEOF)
+ + SVTOC_TAG,
+ sl->sl_vtoc_map[i].svtoc_tag);
+ be16enc(p + SL_VTOC_MAP + (i * SVTOC_SIZEOF)
+ + SVTOC_FLAG,
+ sl->sl_vtoc_map[i].svtoc_flag);
+ }
+ }
+ for (i = u = 0; i < SUN_SIZE; i += 2)
+ u ^= be16dec(p + i);
+ be16enc(p + SL_CKSUM, u);
+}