PATCH: Rename and auto-build mkboot with tools

Zach Lowry <[email protected]>
Newsgroups gmane.os.netbsd.ports.hp700
Message-ID <[email protected]>
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.


------------------------------------------------------------------------ 
--------
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------
mklifboot.patch (application/octet-stream, 24.8 KB)
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"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.