diff options
author | obrien <obrien@FreeBSD.org> | 2000-01-18 11:25:05 +0800 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2000-01-18 11:25:05 +0800 |
commit | 4aff821d280ba45eed8eb9f18fed412a17e382db (patch) | |
tree | ae23b858542fa83cfcc4a4485cd4344697f5a5e4 /sysutils/setcdboot | |
parent | a90724a361deeedd6a2154eca3630494c51429f2 (diff) | |
download | freebsd-ports-gnome-4aff821d280ba45eed8eb9f18fed412a17e382db.tar.gz freebsd-ports-gnome-4aff821d280ba45eed8eb9f18fed412a17e382db.tar.zst freebsd-ports-gnome-4aff821d280ba45eed8eb9f18fed412a17e382db.zip |
Mark a file bootable within an Alpha ISO-9660 image.
Diffstat (limited to 'sysutils/setcdboot')
-rw-r--r-- | sysutils/setcdboot/Makefile | 33 | ||||
-rw-r--r-- | sysutils/setcdboot/distinfo | 1 | ||||
-rw-r--r-- | sysutils/setcdboot/files/setcdboot.c | 237 | ||||
-rw-r--r-- | sysutils/setcdboot/pkg-comment | 1 | ||||
-rw-r--r-- | sysutils/setcdboot/pkg-descr | 10 | ||||
-rw-r--r-- | sysutils/setcdboot/pkg-plist | 1 |
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 |