move mksuncd to here (but still only sparc64 build)
authorderaadt <deraadt@openbsd.org>
Fri, 22 Aug 2008 15:48:32 +0000 (15:48 +0000)
committerderaadt <deraadt@openbsd.org>
Fri, 22 Aug 2008 15:48:32 +0000 (15:48 +0000)
usr.sbin/Makefile
usr.sbin/mksuncd/Makefile [new file with mode: 0644]
usr.sbin/mksuncd/mksuncd.1 [new file with mode: 0644]
usr.sbin/mksuncd/mksuncd.c [new file with mode: 0644]

index af9a155..b8999a6 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.143 2008/08/22 15:18:54 deraadt Exp $
+#      $OpenBSD: Makefile,v 1.144 2008/08/22 15:48:32 deraadt Exp $
 
 .include <bsd.own.mk>
 
@@ -6,7 +6,7 @@ SUBDIR= ac accton acpidump adduser amd apm apmd arp \
        authpf bgpctl bgpd bind chroot config cron crunchgen dev_mkdb \
        dhcpd dhcrelay dvmrpctl dvmrpd edquota eeprom faithd fdformat \
        ftp-proxy gpioctl hostapd hotplugd httpd ifstated inetd iostat \
-       kgmon kvm_mkdb lpr mailwrapper map-mbone memconfig mopd mrinfo \
+       kgmon kvm_mkdb lpr mailwrapper map-mbone memconfig mksuncd mopd mrinfo \
        mrouted mtrace mtree ndp netgroup_mkdb ntpd openssl ospfctl ospfd \
        pcidump pkg_add popa3d portmap ppp pppd pppoe procmap pstat pwd_mkdb \
        quot quotaon rarpd rbootd rdate rdconfig relayctl relayd repquota \
diff --git a/usr.sbin/mksuncd/Makefile b/usr.sbin/mksuncd/Makefile
new file mode 100644 (file)
index 0000000..245ccf1
--- /dev/null
@@ -0,0 +1,15 @@
+#      $OpenBSD: Makefile,v 1.1 2008/08/22 15:48:32 deraadt Exp $
+
+.if ${MACHINE} == "sparc64"
+
+PROG=  mksuncd
+CFLAGS+=-Werror -Wall -Wstrict-prototypes -Wmissing-prototypes
+
+.else
+NOPROG=
+.endif
+
+MAN=   mksuncd.1
+
+.include <bsd.prog.mk>
+
diff --git a/usr.sbin/mksuncd/mksuncd.1 b/usr.sbin/mksuncd/mksuncd.1
new file mode 100644 (file)
index 0000000..5c11a81
--- /dev/null
@@ -0,0 +1,68 @@
+.\"    $OpenBSD: mksuncd.1,v 1.1 2008/08/22 15:48:32 deraadt Exp $
+.\"
+.\" Copyright (c) 2001 Jason L. Wright (jason@thought.net)
+.\" 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 ``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 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.
+.\"
+.Dd $Mdocdate: August 22 2008 $
+.Dt MKSUNCD 1
+.Os
+.Sh NAME
+.Nm mksuncd
+.Nd add a bootable ufs partition to a filesystem image
+.Sh SYNOPSIS
+.Nm mksuncd
+.Ar partition-letter
+.Ar imagefile
+.Ar ufsfile
+.Sh DESCRIPTION
+The
+.Nm
+utility adds the file
+.Ar ufsfile
+to the end of
+.Ar imagefile .
+.Ar ufsfile
+is assumed to be a bootable filesystem image and
+.Ar imagefile
+is assumed to be something like an ISO 9660 filesystem.
+A Sun-style disklabel is expected to already be present
+at the beginning of
+.Ar imagefile ,
+and
+.Nm
+will update that label so that the partition (a-h) given by
+.Ar partition-letter
+points to
+.Ar ufsfile
+within
+.Ar imagefile .
+.Pp
+Based on the label in
+.Ar imagefile ,
+that file is padded so that added files are always on cylinder boundaries.
+This is a requirement of the PROM.
+.Sh BUGS
+This program is not endian or type safe.
+It makes several assumptions about both based on its
+SPARC bias.
diff --git a/usr.sbin/mksuncd/mksuncd.c b/usr.sbin/mksuncd/mksuncd.c
new file mode 100644 (file)
index 0000000..26d50ae
--- /dev/null
@@ -0,0 +1,327 @@
+/*     $OpenBSD: mksuncd.c,v 1.1 2008/08/22 15:48:32 deraadt Exp $     */
+
+/*
+ * Copyright (c) 2001 Jason L. Wright (jason@thought.net)
+ * 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 ``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 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.
+ */
+
+/*
+ * WARNING! WARNING!
+ * This program is not type safe (it assumes sparc type sizes) and not
+ * endian safe (assumes sparc endianness).
+ * WARNING! WARNING!
+ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, Lawrence Berkeley Laboratory.
+ *
+ * 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
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <err.h>
+#include <string.h>
+
+/*
+ * SunOS disk label layout (only relevant portions discovered here).
+ * JLW XXX should get these definitions from elsewhere, oh well.
+ */
+
+#define        SUN_DKMAGIC     55998
+
+/* partition info */
+struct sun_dkpart {
+       int     sdkp_cyloffset;         /* starting cylinder */
+       int     sdkp_nsectors;          /* number of sectors */
+};
+
+struct sun_disklabel {                 /* total size = 512 bytes */
+       char    sl_text[128];
+       char    sl_xxx1[292];
+#define sl_bsdlabel    sl_xxx1         /* Embedded OpenBSD label */
+       u_short sl_rpm;                 /* rotational speed */
+       u_short sl_pcylinders;          /* number of physical cyls */
+#define        sl_pcyl  sl_pcylinders          /* XXX: old sun3 */
+       u_short sl_sparespercyl;        /* spare sectors per cylinder */
+       char    sl_xxx3[4];
+       u_short sl_interleave;          /* interleave factor */
+       u_short sl_ncylinders;          /* data cylinders */
+       u_short sl_acylinders;          /* alternate cylinders */
+       u_short sl_ntracks;             /* tracks per cylinder */
+       u_short sl_nsectors;            /* sectors per track */
+       char    sl_xxx4[4];
+       struct sun_dkpart sl_part[8];   /* partition layout */
+       u_short sl_magic;               /* == SUN_DKMAGIC */
+       u_short sl_cksum;               /* xor checksum of all shorts */
+};
+
+int expand_file(int, off_t);
+void usage(void);
+int adjust_base(int, struct sun_disklabel *);
+int get_label(int, struct sun_disklabel *);
+int append_osfile(int, int);
+off_t cylindersize(int, struct sun_disklabel *);
+int adjust_label(int, struct sun_disklabel *, int, off_t, off_t);
+
+int
+expand_file(int f, off_t len)
+{
+       char buf[1024];
+       off_t i;
+
+       if (lseek(f, 0, SEEK_END) == -1)
+               return (-1);
+       bzero(buf, sizeof(buf));
+       while (len) {
+               i = (sizeof(buf) < len) ? sizeof(buf) : len;
+               if (write(f, buf, i) != i)
+                       return (-1);
+               len -= i;
+       }
+       return (0);
+}
+
+void
+usage(void)
+{
+       fprintf(stderr, "setpart partition baseimage bootimage\n");
+}
+
+/*
+ * Adjust size of base to meet a cylinder boundary.
+ */
+int
+adjust_base(int f, struct sun_disklabel *slp)
+{
+       struct stat st;
+       off_t sz;
+
+       if (lseek(f, 0, SEEK_END) == -1)
+               err(1, "lseek");
+
+       if (fstat(f, &st) == -1)
+               err(1, "fstat");
+
+       sz = ((off_t)slp->sl_nsectors) *
+           ((off_t)slp->sl_ntracks) * ((off_t)512);
+
+       if ((st.st_size % sz) != 0) {
+               if (expand_file(f, sz - (st.st_size % sz)))
+                       err(1, "expand_file");
+       }
+
+       return (0);
+}
+
+int
+get_label(int f, struct sun_disklabel *slp)
+{
+       int r;
+
+       if (lseek(f, 0, SEEK_SET) == -1)
+               err(1, "lseek");
+
+       r = read(f, slp, sizeof(*slp));
+       if (r == -1)
+               err(1, "read");
+       if (r != sizeof(*slp))
+               errx(1, "short read");
+
+       if (slp->sl_ntracks == 0 || slp->sl_ncylinders == 0 ||
+           slp->sl_nsectors == 0)
+               errx(1, "bogus disklabel");
+
+       return (0);
+}
+
+int
+main(int argc, char **argv)
+{
+       struct sun_disklabel sl;
+       int part, bf, of;
+       off_t cylstart, cylsize;
+
+       if (argc != 4) {
+               usage();
+               return (1);
+       }
+
+       if (argv[1] == NULL || strlen(argv[1]) != 1 ||
+           (argv[1][0] < 'a' || argv[1][0] > 'h')) {
+               usage();
+               return (1);
+       }
+       part = argv[1][0] - 'a';
+
+       if (argv[2] == NULL || argv[3] == NULL) {
+               usage();
+               return (1);
+       }
+
+       bf = open(argv[2], O_RDWR);
+       if (bf == -1)
+               err(1, "open");
+
+       of = open(argv[3], O_RDONLY);
+       if (of == -1)
+               err(1, "open");
+
+       if (get_label(bf, &sl))
+               return (1);
+
+       if (adjust_base(bf, &sl))
+               return (1);
+
+       cylstart = cylindersize(bf, &sl);
+       cylsize = cylindersize(of, &sl);
+
+       if (append_osfile(bf, of))
+               return (1);
+
+       if (adjust_base(bf, &sl))
+               return (1);
+
+       if (adjust_label(bf, &sl, part, cylstart, cylsize))
+               return (1);
+
+       close(bf);
+       close(of);
+
+       return (0);
+}
+
+/*
+ * Put our entry into the disklabel, recompute label checksum, and
+ * write it back to the disk.
+ */
+int
+adjust_label(int f, struct sun_disklabel *slp, int part, off_t start, off_t size)
+{
+       u_short sum = 0, *sp;
+       int i;
+
+       if (start > 65535)
+               errx(1, "start too large! %lld", (long long)start);
+       if (part < 0 || part > 8)
+               errx(1, "invalid partition: %d", part);
+       slp->sl_part[part].sdkp_cyloffset = start;
+       slp->sl_part[part].sdkp_nsectors =
+           size * slp->sl_nsectors * slp->sl_ntracks;
+
+       slp->sl_cksum = 0;
+       sp = (u_short *)slp;
+       for (i = 0; i < sizeof(*slp)/sizeof(u_short); i++) {
+               sum ^= *sp;
+               sp++;
+       }
+       slp->sl_cksum = sum;
+
+       if (lseek(f, 0, SEEK_SET) == -1)
+               return (-1);
+
+       i = write(f, slp, sizeof(*slp));
+       if (i < 0)
+               err(1, "write modified label");
+       if (i != sizeof(*slp))
+               errx(1, "short write modified label");
+       return (0);
+}
+
+int
+append_osfile(int outf, int inf)
+{
+       char buf[512];
+       int r, len;
+
+       while (1) {
+               len = read(inf, buf, sizeof(buf));
+               if (len < 0)
+                       err(1, "read osfile");
+               if (len == 0)
+                       return (0);
+
+               r = write(outf, buf, len);
+               if (r < 0)
+                       err(1, "write basefile");
+               if (r != len)
+                       errx(1, "short write basefile");
+       }
+}
+
+off_t
+cylindersize(int f, struct sun_disklabel *slp)
+{
+       struct stat st;
+       off_t sz, r;
+
+       if (fstat(f, &st) == -1)
+               err(1, "fstat");
+
+       sz = ((off_t)slp->sl_nsectors) *
+           ((off_t)slp->sl_ntracks) * ((off_t)512);
+
+       r = st.st_size / sz;
+
+       if ((st.st_size % sz) == 0)
+               return (r);
+       return (r + 1);
+}