summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2018-04-07 14:59:03 +0300
committerDan McDonald <danmcd@joyent.com>2019-01-04 11:13:15 -0500
commitc0455f334914631f42eb41177d677e2820ee6506 (patch)
treebfe2af868d79073f3a299259daf157b63c09f213
parentc62757b2b8b6c26589d7704d0ff20beb107fcd9a (diff)
downloadillumos-joyent-c0455f334914631f42eb41177d677e2820ee6506.tar.gz
9478 etdump: Add the etdump utility for dumping El Torito boot catalog information.
Reviewed by: C Fraire <cfraire@me.com> Reviewed by: Andy Fiddaman <af@citrus-it.net> Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r--usr/src/cmd/Makefile3
-rw-r--r--usr/src/cmd/etdump/Makefile37
-rw-r--r--usr/src/cmd/etdump/THIRDPARTYLICENSE66
-rw-r--r--usr/src/cmd/etdump/THIRDPARTYLICENSE.descrip1
-rw-r--r--usr/src/cmd/etdump/cd9660_conversion.c191
-rw-r--r--usr/src/cmd/etdump/cd9660_eltorito.h187
-rw-r--r--usr/src/cmd/etdump/etdump.c272
-rw-r--r--usr/src/cmd/etdump/etdump.h48
-rw-r--r--usr/src/cmd/etdump/output_shell.c65
-rw-r--r--usr/src/cmd/etdump/output_text.c93
-rw-r--r--usr/src/man/man1/Makefile3
-rw-r--r--usr/src/man/man1/etdump.197
-rw-r--r--usr/src/pkg/manifests/SUNWcs.man1.inc1
-rw-r--r--usr/src/pkg/manifests/system-extended-system-utilities.mf3
14 files changed, 1065 insertions, 2 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index 37e979d619..85c43834e1 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -148,6 +148,7 @@ COMMON_SUBDIRS= \
enhance \
env \
eqn \
+ etdump \
expand \
expr \
exstr \
@@ -777,7 +778,7 @@ AUDITSUBDIRS= \
auditreduce \
auditset \
auditstat \
- praudit
+ praudit
#
# commands not owned by the systems group
diff --git a/usr/src/cmd/etdump/Makefile b/usr/src/cmd/etdump/Makefile
new file mode 100644
index 0000000000..8776a2d698
--- /dev/null
+++ b/usr/src/cmd/etdump/Makefile
@@ -0,0 +1,37 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2018 Toomas Soome <tsoome@me.com>
+#
+
+PROG= etdump
+OBJS= etdump.o output_shell.o output_text.o cd9660_conversion.o
+SRCS= $(OBJS:%.o=%.c)
+
+include ../Makefile.cmd
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTPROG)
+
+clean:
+ $(RM) $(OBJS)
+
+$(PROG): $(OBJS)
+ $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+lint:
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/etdump/THIRDPARTYLICENSE b/usr/src/cmd/etdump/THIRDPARTYLICENSE
new file mode 100644
index 0000000000..f47273514f
--- /dev/null
+++ b/usr/src/cmd/etdump/THIRDPARTYLICENSE
@@ -0,0 +1,66 @@
+cd9660_eltorito.h:
+cd9660_conversion.c:
+/*
+ * SPDX-License-Identifier: BSD-2-Clause-NetBSD
+ *
+ * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
+ * Perez-Rathke and Ram Vedam. All rights reserved.
+ *
+ * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys,
+ * Alan Perez-Rathke and Ram Vedam.
+ *
+ * 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 DANIEL WATT, WALTER DEIGNAN, RYAN
+ * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``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 DANIEL WATT, WALTER DEIGNAN, RYAN
+ * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM 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.
+ */
+
+etdump.h:
+etdump.c:
+etdump.1:
+output_shell.c:
+output_text.c:
+/*
+ * Copyright (c) 2018 iXsystems, Inc.
+ * 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 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 AUTHOR 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.
+ */
diff --git a/usr/src/cmd/etdump/THIRDPARTYLICENSE.descrip b/usr/src/cmd/etdump/THIRDPARTYLICENSE.descrip
new file mode 100644
index 0000000000..18f61b4a66
--- /dev/null
+++ b/usr/src/cmd/etdump/THIRDPARTYLICENSE.descrip
@@ -0,0 +1 @@
+etdump utility cpommand
diff --git a/usr/src/cmd/etdump/cd9660_conversion.c b/usr/src/cmd/etdump/cd9660_conversion.c
new file mode 100644
index 0000000000..a980af35fb
--- /dev/null
+++ b/usr/src/cmd/etdump/cd9660_conversion.c
@@ -0,0 +1,191 @@
+/*
+ * $NetBSD: cd9660_conversion.c,v 1.4 2007/03/14 14:11:17 christos Exp $
+ */
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause-NetBSD
+ *
+ * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
+ * Perez-Rathke and Ram Vedam. All rights reserved.
+ *
+ * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys,
+ * Alan Perez-Rathke and Ram Vedam.
+ *
+ * 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 DANIEL WATT, WALTER DEIGNAN, RYAN
+ * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``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 DANIEL WATT, WALTER DEIGNAN, RYAN
+ * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <endian.h>
+
+static char cd9660_compute_gm_offset(time_t);
+
+/*
+ * These can probably be implemented using a macro
+ */
+
+/* Little endian */
+void
+cd9660_721(uint16_t w, unsigned char *twochar)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+ w = htole16(w);
+#endif
+ memcpy(twochar, &w, 2);
+}
+
+void
+cd9660_731(uint32_t w, unsigned char *fourchar)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+ w = htole32(w);
+#endif
+ memcpy(fourchar, &w, 4);
+}
+
+/* Big endian */
+void
+cd9660_722(uint16_t w, unsigned char *twochar)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ w = htobe16(w);
+#endif
+ memcpy(twochar, &w, 2);
+}
+
+void
+cd9660_732(uint32_t w, unsigned char *fourchar)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ w = htobe32(w);
+#endif
+ memcpy(fourchar, &w, 4);
+}
+
+/*
+ * Convert a dword into a double endian string of eight characters
+ * @param int The double word to convert
+ * @param char* The string to write the both endian double word to - It is
+ * assumed this is allocated and at least eight characters long.
+ */
+void
+cd9660_bothendian_dword(uint32_t dw, unsigned char *eightchar)
+{
+ uint32_t le, be;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ le = dw;
+ be = htobe32(dw);
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ be = dw;
+ le = htole32(dw);
+#endif
+ memcpy(eightchar, &le, 4);
+ memcpy((eightchar+4), &be, 4);
+}
+
+/*
+ * Convert a word into a double endian string of four characters
+ * @param int The word to convert
+ * @param char* The string to write the both endian word to - It is assumed
+ * this is allocated and at least four characters long.
+ */
+void
+cd9660_bothendian_word(uint16_t dw, unsigned char *fourchar)
+{
+ uint16_t le, be;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ le = dw;
+ be = htobe16(dw);
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ be = dw;
+ le = htole16(dw);
+#endif
+ memcpy(fourchar, &le, 2);
+ memcpy((fourchar+2), &be, 2);
+}
+
+void
+cd9660_pad_string_spaces(char *str, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i ++) {
+ if (str[i] == '\0')
+ str[i] = 0x20;
+ }
+}
+
+static char
+cd9660_compute_gm_offset(time_t tim)
+{
+ struct tm t, gm;
+
+ (void) localtime_r(&tim, &t);
+ (void) gmtime_r(&tim, &gm);
+ gm.tm_year -= t.tm_year;
+ gm.tm_yday -= t.tm_yday;
+ gm.tm_hour -= t.tm_hour;
+ gm.tm_min -= t.tm_min;
+ if (gm.tm_year < 0)
+ gm.tm_yday = -1;
+ else if (gm.tm_year > 0)
+ gm.tm_yday = 1;
+
+ return (char)(-(gm.tm_min + 60* (24 * gm.tm_yday + gm.tm_hour)) / 15);
+}
+
+/* Long dates: 17 characters */
+void
+cd9660_time_8426(unsigned char *buf, time_t tim)
+{
+ struct tm t;
+ char temp[18];
+
+ (void) localtime_r(&tim, &t);
+ (void) snprintf(temp, sizeof (temp), "%04i%02i%02i%02i%02i%02i%02i",
+ 1900 + (int)t.tm_year, (int)t.tm_mon + 1, (int)t.tm_mday,
+ (int)t.tm_hour, (int)t.tm_min, (int)t.tm_sec, 0);
+ (void) memcpy(buf, temp, 16);
+ buf[16] = cd9660_compute_gm_offset(tim);
+}
+
+/* Short dates: 7 characters */
+void
+cd9660_time_915(unsigned char *buf, time_t tim)
+{
+ struct tm t;
+
+ (void) localtime_r(&tim, &t);
+ buf[0] = t.tm_year;
+ buf[1] = t.tm_mon+1;
+ buf[2] = t.tm_mday;
+ buf[3] = t.tm_hour;
+ buf[4] = t.tm_min;
+ buf[5] = t.tm_sec;
+ buf[6] = cd9660_compute_gm_offset(tim);
+}
diff --git a/usr/src/cmd/etdump/cd9660_eltorito.h b/usr/src/cmd/etdump/cd9660_eltorito.h
new file mode 100644
index 0000000000..c73f591a73
--- /dev/null
+++ b/usr/src/cmd/etdump/cd9660_eltorito.h
@@ -0,0 +1,187 @@
+/*
+ * $NetBSD: cd9660_eltorito.h,v 1.6 2017/01/24 11:22:43 nonaka Exp $
+ */
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause-NetBSD
+ *
+ * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
+ * Perez-Rathke and Ram Vedam. All rights reserved.
+ *
+ * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys,
+ * Alan Perez-Rathke and Ram Vedam.
+ *
+ * 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 DANIEL WATT, WALTER DEIGNAN, RYAN
+ * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``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 DANIEL WATT, WALTER DEIGNAN, RYAN
+ * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM 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.
+ */
+
+#ifndef _CD9660_ELTORITO_H_
+#define _CD9660_ELTORITO_H_
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+/* Boot defines */
+#define ET_ID "EL TORITO SPECIFICATION"
+#define ET_SYS_X86 0
+#define ET_SYS_PPC 1
+#define ET_SYS_MAC 2
+#define ET_SYS_EFI 0xef /* Platform ID at section header entry */
+
+#define ET_BOOT_ENTRY_SIZE 0x20
+
+#define ET_BOOTABLE 0x88
+#define ET_NOT_BOOTABLE 0
+
+#define ET_MEDIA_NOEM 0
+#define ET_MEDIA_12FDD 1
+#define ET_MEDIA_144FDD 2
+#define ET_MEDIA_288FDD 3
+#define ET_MEDIA_HDD 4
+
+#define ET_INDICATOR_HEADERMORE 0x90
+#define ET_INDICATOR_HEADERLAST 0x91
+#define ET_INDICATOR_EXTENSION 0x44
+
+/* Boot Structures */
+
+#define ISODCL(from, to) (to - from + 1)
+
+typedef struct _boot_volume_descriptor {
+ uchar_t boot_record_indicator [ISODCL(0x00, 0x00)];
+ uchar_t identifier [ISODCL(0x01, 0x05)];
+ uchar_t version [ISODCL(0x06, 0x06)];
+ uchar_t boot_system_identifier [ISODCL(0x07, 0x26)];
+ uchar_t unused1 [ISODCL(0x27, 0x46)];
+ uchar_t boot_catalog_pointer [ISODCL(0x47, 0x4A)];
+ uchar_t unused2 [ISODCL(0x4B, 0x7FF)];
+} boot_volume_descriptor;
+
+typedef struct _boot_catalog_validation_entry {
+ uchar_t header_id [ISODCL(0x00, 0x00)];
+ uchar_t platform_id [ISODCL(0x01, 0x01)];
+ uchar_t reserved1 [ISODCL(0x02, 0x03)];
+ uchar_t manufacturer [ISODCL(0x04, 0x1B)];
+ uchar_t checksum [ISODCL(0x1C, 0x1D)];
+ uchar_t key [ISODCL(0x1E, 0x1F)];
+} boot_catalog_validation_entry;
+
+typedef struct _boot_catalog_initial_entry {
+ uchar_t boot_indicator [ISODCL(0x00, 0x00)];
+ uchar_t media_type [ISODCL(0x01, 0x01)];
+ uchar_t load_segment [ISODCL(0x02, 0x03)];
+ uchar_t system_type [ISODCL(0x04, 0x04)];
+ uchar_t unused_1 [ISODCL(0x05, 0x05)];
+ uchar_t sector_count [ISODCL(0x06, 0x07)];
+ uchar_t load_rba [ISODCL(0x08, 0x0B)];
+ uchar_t unused_2 [ISODCL(0x0C, 0x1F)];
+} boot_catalog_initial_entry;
+
+#define ET_SECTION_HEADER_MORE 0x90
+#define ET_SECTION_HEADER_LAST 0x91
+
+typedef struct _boot_catalog_section_header {
+ uchar_t header_indicator [ISODCL(0x00, 0x00)];
+ uchar_t platform_id [ISODCL(0x01, 0x01)];
+ uchar_t num_section_entries [ISODCL(0x02, 0x03)];
+ uchar_t id_string [ISODCL(0x04, 0x1F)];
+} boot_catalog_section_header;
+
+typedef struct _boot_catalog_section_entry {
+ uchar_t boot_indicator [ISODCL(0x00, 0x00)];
+ uchar_t media_type [ISODCL(0x01, 0x01)];
+ uchar_t load_segment [ISODCL(0x02, 0x03)];
+ uchar_t system_type [ISODCL(0x04, 0x04)];
+ uchar_t unused_1 [ISODCL(0x05, 0x05)];
+ uchar_t sector_count [ISODCL(0x06, 0x07)];
+ uchar_t load_rba [ISODCL(0x08, 0x0B)];
+ uchar_t selection_criteria [ISODCL(0x0C, 0x0C)];
+ uchar_t vendor_criteria [ISODCL(0x0D, 0x1F)];
+} boot_catalog_section_entry;
+
+typedef struct _boot_catalog_section_entry_extension {
+ uchar_t extension_indicator [ISODCL(0x00, 0x00)];
+ uchar_t flags [ISODCL(0x01, 0x01)];
+ uchar_t vendor_criteria [ISODCL(0x02, 0x1F)];
+} boot_catalog_section_entry_extension;
+
+#define ET_ENTRY_VE 1
+#define ET_ENTRY_IE 2
+#define ET_ENTRY_SH 3
+#define ET_ENTRY_SE 4
+#define ET_ENTRY_EX 5
+
+struct boot_catalog_entry {
+ char entry_type;
+ union {
+ boot_catalog_validation_entry VE;
+ boot_catalog_initial_entry IE;
+ boot_catalog_section_header SH;
+ boot_catalog_section_entry SE;
+ boot_catalog_section_entry_extension EX;
+ } entry_data;
+
+ LIST_ENTRY(boot_catalog_entry) ll_struct;
+};
+
+/* Temporary structure */
+struct cd9660_boot_image {
+ char *filename;
+ int size;
+ int sector; /* copied to LoadRBA */
+ int num_sectors;
+ unsigned int loadSegment;
+ uchar_t targetMode;
+ uchar_t system;
+ uchar_t bootable;
+ uchar_t platform_id; /* for section header entry */
+ /*
+ * If the boot image exists in the filesystem
+ * already, this is a pointer to that node. For the sake
+ * of simplicity in future versions, this pointer is only
+ * to the node in the primary volume. This SHOULD be done
+ * via a hashtable lookup.
+ */
+ struct _cd9660node *boot_image_node;
+ TAILQ_ENTRY(cd9660_boot_image) image_list;
+ int serialno;
+};
+
+void cd9660_721(uint16_t, unsigned char *);
+
+static __inline uint16_t
+isonum_721(const unsigned char *p)
+{
+
+ return (p[0] | p[1] << 8);
+}
+
+static __inline uint32_t
+isonum_731(const unsigned char *p)
+{
+
+ return (p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24);
+}
+
+#endif /* _CD9660_ELTORITO_H_ */
diff --git a/usr/src/cmd/etdump/etdump.c b/usr/src/cmd/etdump/etdump.c
new file mode 100644
index 0000000000..5469597151
--- /dev/null
+++ b/usr/src/cmd/etdump/etdump.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2018 iXsystems, Inc.
+ * 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 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 AUTHOR 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.
+ */
+
+#include <err.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <sys/fs/hsfs_isospec.h>
+#include "cd9660_eltorito.h"
+
+#include "etdump.h"
+
+#define ISO_DEFAULT_BLOCK_SHIFT 11
+#define ISO_DEFAULT_BLOCK_SIZE (1 << ISO_DEFAULT_BLOCK_SHIFT)
+
+const char *
+system_id_string(uchar_t system_id)
+{
+
+ switch (system_id) {
+ case ET_SYS_X86:
+ return ("i386");
+ case ET_SYS_PPC:
+ return ("powerpc");
+ case ET_SYS_MAC:
+ return ("mac");
+ case ET_SYS_EFI:
+ return ("efi");
+ default:
+ return ("invalid");
+ }
+}
+
+const char *
+media_type_string(uchar_t media_type)
+{
+
+ switch (media_type) {
+ case ET_MEDIA_NOEM:
+ return ("no emulation");
+ case ET_MEDIA_12FDD:
+ return ("1.2MB FDD");
+ case ET_MEDIA_144FDD:
+ return ("1.44MB FDD");
+ case ET_MEDIA_288FDD:
+ return ("2.88MB FDD");
+ case ET_MEDIA_HDD:
+ return ("HDD");
+ default:
+ return ("invalid");
+ }
+}
+
+static int
+read_sector(FILE *iso, daddr_t sector, char *buffer)
+{
+
+ fseek(iso, sector * ISO_DEFAULT_BLOCK_SIZE, SEEK_SET);
+ if (fread(buffer, ISO_DEFAULT_BLOCK_SIZE, 1, iso) != 1) {
+ return (errno);
+ }
+ return (0);
+}
+
+static bool
+boot_catalog_valid(char *entry)
+{
+ boot_catalog_validation_entry *ve;
+ int16_t checksum, sum;
+ unsigned char *csptr;
+ size_t i;
+
+ ve = (boot_catalog_validation_entry *)entry;
+
+ checksum = isonum_721(ve->checksum);
+ cd9660_721(0, ve->checksum);
+ csptr = (unsigned char *)ve;
+
+ for (i = sum = 0; i < sizeof (*ve); i += 2) {
+ sum += (int16_t)csptr[i];
+ sum += 256 * (int16_t)csptr[i + 1];
+ }
+ if (sum + checksum != 0) {
+ return (false);
+ }
+
+ cd9660_721(checksum, ve->checksum);
+ return (true);
+}
+
+static int
+dump_section(char *buffer, size_t offset, FILE *outfile, const char *filename,
+ struct outputter *outputter)
+{
+ boot_catalog_section_header *sh;
+ uchar_t platform_id;
+ int i;
+ size_t entry_offset;
+ boot_catalog_section_entry *entry;
+
+ sh = (boot_catalog_section_header *)&buffer[offset];
+ if (outputter->output_section != NULL) {
+ outputter->output_section(outfile, filename, sh);
+ }
+
+ platform_id = sh->platform_id[0];
+
+ if (outputter->output_entry != NULL) {
+ for (i = 1; i <= (int)sh->num_section_entries[0]; i++) {
+ entry_offset = offset + i * ET_BOOT_ENTRY_SIZE;
+ entry =
+ (boot_catalog_section_entry *)&buffer[entry_offset];
+ outputter->output_entry(outfile, filename, entry,
+ platform_id, false);
+ }
+ }
+
+ return (1 + (int)sh->num_section_entries[0]);
+}
+
+static void
+dump_eltorito(FILE *iso, const char *filename, FILE *outfile,
+ struct outputter *outputter)
+{
+ char buffer[ISO_DEFAULT_BLOCK_SIZE], *entry;
+ boot_volume_descriptor *bvd;
+ daddr_t boot_catalog;
+ size_t offset;
+ int entry_count;
+
+ if (read_sector(iso, 17, buffer) != 0)
+ err(1, "failed to read from image");
+
+ bvd = (boot_volume_descriptor *)buffer;
+ if (memcmp(bvd->identifier, ISO_ID_STRING, 5) != 0)
+ warnx("%s: not a valid ISO", filename);
+ if (bvd->boot_record_indicator[0] != ISO_VD_BOOT)
+ warnx("%s: not an El Torito bootable ISO", filename);
+ if (memcmp(bvd->boot_system_identifier, ET_ID, 23) != 0)
+ warnx("%s: not an El Torito bootable ISO", filename);
+
+ boot_catalog = isonum_731(bvd->boot_catalog_pointer);
+
+ if (read_sector(iso, boot_catalog, buffer) != 0)
+ err(1, "failed to read from image");
+
+ entry = buffer;
+ offset = 0;
+
+ if (!boot_catalog_valid(entry))
+ warnx("%s: boot catalog checksum is invalid", filename);
+
+ if (outputter->output_image != NULL)
+ outputter->output_image(outfile, filename, bvd);
+
+ offset += ET_BOOT_ENTRY_SIZE;
+ entry = &buffer[offset];
+ if (outputter->output_entry != NULL)
+ outputter->output_entry(outfile, filename,
+ (boot_catalog_section_entry *)entry, 0, true);
+
+ offset += ET_BOOT_ENTRY_SIZE;
+
+ while (offset < ISO_DEFAULT_BLOCK_SIZE) {
+ entry = &buffer[offset];
+
+ if ((uint8_t)entry[0] != ET_SECTION_HEADER_MORE &&
+ (uint8_t)entry[0] != ET_SECTION_HEADER_LAST)
+ break;
+
+ entry_count = dump_section(buffer, offset, outfile, filename,
+ outputter);
+
+ offset += entry_count * ET_BOOT_ENTRY_SIZE;
+ }
+}
+
+static void
+usage(const char *progname)
+{
+ char *path;
+
+ path = strdup(progname);
+
+ fprintf(stderr, "usage: %s [-f format] [-o filename] filename [...]\n",
+ basename(path));
+ fprintf(stderr, "\tsupported output formats: shell, text\n");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch, i;
+ FILE *outfile, *iso;
+ struct outputter *outputter;
+
+ outfile = stdout;
+ outputter = output_text;
+
+ static struct option longopts[] = {
+ { "format", required_argument, NULL, 'f' },
+ { "output", required_argument, NULL, 'o' },
+ { NULL, 0, NULL, 0 },
+ };
+
+ while ((ch = getopt_long(argc, argv, "f:o:", longopts, NULL)) != -1) {
+ switch (ch) {
+ case 'f':
+ if (strcmp(optarg, "shell") == 0)
+ outputter = output_shell;
+ else if (strcmp(optarg, "text") == 0)
+ outputter = output_text;
+ else
+ usage(argv[0]);
+ break;
+ case 'o':
+ if (strcmp(optarg, "-") == 0) {
+ outfile = stdout;
+ } else if ((outfile = fopen(optarg, "w")) == NULL) {
+ err(1, "unable to open %s for output", optarg);
+ }
+ break;
+ default:
+ usage(argv[0]);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "-") == 0) {
+ iso = stdin;
+ } else {
+ iso = fopen(argv[i], "r");
+ if (iso == NULL)
+ err(1, "could not open %s", argv[1]);
+ }
+ dump_eltorito(iso, argv[i], outfile, outputter);
+ }
+ return (0);
+}
diff --git a/usr/src/cmd/etdump/etdump.h b/usr/src/cmd/etdump/etdump.h
new file mode 100644
index 0000000000..f7e64205dd
--- /dev/null
+++ b/usr/src/cmd/etdump/etdump.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018 iXsystems, Inc.
+ * 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 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 AUTHOR 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.
+ *
+ * $FreeBSD: head/usr.bin/etdump/etdump.h 331949 2018-04-03 21:08:10Z benno $
+ */
+
+#ifndef _ETDUMP_H_
+#define _ETDUMP_H_
+
+struct outputter {
+ void (*output_image)(FILE *outfile, const char *filename,
+ boot_volume_descriptor *bvd);
+ void (*output_section)(FILE *outfile, const char *filename,
+ boot_catalog_section_header *bcsh);
+ void (*output_entry)(FILE *outfile, const char *filename,
+ boot_catalog_section_entry *bcse,
+ uchar_t platform_id, bool initial);
+};
+
+extern struct outputter *output_text;
+extern struct outputter *output_shell;
+
+const char *system_id_string(uchar_t system_id);
+const char *media_type_string(uchar_t media_type);
+
+#endif /* _ETDUMP_H_ */
diff --git a/usr/src/cmd/etdump/output_shell.c b/usr/src/cmd/etdump/output_shell.c
new file mode 100644
index 0000000000..291983ff64
--- /dev/null
+++ b/usr/src/cmd/etdump/output_shell.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 iXsystems, Inc.
+ * 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 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 AUTHOR 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.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "cd9660_eltorito.h"
+
+#include "etdump.h"
+
+static void
+output_entry(FILE *outfile, const char *filename __unused,
+ boot_catalog_section_entry *bcse, uchar_t platform_id, bool initial)
+{
+ const char *platform;
+
+ switch (bcse->boot_indicator[0]) {
+ case ET_BOOTABLE:
+ break;
+ case ET_NOT_BOOTABLE:
+ default:
+ return;
+ }
+
+ if (initial)
+ platform = "default";
+ else
+ platform = system_id_string(platform_id);
+
+ fprintf(outfile,
+ "et_platform=%s;et_system=%s;et_lba=%d;et_sectors=%d\n",
+ platform, system_id_string(bcse->system_type[0]),
+ isonum_731(bcse->load_rba), isonum_721(bcse->sector_count));
+}
+
+static struct outputter _output_shell = {
+ .output_image = NULL,
+ .output_section = NULL,
+ .output_entry = output_entry,
+};
+
+struct outputter *output_shell = &_output_shell;
diff --git a/usr/src/cmd/etdump/output_text.c b/usr/src/cmd/etdump/output_text.c
new file mode 100644
index 0000000000..eb0681c63f
--- /dev/null
+++ b/usr/src/cmd/etdump/output_text.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018 iXsystems, Inc.
+ * 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 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 AUTHOR 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.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "cd9660_eltorito.h"
+#include "etdump.h"
+
+static void
+output_image(FILE *outfile, const char *filename,
+ boot_volume_descriptor *bvd __unused)
+{
+
+ fprintf(outfile, "Image in %s\n", filename);
+}
+
+static void
+output_section(FILE *outfile, const char *filename __unused,
+ boot_catalog_section_header *bcsh)
+{
+
+ fprintf(outfile, "\nSection header: %s",
+ system_id_string(bcsh->platform_id[0]));
+
+ if (bcsh->header_indicator[0] == ET_SECTION_HEADER_LAST)
+ fprintf(outfile, ", final\n");
+ else
+ fprintf(outfile, "\n");
+}
+
+static void
+output_entry(FILE *outfile, const char *filename __unused,
+ boot_catalog_section_entry *bcse, uchar_t platform_id __unused,
+ bool initial)
+{
+ const char *indent;
+
+ switch (bcse->boot_indicator[0]) {
+ case ET_BOOTABLE:
+ break;
+ case ET_NOT_BOOTABLE:
+ default:
+ return;
+ }
+
+ if (initial) {
+ fprintf(outfile, "Default entry\n");
+ indent = "\t";
+ } else {
+ fprintf(outfile, "\tSection entry\n");
+ indent = "\t\t";
+ }
+
+ fprintf(outfile, "%sSystem %s\n", indent,
+ system_id_string(bcse->system_type[0]));
+ fprintf(outfile, "%sStart LBA %d (0x%x), sector count %d (0x%x)\n",
+ indent, isonum_731(bcse->load_rba), isonum_731(bcse->load_rba),
+ isonum_721(bcse->sector_count), isonum_721(bcse->sector_count));
+ fprintf(outfile, "%sMedia type: %s\n", indent,
+ media_type_string(bcse->media_type[0]));
+}
+
+static struct outputter _output_text = {
+ .output_image = output_image,
+ .output_section = output_section,
+ .output_entry = output_entry,
+};
+
+struct outputter *output_text = &_output_text;
diff --git a/usr/src/man/man1/Makefile b/usr/src/man/man1/Makefile
index fb16e3462d..8629eff5d0 100644
--- a/usr/src/man/man1/Makefile
+++ b/usr/src/man/man1/Makefile
@@ -17,7 +17,7 @@
include $(SRC)/Makefile.master
-MANSECT= 1
+MANSECT= 1
MANFILES= acctcom.1 \
adb.1 \
@@ -120,6 +120,7 @@ MANFILES= acctcom.1 \
enhance.1 \
env.1 \
eqn.1 \
+ etdump.1 \
exec.1 \
exit.1 \
expand.1 \
diff --git a/usr/src/man/man1/etdump.1 b/usr/src/man/man1/etdump.1
new file mode 100644
index 0000000000..a806eccc8b
--- /dev/null
+++ b/usr/src/man/man1/etdump.1
@@ -0,0 +1,97 @@
+.\" Copyright (c) 2018 iXsystems, Inc
+.\" 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 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 AUTHOR 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.
+.\"
+.Dd April 3, 2018
+.Dt ETDUMP 1
+.Os
+.Sh NAME
+.Nm etdump
+.Nd Dump El Torito boot catalog information from ISO images
+.Sh SYNOPSIS
+.Nm
+.Op Fl f Ar format
+.Op Fl o Ar file
+.Ar
+.Sh DESCRIPTION
+This program reads El Torito boot catalog information from an ISO image and
+outputs it in various formats.
+It can be used to check the catalog in an image or to output catalog data in
+a format that can be used by other tools such as shell scripts.
+.Pp
+Supported options are:
+.Bl -tag -width flag
+.It Fl f Ar format Fl -format Ar format
+Select the output format.
+Supported output formats are:
+.Bl -tag -width shell -offset indent
+.It Sy text
+Human-readable text (default)
+.It Sy shell
+Each boot entry is emitted as a string suitable for passing to a sh-compatible
+eval command.
+The variables emitted are:
+.Bl -tag -width et_platform -offset indent
+.It et_platform
+The platform ID from the section header.
+Set to 'default' for the initial (default) entry.
+.It et_system
+The system ID from the boot entry.
+.It et_lba
+The starting LBA (2048-byte blocks) of the boot image.
+.It et_sectors
+The number of sectors (512-byte sectors) that comprise the boot image.
+.El
+.El
+.It Fl o Ar file Fl -output Ar file
+Write output to
+.Ar file .
+If '-' is specified then standard out is used.
+.El
+.Sh EXAMPLES
+To see what entries are in a given boot catalog run
+.Nm
+passing the filename of the image as an argument like so:
+.Bd -literal -offset indent
+% etdump bootonly.iso
+Image in bootonly.iso
+Default entry
+ System i386
+ Start LBA 420 (0x1a4), sector count 4 (0x4)
+ Media type: no emulation
+
+Section header: efi, final
+ Section entry
+ System i386
+ Start LBA 20 (0x14), sector count 1600 (0x640)
+ Media type: no emulation
+.Ed
+.Pp
+To use the output in a shell script a for loop can be used to iterate over the
+entries returned using eval:
+.Bd -literal -offset indent
+for entry in `etdump --format shell bootonly.iso`; do
+ eval $entry
+ echo $et_platform $et_system $et_lba $et_sectors
+done
+.Ed
diff --git a/usr/src/pkg/manifests/SUNWcs.man1.inc b/usr/src/pkg/manifests/SUNWcs.man1.inc
index f42294f4cd..381f383b88 100644
--- a/usr/src/pkg/manifests/SUNWcs.man1.inc
+++ b/usr/src/pkg/manifests/SUNWcs.man1.inc
@@ -71,6 +71,7 @@ file path=usr/share/man/man1/ed.1
file path=usr/share/man/man1/eject.1
file path=usr/share/man/man1/encrypt.1
file path=usr/share/man/man1/env.1
+file path=usr/share/man/man1/etdump.1
file path=usr/share/man/man1/exec.1
file path=usr/share/man/man1/exit.1
file path=usr/share/man/man1/expr.1
diff --git a/usr/src/pkg/manifests/system-extended-system-utilities.mf b/usr/src/pkg/manifests/system-extended-system-utilities.mf
index 546da82239..f9fa79d5ed 100644
--- a/usr/src/pkg/manifests/system-extended-system-utilities.mf
+++ b/usr/src/pkg/manifests/system-extended-system-utilities.mf
@@ -107,6 +107,7 @@ file path=usr/bin/diff mode=0555
file path=usr/bin/diff3 mode=0555
file path=usr/bin/dircmp mode=0555
file path=usr/bin/dos2unix mode=0555
+file path=usr/bin/etdump mode=0555
file path=usr/bin/expand mode=0555
file path=usr/bin/factor mode=0555
file path=usr/bin/kstat mode=0555
@@ -247,6 +248,8 @@ license cr_Sun license=cr_Sun
license lic_CDDL license=lic_CDDL
license usr/src/cmd/compress/THIRDPARTYLICENSE \
license=usr/src/cmd/compress/THIRDPARTYLICENSE
+license usr/src/cmd/etdump/THIRDPARTYLICENSE \
+ license=usr/src/cmd/etdump/THIRDPARTYLICENSE
license usr/src/cmd/lastcomm/THIRDPARTYLICENSE \
license=usr/src/cmd/lastcomm/THIRDPARTYLICENSE
license usr/src/cmd/look/THIRDPARTYLICENSE \