Subject: PATCH: Rename and auto-build mkboot with tools
To: Jochen Kunz <jkunz@unixag-kl.fh-kl.de>
From: Zach Lowry <zach@zachlowry.net>
List: port-hp700
Date: 06/05/2004 20:23:04
--Apple-Mail-1-803602517
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed

Here's a little patch I did today. This renames mkboot to mklifboot as 
described here:

http://mail-index.netbsd.org/port-hp700/2003/11/23/0002.html

and causes mkboot to be built with the host tools. Hopefully, this is 
an ok thing to do.

--Apple-Mail-1-803602517
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="mklifboot.patch"
Content-Disposition: attachment;
	filename=mklifboot.patch

diff -Naur -x CVS ../src.orig/sys/arch/hp700/stand/Makefile.inc ./sys/arch/hp700/stand/Makefile.inc
--- ../src.orig/sys/arch/hp700/stand/Makefile.inc	2004-06-05 14:18:51.000000000 -0500
+++ ./sys/arch/hp700/stand/Makefile.inc	2004-06-05 15:54:21.000000000 -0500
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.2 2002/11/28 06:01:00 chs Exp $
+#	$NetBSD: Makefile.inc,v 1.3 2002/11/28 06:01:00 chs Exp $
 
 BINDIR=			/usr/mdec
 
@@ -6,7 +6,7 @@
 
 S?=		${.CURDIR}/../../../..
 
-.if !(defined(PROG) && ${PROG} == "mkboot")
+.if !(defined(PROG) && ${PROG} == "mklifboot")
 
 .BEGIN: machine hp700 hppa
 .NOPATH: machine hp700 hppa
diff -Naur -x CVS ../src.orig/sys/arch/hp700/stand/Makefile.orig ./sys/arch/hp700/stand/Makefile.orig
--- ../src.orig/sys/arch/hp700/stand/Makefile.orig	2004-06-05 14:18:51.000000000 -0500
+++ ./sys/arch/hp700/stand/Makefile.orig	2004-06-05 14:35:54.000000000 -0500
@@ -2,6 +2,6 @@
 
 #	$OpenBSD: Makefile,v 1.2 2000/05/31 19:59:31 mickey Exp $
 
-SUBDIR+= mkboot boot
+SUBDIR+= mklifboot boot
 
 .include <bsd.subdir.mk>
diff -Naur -x CVS ../src.orig/sys/arch/hp700/stand/mkboot/Makefile ./sys/arch/hp700/stand/mkboot/Makefile
--- ../src.orig/sys/arch/hp700/stand/mkboot/Makefile	2004-06-05 14:18:51.000000000 -0500
+++ ./sys/arch/hp700/stand/mkboot/Makefile	1969-12-31 18:00:00.000000000 -0600
@@ -1,8 +0,0 @@
-#	$NetBSD: Makefile,v 1.2 2002/10/23 14:35:28 lukem Exp $
-
-NOMAN=		# defined
-
-HOSTPROG=	mkboot
-SRCS=		mkboot.c
-
-.include <bsd.hostprog.mk>
diff -Naur -x CVS ../src.orig/sys/arch/hp700/stand/mkboot/mkboot.c ./sys/arch/hp700/stand/mkboot/mkboot.c
--- ../src.orig/sys/arch/hp700/stand/mkboot/mkboot.c	2004-06-05 14:18:51.000000000 -0500
+++ ./sys/arch/hp700/stand/mkboot/mkboot.c	1969-12-31 18:00:00.000000000 -0600
@@ -1,394 +0,0 @@
-/*	$NetBSD: mkboot.c,v 1.4 2003/08/07 16:27:46 agc Exp $	*/
-
-/*	$OpenBSD: mkboot.c,v 1.9 2001/05/17 00:57:55 pvalchev Exp $	*/
-
-/*
- * Copyright (c) 1990, 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. 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.
- *
- *	@(#)mkboot.c	8.1 (Berkeley) 7/15/93
- */
-
-#if 0
-#ifndef lint
-static char copyright[] =
-"@(#) Copyright (c) 1990, 1993\n\
-	The Regents of the University of California.  All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char rcsid[] = "$OpenBSD: mkboot.c,v 1.9 2001/05/17 00:57:55 pvalchev Exp $";
-#endif /* not lint */
-#endif
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-#include <err.h>
-
-#include <sys/exec_aout.h>
-#include <sys/exec_elf.h>
-
-#ifndef hppa
-/* hack for cross compile XXX */
-#include "../../include/disklabel.h"
-#else
-#include <sys/disklabel.h>
-#endif
-
-#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
-		      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
-		      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
-		      (ehdr).e_ident[EI_MAG3] == ELFMAG3)
-
-#include <stdio.h>
-#include <ctype.h>
-
-int putfile(char *, int);
-void __dead usage(void);
-void bcddate(char *, char *);
-char *lifname(char *);
-int cksum(int, int *, int);
-
-char *to_file;
-int loadpoint, verbose;
-u_long entry;
-
-/*
- * Old Format:
- *	sector 0:	LIF volume header (40 bytes)
- *	sector 1:	<unused>
- *	sector 2:	LIF directory (8 x 32 == 256 bytes)
- *	sector 3-:	LIF file 0, LIF file 1, etc.
- * where sectors are 256 bytes.
- *
- * New Format:
- *	sector 0:	LIF volume header (40 bytes)
- *	sector 1:	<unused>
- *	sector 2:	LIF directory (8 x 32 == 256 bytes)
- *	sector 3:	<unused>
- *	sector 4-31:	disklabel (~300 bytes right now)
- *	sector 32-:	LIF file 0, LIF file 1, etc.
- */
-int
-main(int argc, char **argv)
-{
-	int to, n, pos, c;
-	char buf[LIF_FILESTART];
-	struct lifvol *lifv = (struct lifvol *)buf;
-	struct lifdir *lifd = (struct lifdir *)(buf + LIF_DIRSTART);
-
-	while ((c = getopt(argc, argv, "vl:")) != -1) {
-		switch (c) {
-		case 'v':
-			verbose++;
-			break;
-		case 'l':
-			sscanf(optarg, "0x%x", &loadpoint);
-			break;
-		default:
-			usage();
-		}
-	}
-	if (argc - optind < 2)
-		usage();
-	else if (argc - optind > 8)
-		errx(1, "too many boot programs (max 8 supported)");
-
-	to_file = argv[--argc];
-	if ((to = open(to_file, O_RDWR | O_TRUNC | O_CREAT, 0644)) < 0)
-		err(1, "%s: open", to_file);
-
-	bzero(buf, sizeof(buf));
-
-	/* record volume info */
-	lifv->vol_id = htobe16(LIF_VOL_ID);
-	strncpy(lifv->vol_label, "MKBOOT", 6);
-	lifv->vol_addr = htobe32(btolifs(LIF_DIRSTART));
-	lifv->vol_oct = htobe16(LIF_VOL_OCT);
-	lifv->vol_dirsize = htobe32(btolifs(LIF_DIRSIZE));
-	lifv->vol_version = htobe16(1);
-	lifv->vol_number = htobe32(1);
-	lifv->vol_lastvol = htobe32(1);
-	lifv->vol_length = LIF_FILESTART;	/* ... so far. */
-	bcddate(to_file, lifv->vol_toc);
-	lifv->ipl_addr = htobe32(LIF_FILESTART);
-
-	argv += optind;
-	argc -= optind;
-	optind = 0;
-	for (pos = LIF_FILESTART; optind < argc; optind++) {
-
-		/* output bootfile */
-		if (lseek(to, pos, SEEK_SET) < 0)
-			err(1, "%s: lseek", to_file);
-		lifd[optind].dir_addr = htobe32(btolifs(pos));
-		n = btolifs(putfile(argv[optind], to));
-		if (lifv->ipl_entry == 0) {
-			lifv->ipl_entry = htobe32(loadpoint + entry);
-			lifv->ipl_size = htobe32(lifstob(n));
-			lifd[optind].dir_type = htobe16(LIF_DIR_ISL);
-			lifd[optind].dir_implement = 0;
-		} else {
-			lifd[optind].dir_type = htobe16(LIF_DIR_TYPE);
-			lifd[optind].dir_implement = htobe32(loadpoint + entry);
-		}
-
-		memcpy(lifd[optind].dir_name, lifname(argv[optind]),
-			sizeof(lifd[optind].dir_name));
-		lifd[optind].dir_length = htobe32(n);
-		bcddate(argv[optind], lifd[optind].dir_toc);
-		lifd[optind].dir_flag = htobe16(LIF_DIR_FLAG);
-
-		lifv->vol_length += n;
-		pos += lifstob(n);
-	}
-
-	/* terminate the directory */
-	lifd[optind].dir_type = htobe16(0xffff);
-
-	/* byte-swap the length now that we're done computing it */
-	lifv->vol_length = htobe32(lifv->vol_length);
-
-	/* output volume/directory header info */
-	if (lseek(to, LIF_VOLSTART, SEEK_SET) < 0)
-		err(1, "%s: lseek", to_file);
-	if (write(to, buf, sizeof(buf)) != sizeof(buf))
-		err(1, "%s: write LIF volume", to_file);
-	lseek(to, 0, SEEK_END);
-
-	if (close(to) < 0)
-		err(1, "%s", to_file);
-
-	return(0);
-}
-
-int
-putfile(char *from_file, int to)
-{
-	struct exec ex;
-	char buf[2048];
-	int n, total;
-	int from, check_sum = 0;
-	struct lif_load load;
-	Elf32_Ehdr elf_header;
-	Elf32_Phdr *elf_segments;
-	int i, header_count, memory_needed, elf_load_image_segment;
-
-	if ((from = open(from_file, O_RDONLY)) < 0)
-		err(1, "%s", from_file);
-
-	n = read(from, &ex, sizeof(ex));
-	if (n != sizeof(ex))
-		err(1, "%s: reading file header", from_file);
-
-	entry = ex.a_entry;
-	if (N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC)
-		entry += sizeof(ex);
-	else if (IS_ELF(*(Elf32_Ehdr *)&ex)) {
-
-		if (lseek(from, 0, SEEK_SET) < 0)
-			err(1, "lseek");
-		n = read(from, &elf_header, sizeof (elf_header));
-		if (n != sizeof (elf_header))
-			err(1, "%s: reading ELF header", from_file);
-		header_count = be16toh(elf_header.e_phnum);
-		memory_needed = header_count * sizeof (Elf32_Phdr);
-		elf_segments = malloc(memory_needed);
-		if (elf_segments == NULL)
-			err(1, "malloc");
-		if (lseek(from, be32toh(elf_header.e_phoff), SEEK_SET) < 0)
-			err(1, "lseek");
-		n = read(from, elf_segments, memory_needed);
-		if (n != memory_needed)
-			err(1, "%s: reading ELF segments", from_file);
-		elf_load_image_segment = -1;
-		for (i = 0; i < header_count; i++) {
-			if (elf_segments[i].p_filesz &&
-			    be32toh(elf_segments[i].p_flags) & PF_X) {
-				if (elf_load_image_segment != -1)
-					errx(1, "%s: more than one ELF program "
-					     "segment", from_file);
-				elf_load_image_segment = i;
-			}
-		}
-		if (elf_load_image_segment == -1)
-			errx(1, "%s: no suitable ELF program segment",
-			     from_file);
-		entry = be32toh(elf_header.e_entry) +
-			be32toh(elf_segments[elf_load_image_segment].p_offset) -
-			be32toh(elf_segments[elf_load_image_segment].p_vaddr);
-	} else if (*(uint8_t *)&ex == 0x1f && ((uint8_t *)&ex)[1] == 0x8b) {
-		entry = 0;
-	} else
-		errx(1, "%s: bad magic number", from_file);
-
-	entry += sizeof(load);
-	lseek(to, sizeof(load), SEEK_CUR);
-
-	total = 0;
-	n = sizeof(buf) - sizeof(load);
-	/* copy the whole file */
-	for (lseek(from, 0, SEEK_SET); ; n = sizeof(buf)) {
-		memset(buf, 0, sizeof(buf));
-		if ((n = read(from, buf, n)) < 0)
-			err(1, "%s", from_file);
-		else if (n == 0)
-			break;
-
-		if (write(to, buf, n) != n)
-			err(1, "%s", to_file);
-
-		total += n;
-		check_sum = cksum(check_sum, (int *)buf, n);
-	}
-
-	/* load header */
-	load.address = htobe32(loadpoint + sizeof(load));
-	load.count = htobe32(4 + total);
-	check_sum = cksum(check_sum, (int *)&load, sizeof(load));
-
-	if (verbose)
-		warnx("wrote %d bytes of file \'%s\'", total, from_file);
-
-	total += sizeof(load);
-	/* insert the header */
-	lseek(to, -total, SEEK_CUR);
-	if (write(to, &load, sizeof(load)) != sizeof(load))
-		err(1, "%s", to_file);
-	lseek(to, total - sizeof(load), SEEK_CUR);
-
-	bzero(buf, sizeof(buf));
-	/* pad to int */
-	n = sizeof(int) - total % sizeof(int);
-	if (total % sizeof(int)) {
-		if (write(to, buf, n) != n)
-			err(1, "%s", to_file);
-		else
-			total += n;
-	}
-
-	/* pad to the blocksize */
-	n = sizeof(buf) - total % sizeof(buf);
-
-	if (n < sizeof(int)) {
-		n += sizeof(buf);
-		total += sizeof(buf);
-	} else
-		total += n;
-
-	/* TODO should pad here to the 65k boundary for tape boot */
-
-	if (verbose)
-		warnx("checksum is 0x%08x", -check_sum);
-
-	check_sum = htobe32(-check_sum);
-	if (write(to, &check_sum, sizeof(int)) != sizeof(int))
-		err(1, "%s", to_file);
-
-	n -= sizeof(int);
-
-	if (write(to, buf, n) != n)
-		err(1, "%s", to_file);
-
-	if (close(from) < 0)
-		err(1, "%s", from_file);
-
-	return total;
-}
-
-int
-cksum(int ck, int *p, int size)
-{
-	/* we assume size is int-aligned */
-	for (size = (size + sizeof(int) - 1) / sizeof(int); size--; p++ )
-		ck += be32toh(*p);
-
-	return ck;
-}
-
-void __dead
-usage(void)
-{
-	fprintf(stderr,
-		"usage: %s [-v] [-l loadpoint] prog1 {progN} outfile\n",
-		getprogname());
-	exit(1);
-}
-
-char *
-lifname(char *str)
-{
-	static char lname[10] = "XXXXXXXXXX";
-	char *cp;
-	int i;
-
-	cp = strrchr(str, '/');
-	if (cp != NULL) {
-		str = cp + 1;
-	}
-	for (i = 0; i < 9; i++) {
-		if (islower(*str))
-			lname[i] = toupper(*str);
-		else if (isalnum(*str) || *str == '_')
-			lname[i] = *str;
-		else
-			break;
-		str++;
-	}
-	for ( ; i < 10; i++)
-		lname[i] = ' ';
-	return(lname);
-}
-
-
-void
-bcddate(char *file, char *toc)
-{
-	struct stat statb;
-	struct tm *tm;
-
-	stat(file, &statb);
-	tm = localtime(&statb.st_ctime);
-	tm->tm_year %= 100;
-	*toc = (tm->tm_year / 10) << 4;
-	*toc++ |= tm->tm_year % 10;
-	*toc = ((tm->tm_mon+1) / 10) << 4;
-	*toc++ |= (tm->tm_mon+1) % 10;
-	*toc = (tm->tm_mday / 10) << 4;
-	*toc++ |= tm->tm_mday % 10;
-	*toc = (tm->tm_hour / 10) << 4;
-	*toc++ |= tm->tm_hour % 10;
-	*toc = (tm->tm_min / 10) << 4;
-	*toc++ |= tm->tm_min % 10;
-	*toc = (tm->tm_sec / 10) << 4;
-	*toc |= tm->tm_sec % 10;
-}
diff -Naur -x CVS ../src.orig/sys/arch/hp700/stand/mklifboot/Makefile ./sys/arch/hp700/stand/mklifboot/Makefile
--- ../src.orig/sys/arch/hp700/stand/mklifboot/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ ./sys/arch/hp700/stand/mklifboot/Makefile	2004-06-05 15:55:02.000000000 -0500
@@ -0,0 +1,13 @@
+#	$NetBSD: Makefile,v 1.3 2002/10/23 14:35:28 lukem Exp $
+
+NOMAN=		# defined
+
+SRCS=		mklifboot.c
+
+.if ${USETOOLS} == "yes"
+PROG=           mklifboot
+.include <bsd.prog.mk>
+.else
+HOSTPROG=       mklifboot
+.include <bsd.hostprog.mk>
+.endif
diff -Naur -x CVS ../src.orig/sys/arch/hp700/stand/mklifboot/mklifboot.c ./sys/arch/hp700/stand/mklifboot/mklifboot.c
--- ../src.orig/sys/arch/hp700/stand/mklifboot/mklifboot.c	1969-12-31 18:00:00.000000000 -0600
+++ ./sys/arch/hp700/stand/mklifboot/mklifboot.c	2003-08-07 11:27:46.000000000 -0500
@@ -0,0 +1,394 @@
+/*	$NetBSD: mklifboot.c,v 1.4 2003/08/07 16:27:46 agc Exp $	*/
+
+/*	$OpenBSD: mklifboot.c,v 1.9 2001/05/17 00:57:55 pvalchev Exp $	*/
+
+/*
+ * Copyright (c) 1990, 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. 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.
+ *
+ *	@(#)mklifboot.c	8.1 (Berkeley) 7/15/93
+ */
+
+#if 0
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: mklifboot.c,v 1.9 2001/05/17 00:57:55 pvalchev Exp $";
+#endif /* not lint */
+#endif
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <err.h>
+
+#include <sys/exec_aout.h>
+#include <sys/exec_elf.h>
+
+#ifndef hppa
+/* hack for cross compile XXX */
+#include "../../include/disklabel.h"
+#else
+#include <sys/disklabel.h>
+#endif
+
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+		      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+		      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+		      (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+#include <stdio.h>
+#include <ctype.h>
+
+int putfile(char *, int);
+void __dead usage(void);
+void bcddate(char *, char *);
+char *lifname(char *);
+int cksum(int, int *, int);
+
+char *to_file;
+int loadpoint, verbose;
+u_long entry;
+
+/*
+ * Old Format:
+ *	sector 0:	LIF volume header (40 bytes)
+ *	sector 1:	<unused>
+ *	sector 2:	LIF directory (8 x 32 == 256 bytes)
+ *	sector 3-:	LIF file 0, LIF file 1, etc.
+ * where sectors are 256 bytes.
+ *
+ * New Format:
+ *	sector 0:	LIF volume header (40 bytes)
+ *	sector 1:	<unused>
+ *	sector 2:	LIF directory (8 x 32 == 256 bytes)
+ *	sector 3:	<unused>
+ *	sector 4-31:	disklabel (~300 bytes right now)
+ *	sector 32-:	LIF file 0, LIF file 1, etc.
+ */
+int
+main(int argc, char **argv)
+{
+	int to, n, pos, c;
+	char buf[LIF_FILESTART];
+	struct lifvol *lifv = (struct lifvol *)buf;
+	struct lifdir *lifd = (struct lifdir *)(buf + LIF_DIRSTART);
+
+	while ((c = getopt(argc, argv, "vl:")) != -1) {
+		switch (c) {
+		case 'v':
+			verbose++;
+			break;
+		case 'l':
+			sscanf(optarg, "0x%x", &loadpoint);
+			break;
+		default:
+			usage();
+		}
+	}
+	if (argc - optind < 2)
+		usage();
+	else if (argc - optind > 8)
+		errx(1, "too many boot programs (max 8 supported)");
+
+	to_file = argv[--argc];
+	if ((to = open(to_file, O_RDWR | O_TRUNC | O_CREAT, 0644)) < 0)
+		err(1, "%s: open", to_file);
+
+	bzero(buf, sizeof(buf));
+
+	/* record volume info */
+	lifv->vol_id = htobe16(LIF_VOL_ID);
+	strncpy(lifv->vol_label, "MKBOOT", 6);
+	lifv->vol_addr = htobe32(btolifs(LIF_DIRSTART));
+	lifv->vol_oct = htobe16(LIF_VOL_OCT);
+	lifv->vol_dirsize = htobe32(btolifs(LIF_DIRSIZE));
+	lifv->vol_version = htobe16(1);
+	lifv->vol_number = htobe32(1);
+	lifv->vol_lastvol = htobe32(1);
+	lifv->vol_length = LIF_FILESTART;	/* ... so far. */
+	bcddate(to_file, lifv->vol_toc);
+	lifv->ipl_addr = htobe32(LIF_FILESTART);
+
+	argv += optind;
+	argc -= optind;
+	optind = 0;
+	for (pos = LIF_FILESTART; optind < argc; optind++) {
+
+		/* output bootfile */
+		if (lseek(to, pos, SEEK_SET) < 0)
+			err(1, "%s: lseek", to_file);
+		lifd[optind].dir_addr = htobe32(btolifs(pos));
+		n = btolifs(putfile(argv[optind], to));
+		if (lifv->ipl_entry == 0) {
+			lifv->ipl_entry = htobe32(loadpoint + entry);
+			lifv->ipl_size = htobe32(lifstob(n));
+			lifd[optind].dir_type = htobe16(LIF_DIR_ISL);
+			lifd[optind].dir_implement = 0;
+		} else {
+			lifd[optind].dir_type = htobe16(LIF_DIR_TYPE);
+			lifd[optind].dir_implement = htobe32(loadpoint + entry);
+		}
+
+		memcpy(lifd[optind].dir_name, lifname(argv[optind]),
+			sizeof(lifd[optind].dir_name));
+		lifd[optind].dir_length = htobe32(n);
+		bcddate(argv[optind], lifd[optind].dir_toc);
+		lifd[optind].dir_flag = htobe16(LIF_DIR_FLAG);
+
+		lifv->vol_length += n;
+		pos += lifstob(n);
+	}
+
+	/* terminate the directory */
+	lifd[optind].dir_type = htobe16(0xffff);
+
+	/* byte-swap the length now that we're done computing it */
+	lifv->vol_length = htobe32(lifv->vol_length);
+
+	/* output volume/directory header info */
+	if (lseek(to, LIF_VOLSTART, SEEK_SET) < 0)
+		err(1, "%s: lseek", to_file);
+	if (write(to, buf, sizeof(buf)) != sizeof(buf))
+		err(1, "%s: write LIF volume", to_file);
+	lseek(to, 0, SEEK_END);
+
+	if (close(to) < 0)
+		err(1, "%s", to_file);
+
+	return(0);
+}
+
+int
+putfile(char *from_file, int to)
+{
+	struct exec ex;
+	char buf[2048];
+	int n, total;
+	int from, check_sum = 0;
+	struct lif_load load;
+	Elf32_Ehdr elf_header;
+	Elf32_Phdr *elf_segments;
+	int i, header_count, memory_needed, elf_load_image_segment;
+
+	if ((from = open(from_file, O_RDONLY)) < 0)
+		err(1, "%s", from_file);
+
+	n = read(from, &ex, sizeof(ex));
+	if (n != sizeof(ex))
+		err(1, "%s: reading file header", from_file);
+
+	entry = ex.a_entry;
+	if (N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC)
+		entry += sizeof(ex);
+	else if (IS_ELF(*(Elf32_Ehdr *)&ex)) {
+
+		if (lseek(from, 0, SEEK_SET) < 0)
+			err(1, "lseek");
+		n = read(from, &elf_header, sizeof (elf_header));
+		if (n != sizeof (elf_header))
+			err(1, "%s: reading ELF header", from_file);
+		header_count = be16toh(elf_header.e_phnum);
+		memory_needed = header_count * sizeof (Elf32_Phdr);
+		elf_segments = malloc(memory_needed);
+		if (elf_segments == NULL)
+			err(1, "malloc");
+		if (lseek(from, be32toh(elf_header.e_phoff), SEEK_SET) < 0)
+			err(1, "lseek");
+		n = read(from, elf_segments, memory_needed);
+		if (n != memory_needed)
+			err(1, "%s: reading ELF segments", from_file);
+		elf_load_image_segment = -1;
+		for (i = 0; i < header_count; i++) {
+			if (elf_segments[i].p_filesz &&
+			    be32toh(elf_segments[i].p_flags) & PF_X) {
+				if (elf_load_image_segment != -1)
+					errx(1, "%s: more than one ELF program "
+					     "segment", from_file);
+				elf_load_image_segment = i;
+			}
+		}
+		if (elf_load_image_segment == -1)
+			errx(1, "%s: no suitable ELF program segment",
+			     from_file);
+		entry = be32toh(elf_header.e_entry) +
+			be32toh(elf_segments[elf_load_image_segment].p_offset) -
+			be32toh(elf_segments[elf_load_image_segment].p_vaddr);
+	} else if (*(uint8_t *)&ex == 0x1f && ((uint8_t *)&ex)[1] == 0x8b) {
+		entry = 0;
+	} else
+		errx(1, "%s: bad magic number", from_file);
+
+	entry += sizeof(load);
+	lseek(to, sizeof(load), SEEK_CUR);
+
+	total = 0;
+	n = sizeof(buf) - sizeof(load);
+	/* copy the whole file */
+	for (lseek(from, 0, SEEK_SET); ; n = sizeof(buf)) {
+		memset(buf, 0, sizeof(buf));
+		if ((n = read(from, buf, n)) < 0)
+			err(1, "%s", from_file);
+		else if (n == 0)
+			break;
+
+		if (write(to, buf, n) != n)
+			err(1, "%s", to_file);
+
+		total += n;
+		check_sum = cksum(check_sum, (int *)buf, n);
+	}
+
+	/* load header */
+	load.address = htobe32(loadpoint + sizeof(load));
+	load.count = htobe32(4 + total);
+	check_sum = cksum(check_sum, (int *)&load, sizeof(load));
+
+	if (verbose)
+		warnx("wrote %d bytes of file \'%s\'", total, from_file);
+
+	total += sizeof(load);
+	/* insert the header */
+	lseek(to, -total, SEEK_CUR);
+	if (write(to, &load, sizeof(load)) != sizeof(load))
+		err(1, "%s", to_file);
+	lseek(to, total - sizeof(load), SEEK_CUR);
+
+	bzero(buf, sizeof(buf));
+	/* pad to int */
+	n = sizeof(int) - total % sizeof(int);
+	if (total % sizeof(int)) {
+		if (write(to, buf, n) != n)
+			err(1, "%s", to_file);
+		else
+			total += n;
+	}
+
+	/* pad to the blocksize */
+	n = sizeof(buf) - total % sizeof(buf);
+
+	if (n < sizeof(int)) {
+		n += sizeof(buf);
+		total += sizeof(buf);
+	} else
+		total += n;
+
+	/* TODO should pad here to the 65k boundary for tape boot */
+
+	if (verbose)
+		warnx("checksum is 0x%08x", -check_sum);
+
+	check_sum = htobe32(-check_sum);
+	if (write(to, &check_sum, sizeof(int)) != sizeof(int))
+		err(1, "%s", to_file);
+
+	n -= sizeof(int);
+
+	if (write(to, buf, n) != n)
+		err(1, "%s", to_file);
+
+	if (close(from) < 0)
+		err(1, "%s", from_file);
+
+	return total;
+}
+
+int
+cksum(int ck, int *p, int size)
+{
+	/* we assume size is int-aligned */
+	for (size = (size + sizeof(int) - 1) / sizeof(int); size--; p++ )
+		ck += be32toh(*p);
+
+	return ck;
+}
+
+void __dead
+usage(void)
+{
+	fprintf(stderr,
+		"usage: %s [-v] [-l loadpoint] prog1 {progN} outfile\n",
+		getprogname());
+	exit(1);
+}
+
+char *
+lifname(char *str)
+{
+	static char lname[10] = "XXXXXXXXXX";
+	char *cp;
+	int i;
+
+	cp = strrchr(str, '/');
+	if (cp != NULL) {
+		str = cp + 1;
+	}
+	for (i = 0; i < 9; i++) {
+		if (islower(*str))
+			lname[i] = toupper(*str);
+		else if (isalnum(*str) || *str == '_')
+			lname[i] = *str;
+		else
+			break;
+		str++;
+	}
+	for ( ; i < 10; i++)
+		lname[i] = ' ';
+	return(lname);
+}
+
+
+void
+bcddate(char *file, char *toc)
+{
+	struct stat statb;
+	struct tm *tm;
+
+	stat(file, &statb);
+	tm = localtime(&statb.st_ctime);
+	tm->tm_year %= 100;
+	*toc = (tm->tm_year / 10) << 4;
+	*toc++ |= tm->tm_year % 10;
+	*toc = ((tm->tm_mon+1) / 10) << 4;
+	*toc++ |= (tm->tm_mon+1) % 10;
+	*toc = (tm->tm_mday / 10) << 4;
+	*toc++ |= tm->tm_mday % 10;
+	*toc = (tm->tm_hour / 10) << 4;
+	*toc++ |= tm->tm_hour % 10;
+	*toc = (tm->tm_min / 10) << 4;
+	*toc++ |= tm->tm_min % 10;
+	*toc = (tm->tm_sec / 10) << 4;
+	*toc |= tm->tm_sec % 10;
+}
diff -Naur -x CVS ../src.orig/tools/Makefile ./tools/Makefile
--- ../src.orig/tools/Makefile	2004-06-05 14:18:13.000000000 -0500
+++ ./tools/Makefile	2004-06-05 15:55:33.000000000 -0500
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.81 2004/01/03 14:04:27 lukem Exp $
+#	$NetBSD: Makefile,v 1.9 2004/01/03 14:04:27 lukem Exp $
 
 .include <bsd.own.mk>
 
@@ -44,6 +44,10 @@
 SUBDIR+=	ibmnws-ncdcs
 .endif
 
+.if ${MACHINE} == hp700
+SUBDIR+=	mklifboot
+.endif
+
 .if ${MACHINE} == macppc
 SUBDIR+=	macppc-fixcoff
 .endif
diff -Naur -x CVS ../src.orig/tools/mklifboot/Makefile ./tools/mklifboot/Makefile
--- ../src.orig/tools/mklifboot/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ ./tools/mklifboot/Makefile	2004-06-05 15:55:48.000000000 -0500
@@ -0,0 +1,6 @@
+#	$NetBSD: Makefile,v 1.0 2003/12/30 21:08:26 jmc Exp $
+
+HOSTPROGNAME=	${_TOOL_PREFIX}mklifboot
+HOST_SRCDIR=	sys/arch/hp700/stand/mklifboot
+
+.include "${.CURDIR}/../Makefile.host"

--Apple-Mail-1-803602517
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed


------------------------------------------------------------------------ 
--------
Zach Lowry                                                  
http://www.netbsd.org
MTSU, Murfreesboro, TN                              Owner of 20 NetBSD  
Platforms

-----BEGIN GEEK CODE BLOCK-----
  Version: 3.1
  GCS/IT/MU d-> s>+:->-- a-- C++$>+++ UBLUAHIOSX++++$ P++$>+++ L++++ !E  
W++ N++ !o !K-- w--$>--- !O M++ !V PS++>+++ PE+++ Y PGP !t !5 !X R tv>+  
b+>++ DI+>++ D++ G e++>+++ h++ r+++ y++++**
  ------END GEEK CODE BLOCK------
--Apple-Mail-1-803602517--