diff options
author | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2007-09-04 23:28:27 +0000 |
---|---|---|
committer | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2007-09-04 23:28:27 +0000 |
commit | ed2c81c020cc88cbbf163e0b0ea1b6bca2fbf8cb (patch) | |
tree | f435763744f8a6a4ceb1ebccde900efde544e88d /usr.sbin | |
parent | 47466b70b139eca58302a1af773a0e76c0a280a0 (diff) |
add support to print the derivated tree from the OpenPROM (alas devinfo or
prtconf); ok kettenis@.
thanks to the various people who helped me test in different sparc* machines.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/eeprom/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/eeprom/defs.h | 5 | ||||
-rw-r--r-- | usr.sbin/eeprom/eeprom.8 | 8 | ||||
-rw-r--r-- | usr.sbin/eeprom/main.c | 22 | ||||
-rw-r--r-- | usr.sbin/eeprom/ophandlers.c | 3 | ||||
-rw-r--r-- | usr.sbin/eeprom/optree.c | 156 |
6 files changed, 185 insertions, 13 deletions
diff --git a/usr.sbin/eeprom/Makefile b/usr.sbin/eeprom/Makefile index 76b385eba42..cf17a23d638 100644 --- a/usr.sbin/eeprom/Makefile +++ b/usr.sbin/eeprom/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.9 2002/12/31 16:22:26 miod Exp $ +# $OpenBSD: Makefile,v 1.10 2007/09/04 23:28:26 fgsch Exp $ .if ${MACHINE} == "sparc" || ${MACHINE} == "sparc64" PROG= eeprom @@ -9,7 +9,7 @@ BINMODE=2555 SRCS= eehandlers.c getdate.c main.c . if ${MACHINE} == "sparc" || ${MACHINE} == "sparc64" -SRCS+= ophandlers.c +SRCS+= ophandlers.c optree.c . endif CLEANFILES+=getdate.c y.tab.h diff --git a/usr.sbin/eeprom/defs.h b/usr.sbin/eeprom/defs.h index 8be7394133a..a5c629e95bb 100644 --- a/usr.sbin/eeprom/defs.h +++ b/usr.sbin/eeprom/defs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: defs.h,v 1.4 2002/02/17 19:42:36 millert Exp $ */ +/* $OpenBSD: defs.h,v 1.5 2007/09/04 23:28:26 fgsch Exp $ */ /* $NetBSD: defs.h,v 1.2 1996/02/28 01:13:20 thorpej Exp $ */ /*- @@ -109,5 +109,6 @@ void ee_verifychecksums(void); #ifdef __sparc__ /* Sparc Openprom handlers. */ char *op_handler(char *, char *); -void op_dump(void); +void op_dump(void); +void op_tree(void); #endif /* __sparc__ */ diff --git a/usr.sbin/eeprom/eeprom.8 b/usr.sbin/eeprom/eeprom.8 index 7c827113c4a..13ce63875a2 100644 --- a/usr.sbin/eeprom/eeprom.8 +++ b/usr.sbin/eeprom/eeprom.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: eeprom.8,v 1.16 2007/05/31 19:20:23 jmc Exp $ +.\" $OpenBSD: eeprom.8,v 1.17 2007/09/04 23:28:26 fgsch Exp $ .\" $NetBSD: eeprom.8,v 1.2 1996/02/28 01:13:24 thorpej Exp $ .\" .\" Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 31 2007 $ +.Dd $Mdocdate: September 4 2007 $ .Dt EEPROM 8 .Os .Sh NAME @@ -47,6 +47,7 @@ .Op Fl c .Op Fl f Ar device .Op Fl i +.Op Fl p .Op Fl v .Op Fl N Ar system .Oo @@ -90,6 +91,9 @@ If checksum values are incorrect, .Nm eeprom will ignore them and continue after displaying a warning. This flag is quietly ignored on systems with an OpenPROM. +.It Fl p +On systems with an OpenPROM, display the tree derivated from it and exit. +This flag is quietly ignored on systems with an EEPROM. .It Fl v On systems with an OpenPROM, be verbose when setting a value. Systems with an EEPROM are always verbose. diff --git a/usr.sbin/eeprom/main.c b/usr.sbin/eeprom/main.c index 3fdcf072cd6..5b458f66814 100644 --- a/usr.sbin/eeprom/main.c +++ b/usr.sbin/eeprom/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.13 2005/05/02 02:29:27 djm Exp $ */ +/* $OpenBSD: main.c,v 1.14 2007/09/04 23:28:26 fgsch Exp $ */ /* $NetBSD: main.c,v 1.3 1996/05/16 16:00:55 thorpej Exp $ */ /*- @@ -41,6 +41,7 @@ #include <err.h> #include <string.h> #include <stdio.h> +#include <stdlib.h> #include <unistd.h> #ifdef __sparc__ @@ -51,7 +52,7 @@ #include <machine/openpromio.h> -static char *system = NULL; +static char *nlistf = NULL; #endif /* __sparc__ */ #include <machine/eeprom.h> @@ -110,6 +111,7 @@ int cksumfail = 0; u_short writecount; int eval = 0; int use_openprom = 0; +int print_tree = 0; int verbose = 0; extern char *__progname; @@ -121,7 +123,7 @@ main(int argc, char *argv[]) char *cp, line[BUFSIZE]; #ifdef __sparc__ gid_t gid; - char *optstring = "cf:ivN:-"; + char *optstring = "cf:ipvN:-"; #else char *optstring = "cf:i-"; #endif /* __sparc__ */ @@ -144,12 +146,16 @@ main(int argc, char *argv[]) ignore_checksum = 1; break; #ifdef __sparc__ + case 'p': + print_tree = 1; + break; + case 'v': verbose = 1; break; case 'N': - system = optarg; + nlistf = optarg; break; #endif /* __sparc__ */ @@ -162,13 +168,17 @@ main(int argc, char *argv[]) argv += optind; #ifdef __sparc__ - if (system != NULL) { + if (nlistf != NULL) { gid = getgid(); if (setresgid(gid, gid, gid) == -1) err(1, "setresgid"); } if (getcputype() != CPU_SUN4) use_openprom = 1; + if (print_tree && use_openprom) { + op_tree(); + exit(0); + } #endif /* __sparc__ */ if (use_openprom == 0) { @@ -293,7 +303,7 @@ usage(void) #ifdef __sparc__ fprintf(stderr, "usage: %s %s %s\n", __progname, - "[-] [-c] [-f device] [-i] [-v]", + "[-] [-c] [-f device] [-i] [-p] [-v]", "[-N system] [field[=value] ...]"); #else fprintf(stderr, "usage: %s %s\n", __progname, diff --git a/usr.sbin/eeprom/ophandlers.c b/usr.sbin/eeprom/ophandlers.c index ec8cddcd218..3fb666d7cbb 100644 --- a/usr.sbin/eeprom/ophandlers.c +++ b/usr.sbin/eeprom/ophandlers.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ophandlers.c,v 1.9 2005/03/06 16:12:48 miod Exp $ */ +/* $OpenBSD: ophandlers.c,v 1.10 2007/09/04 23:28:26 fgsch Exp $ */ /* $NetBSD: ophandlers.c,v 1.2 1996/02/28 01:13:30 thorpej Exp $ */ /*- @@ -46,6 +46,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include <vis.h> #include <machine/eeprom.h> diff --git a/usr.sbin/eeprom/optree.c b/usr.sbin/eeprom/optree.c new file mode 100644 index 00000000000..3930fbaddc7 --- /dev/null +++ b/usr.sbin/eeprom/optree.c @@ -0,0 +1,156 @@ +/* $OpenBSD: optree.c,v 1.1 2007/09/04 23:28:26 fgsch Exp $ */ + +/* + * Copyright (c) 2007 Federico G. Schwindt <fgsch@openbsd.org> + * 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 ``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 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 <machine/openpromio.h> +#include <sys/ioctl.h> +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +extern char *path_openprom; + +static void +op_print(struct opiocdesc *opio, int depth) +{ + char *p; + int i, special; + + opio->op_name[opio->op_namelen] = '\0'; + printf("%*s%s: ", depth * 4, " ", opio->op_name); + if (opio->op_buflen > 0) { + opio->op_buf[opio->op_buflen] = '\0'; + special = 0; + + for (i = 0; i < opio->op_buflen; i++) { + p = &opio->op_buf[i]; + if ((*p < ' ' || *p > '~') && (*p != '\0' || + (i + 1 < opio->op_buflen && + (*++p < ' ' || *p > '~')))) { + special = 1; + break; + } + } + + if (special) { + for (i = 0; opio->op_buflen - i >= sizeof(int); + i += sizeof(int)) { + if (i) + printf("."); + printf("%08x", *(int *)(long)&opio->op_buf[i]); + } + if (i < opio->op_buflen) { + printf("."); + for (; i < opio->op_buflen; i++) { + printf("%02x", + *(u_char *)&opio->op_buf[i]); + } + } + } else { + for (i = 0; i < opio->op_buflen; + i += strlen(&opio->op_buf[i]) + 1) { + if (i) + printf(" + "); + printf("'%s'", &opio->op_buf[i]); + } + } + } + printf("\n"); +} + +void +op_nodes(int fd, int node, int depth) +{ + char op_buf[BUFSIZ * 4]; + char op_name[BUFSIZ]; + struct opiocdesc opio; + + opio.op_nodeid = node; + opio.op_buf = op_buf; + opio.op_name = op_name; + + if (!node) { + if (ioctl(fd, OPIOCGETNEXT, &opio) < 0) + err(1, "OPIOCGETNEXT"); + node = opio.op_nodeid; + } else + printf("\n%*s", depth * 4, " "); + + printf("Node 0x%x\n", node); + + for (;;) { + opio.op_buflen = sizeof(op_buf); + opio.op_namelen = sizeof(op_name); + + /* Get the next property. */ + if (ioctl(fd, OPIOCNEXTPROP, &opio) < 0) + err(1, "OPIOCNEXTPROP"); + + op_buf[opio.op_buflen] = '\0'; + (void)strlcpy(op_name, op_buf, sizeof(op_name)); + opio.op_namelen = strlen(op_name); + + /* If it's the last, punt. */ + if (opio.op_namelen == 0) + break; + + bzero(op_buf, sizeof(op_buf)); + opio.op_buflen = sizeof(op_buf); + + /* And its value. */ + if (ioctl(fd, OPIOCGET, &opio) < 0) + err(1, "OPIOCGET"); + + op_print(&opio, depth + 1); + } + + /* Get next child. */ + if (ioctl(fd, OPIOCGETCHILD, &opio) < 0) + err(1, "OPIOCGETCHILD"); + if (opio.op_nodeid) + op_nodes(fd, opio.op_nodeid, depth + 1); + + /* Get next node/sibling. */ + opio.op_nodeid = node; + if (ioctl(fd, OPIOCGETNEXT, &opio) < 0) + err(1, "OPIOCGETNEXT"); + if (opio.op_nodeid) + op_nodes(fd, opio.op_nodeid, depth); +} + +void +op_tree(void) +{ + int fd; + + if ((fd = open(path_openprom, O_RDONLY, 0640)) < 0) + err(1, "open: %s", path_openprom); + op_nodes(fd, 0, 0); + (void)close(fd); +} |