summaryrefslogtreecommitdiff
path: root/sysutils/setcdboot
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>2000-01-18 03:25:05 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>2000-01-18 03:25:05 +0000
commit7ebe0ef9855dc2aa77464c464d742251b055c398 (patch)
treed62c62fee6b8536daefd3156819a7af6c9ba8b40 /sysutils/setcdboot
parentImport version 0.007 of vigor... (diff)
Mark a file bootable within an Alpha ISO-9660 image.
Notes
Notes: svn path=/head/; revision=24806
Diffstat (limited to 'sysutils/setcdboot')
-rw-r--r--sysutils/setcdboot/Makefile33
-rw-r--r--sysutils/setcdboot/distinfo1
-rw-r--r--sysutils/setcdboot/files/setcdboot.c237
-rw-r--r--sysutils/setcdboot/pkg-comment1
-rw-r--r--sysutils/setcdboot/pkg-descr10
-rw-r--r--sysutils/setcdboot/pkg-plist1
6 files changed, 283 insertions, 0 deletions
diff --git a/sysutils/setcdboot/Makefile b/sysutils/setcdboot/Makefile
new file mode 100644
index 000000000000..cbfe02d8a7cc
--- /dev/null
+++ b/sysutils/setcdboot/Makefile
@@ -0,0 +1,33 @@
+# ex:ts=8
+# Ports collection makefile for: setcdboot
+# Version required: 1.0
+# Date created: Mon Jan 17, 1998
+# Whom: David O'Brien (obrien@NUXI.com)
+#
+# $FreeBSD$
+#
+
+DISTNAME= setcdboot
+PKGNAME= setcdboot-1.0
+CATEGORIES= sysutils
+MASTER_SITES= 'part of port'
+EXTRACT_SUFX= .c
+
+MAINTAINER= obrien@FreeBSD.org
+
+ONLY_FOR_ARCHS= alpha
+
+NO_WRKSUBDIR= yes
+DISTDIR= ${FILESDIR}
+
+do-extract:
+ @${MKDIR} ${WRKDIR}
+ @${CP} ${DISTDIR}/${DISTFILES} ${WRKDIR}
+
+do-build:
+ (cd ${WRKSRC} && ${CC} ${CFLAGS} -o ${DISTNAME} ${DISTNAME}.c)
+
+do-install:
+ ${INSTALL_PROGRAM} ${WRKSRC}/${DISTNAME} ${PREFIX}/bin
+
+.include <bsd.port.mk>
diff --git a/sysutils/setcdboot/distinfo b/sysutils/setcdboot/distinfo
new file mode 100644
index 000000000000..e014adad57f3
--- /dev/null
+++ b/sysutils/setcdboot/distinfo
@@ -0,0 +1 @@
+MD5 (setcdboot.c) = 008f0aeb92185d2623c2febc4f938734
diff --git a/sysutils/setcdboot/files/setcdboot.c b/sysutils/setcdboot/files/setcdboot.c
new file mode 100644
index 000000000000..5f51971f5eb5
--- /dev/null
+++ b/sysutils/setcdboot/files/setcdboot.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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$
+ */
+
+/*
+ * Stand-alone ISO9660 file reading package.
+ *
+ * Note: This doesn't support Rock Ridge extensions, extended attributes,
+ * blocksizes other than 2048 bytes, multi-extent files, etc.
+ */
+#include <sys/param.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <err.h>
+#include <isofs/cd9660/iso.h>
+
+struct ptable_ent {
+ char namlen [ISODCL( 1, 1)]; /* 711 */
+ char extlen [ISODCL( 2, 2)]; /* 711 */
+ char block [ISODCL( 3, 6)]; /* 732 */
+ char parent [ISODCL( 7, 8)]; /* 722 */
+ char name [1];
+};
+#define PTFIXSZ 8
+#define PTSIZE(pp) roundup(PTFIXSZ + isonum_711((pp)->namlen), 2)
+
+#define cdb2off(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE)
+
+/* XXX these should be in the system headers */
+static __inline int
+isonum_722(u_char *p)
+{
+ return (*p << 8)|p[1];
+}
+
+static __inline int
+isonum_732( u_char *p)
+{
+ return (*p << 24)|(p[1] << 16)|(p[2] << 8)|p[3];
+}
+
+static int
+dirmatch(const char *path, struct iso_directory_record *dp)
+{
+ char *cp;
+ int i;
+
+ cp = dp->name;
+ for (i = isonum_711(dp->name_len); --i >= 0; path++, cp++) {
+ if (!*path || *path == '/')
+ break;
+ if (toupper(*path) == *cp)
+ continue;
+ return 0;
+ }
+ if (*path && *path != '/')
+ return 0;
+ /*
+ * Allow stripping of trailing dots and the version number.
+ * Note that this will find the first instead of the last version
+ * of a file.
+ */
+ if (i >= 0 && (*cp == ';' || *cp == '.')) {
+ /* This is to prevent matching of numeric extensions */
+ if (*cp == '.' && cp[1] != ';')
+ return 0;
+ while (--i >= 0)
+ if (*++cp != ';' && (*cp < '0' || *cp > '9'))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+cd9660_findfile(int disk, const char *path, int *startp, int *lenp)
+{
+ void *buf;
+ struct iso_primary_descriptor *vd;
+ size_t buf_size, read, dsize, off;
+ daddr_t bno, boff;
+ struct iso_directory_record rec;
+ struct iso_directory_record *dp = 0;
+ int rc = 0;
+
+ /* First find the volume descriptor */
+ buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
+ vd = buf;
+ for (bno = 16;; bno++) {
+ read = pread(disk, buf, ISO_DEFAULT_BLOCK_SIZE, cdb2off(bno));
+ if (read != ISO_DEFAULT_BLOCK_SIZE) {
+ rc = EIO;
+ goto out;
+ }
+ rc = EINVAL;
+ if (bcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0)
+ goto out;
+ if (isonum_711(vd->type) == ISO_VD_END)
+ goto out;
+ if (isonum_711(vd->type) == ISO_VD_PRIMARY)
+ break;
+ }
+ if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE) {
+ rc = EINVAL;
+ goto out;
+ }
+
+ rec = *(struct iso_directory_record *) vd->root_directory_record;
+ if (*path == '/') path++; /* eat leading '/' */
+
+ while (*path) {
+ bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length);
+ dsize = isonum_733(rec.size);
+ off = 0;
+ boff = 0;
+
+ while (off < dsize) {
+ if ((off % ISO_DEFAULT_BLOCK_SIZE) == 0) {
+ read = pread(disk, buf,
+ ISO_DEFAULT_BLOCK_SIZE,
+ cdb2off(bno + boff));
+ if (read != ISO_DEFAULT_BLOCK_SIZE) {
+ rc = EIO;
+ goto out;
+ }
+ boff++;
+ dp = (struct iso_directory_record *) buf;
+ }
+ if (isonum_711(dp->length) == 0) {
+ /* skip to next block, if any */
+ off = boff * ISO_DEFAULT_BLOCK_SIZE;
+ continue;
+ }
+
+ if (dirmatch(path, dp))
+ break;
+
+ dp = (struct iso_directory_record *)
+ ((char *) dp + isonum_711(dp->length));
+ off += isonum_711(dp->length);
+ }
+ if (off == dsize) {
+ rc = ENOENT;
+ goto out;
+ }
+
+ rec = *dp;
+ while (*path && *path != '/') /* look for next component */
+ path++;
+ if (*path) path++; /* skip '/' */
+ }
+
+ *startp = cdb2off(isonum_733(rec.extent)
+ + isonum_711(rec.ext_attr_length));
+ *lenp = isonum_733(rec.size);
+ rc = 0;
+
+ out:
+ free(buf);
+ return rc;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int disk, start, len, i;
+ char buf[512];
+ unsigned long long *lp, sum;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: setcdboot <cd image> <boot path>\n");
+ exit(1);
+ }
+
+ disk = open(argv[1], O_RDWR);
+ if (disk < 0)
+ err(1, "Can't open %s", argv[1]);
+ if (cd9660_findfile(disk, argv[2], &start, &len))
+ errx(1, "Can't find %s in image", argv[2]);
+ printf("start=%d, len=%d\n", start, len);
+
+ /*
+ * Read the SRM boot sector and write location of bootstrap.
+ */
+ if (pread(disk, buf, 512, 0) < 0)
+ errx(1, "Can't read boot sector");
+ lp = (unsigned long long *) buf;
+ lp[60] = (len + 511) / 512;
+ lp[61] = start / 512;
+ lp[62] = 0;
+
+ /*
+ * Checksum the boot sector and write it back.
+ */
+ sum = 0;
+ for (i = 0; i < 63; i++)
+ sum += lp[i];
+ lp[63] = sum;
+
+ if (pwrite(disk, buf, 512, 0) < 0)
+ errx(1, "Can't write boot sector");
+
+ return 0;
+}
diff --git a/sysutils/setcdboot/pkg-comment b/sysutils/setcdboot/pkg-comment
new file mode 100644
index 000000000000..ef9cf650bde8
--- /dev/null
+++ b/sysutils/setcdboot/pkg-comment
@@ -0,0 +1 @@
+Mark a file bootable within an Alpha ISO-9660 image.
diff --git a/sysutils/setcdboot/pkg-descr b/sysutils/setcdboot/pkg-descr
new file mode 100644
index 000000000000..8e023dc611d0
--- /dev/null
+++ b/sysutils/setcdboot/pkg-descr
@@ -0,0 +1,10 @@
+`setcdboot' is used on the DEC Alpha platform to mark a file bootable
+within an Alpha ISO-9660 image bootable. First create an ISO-9660 image
+using `mkisofs', and then run
+
+ setcdboot <name_of_iso_image> <boot_path_within_image>
+
+Once a bootable file image has been marked with `setcdboot', burn the image
+to CDROM media in the usual manner. To boot the resulting CDROM, simply
+specify the CDROM device as the boot device and the Alpha will boot as if
+from hard disk.
diff --git a/sysutils/setcdboot/pkg-plist b/sysutils/setcdboot/pkg-plist
new file mode 100644
index 000000000000..b2ef767af957
--- /dev/null
+++ b/sysutils/setcdboot/pkg-plist
@@ -0,0 +1 @@
+bin/setcdboot