Add eeprom(8), a utility to display and modify system configurations

stored in EEPROM or NVRAM. It's inspired by the NetBSD eeprom(8) and
the SunOS/Solaris eeprom(1M) utilities. Currently, this eeprom(8)
only supports systems equipped with Open Firmware and is only tested
on Sun machines but should work on any platform using Open Firmware.
A bit more specific, eeprom(8) can be used on these systems to do the
same under FreeBSD as can be done using the printenv and setenv
commandos in the boot monitor. One thing that only hardly can be done
using the boot monitor but easily with eeprom(8) is to write a logo
to the "oem-logo" property. eeprom(8) may also be useful to recover
the boot monitor password (in the default configuration only as root,
of course), i.e. when the boot monitor allows you to boot but you
can't alter the configuration because the password is unknown. The
man page may also be a useful reference of the various configuration
variables.

The idea of eeprom(8) is that handlers can be written to add support
for any firmware that stores such configuration in EEPROM or NVRAM;
sort of e.g. eeprom(1M) on Solaris/x86 is used to turn PAE-support
on and off (stored in a file then, not hardware). In FreeBSD, a
candidate for this would be a handler for the EFI boot environment
for FreeBSD/ia64.

eeprom(8) uses some code from NetBSD (eeprom.c and the base for
eeprom.8), the handler for the Open Firmware /options node
(ofw_options.[c,h]) was written using ofw_util.[c,h] from ofwdump(8).

Reviewed by:	ru (slightly earlier version of the man page)
This commit is contained in:
marius 2004-05-22 16:56:04 +00:00
parent 3c4ba8308a
commit bd8e8f6899
5 changed files with 1181 additions and 0 deletions

12
usr.sbin/eeprom/Makefile Normal file
View File

@ -0,0 +1,12 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../ofwdump
PROG= eeprom
MAN= eeprom.8
MANSUBDIR= /sparc64
SRCS= eeprom.c ofw_options.c ofw_util.c
WARNS?= 6
CFLAGS+= -I${.CURDIR}/../ofwdump
.include <bsd.prog.mk>

668
usr.sbin/eeprom/eeprom.8 Normal file
View File

@ -0,0 +1,668 @@
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
.\" Copyright (c) 2004 Marius Strobl
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Jason R. Thorpe.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the NetBSD
.\" Foundation, Inc. and its contributors.
.\" 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" from: NetBSD: eeprom.8,v 1.11 2003/03/31 01:31:39 perry Exp
.\" $FreeBSD$
.\"
.Dd May 16, 2004
.Dt EEPROM 8 sparc64
.Os
.Sh NAME
.Nm eeprom
.Nd "display or modify contents of the EEPROM or NVRAM"
.Sh SYNOPSIS
.Nm
.Fl a
.Nm
.Op Fl
.Ar name Ns Op = Ns Ar value
.Ar ...
.Sh DESCRIPTION
The
.Nm
utility provides an interface for displaying and changing the system's
configuration variables contained in EEPROM or NVRAM.
In the first synopsis form, all available configuration variables and their
current values are printed.
In the second form, only the variable selected by
.Ar name
and its value is printed or changed if
.Ar name
is followed by
.Ql =
and a
.Ar value .
.Pp
The following options are available:
.Bl -tag -width indent
.It Fl
Commands for displaying or changing variables are taken from stdin, allowing
one
.Ar name
or one
.Ar name
and
.Ar value
pair per line.
The output is printed on stdout.
.It Fl a
Print all available configuration variables and their current values.
.El
.Sh VARIABLES AND VALUES
Below are variables and values that one is likely to find on a system equipped
with OpenBoot 3.x and Open Firmware respectively.
.Pp
Note: the attempt to set a variable to an illegal value results in the
Open Firmware setting it to some legal value instead.
The
.Nm
utility will detect this, try to recover the previous value of the variable
and issue a warning telling that the requested value could not be set.
.Bl -tag -width ".Va last-hardware-update"
.It Va auto-boot?
If
.Dq Li true ,
the system will try to boot automatically from the devices listed in
.Va boot-device
and
.Va diag-device
respectively, using the command specified in
.Va boot-command
at power-up.
Default:
.Dq Li true .
.It Va auto-boot-retry?
If set to
.Dq Li true
and
.Va auto-boot?
is also set to
.Dq Li true ,
the system will try to boot from the specified boot devices forever.
Default:
.Dq Li false .
.It Va ansi-terminal?
If
.Dq Li false ,
.Tn ANSI
escape sequences are not interpreted by the terminal emulator.
Default:
.Dq Li true .
.It Va boot-command
Command executed when
.Va auto-boot?
is set to
.Dq Li true .
Default:
.Dq Li boot .
.It Va boot-device
Default device to boot from if
.Va diag-switch?
is set to
.Dq Li false .
Takes one or more device aliases or device paths.
The boot devices are sequentially tried to boot from, beginning with the first
one specified.
Default:
.Dq Li "net disk" .
.It Va cpci-probe-list
Digits in the format
.Dq Li 0,1,2
specifying in which order to probe the devices on the CompactPCI bus at
power-up.
Default: system-dependent.
.It Va boot-file
Default arguments for boot when
.Va diag-switch?
is set to
.Dq Li false .
When empty, the secondary boot loader will choose the file to boot.
Default: empty string.
.It Va diag-device
Like
.Va boot-device .
Used when
.Va diag-switch?
is set to
.Dq Li true .
Default:
.Dq Li net .
.It Va diag-file
Like
.Va boot-file .
Used when
.Va diag-switch?
is set to
.Dq Li true .
Default: empty string.
.It Va diag-level
Level of diagnostics to run when
.Va diag-switch?
is set to
.Dq Li true .
Possible values are
.Dq Li max ,
.Dq Li menus ,
.Dq Li min
and
.Dq Li off
(depending on the system model).
When set to
.Dq Li off ,
the Power-On Self Test (POST) is not run.
The other values are interpreted by the POST.
Default:
.Dq Li min
or
.Dq Li max
(system-dependent).
.It Va diag-switch?
If
.Dq Li true ,
the system will boot and run in diagnostic mode.
Default:
.Dq Li false
or
.Dq Li true
(system-dependent).
.It Va env-monitor
Enables or disables the Advanced System Monitoring (ASM).
Possible values are
.Dq Li enabled
and
.Dq Li disabled .
Default:
.Dq Li enabled .
.It Va fcode-debug?
Used for debugging FCode programs.
If set to
.Dq Li true ,
names of additional FCodes are registered in the Forth dictionary.
Default:
.Dq Li false .
.It Va hardware-revision
A string describing the system hardware version.
Default: system-dependent.
.It Va input-device
One of the strings
.Dq Li keyboard ,
.Dq Li ttya ,
or
.Dq Li ttyb ,
specifying the default console input device.
Default:
.Dq Li keyboard
or
.Dq Li ttya
(system-dependent).
.It Va keyboard-click?
If set to
.Dq Li true ,
the keys click annoyingly.
Default:
.Dq Li false .
.It Va keymap
Keymap for a custom keyboard.
Default: empty string.
.It Va last-hardware-update
Similar to
.Va hardware-revision ,
describing when the hardware was last updated.
Default: system-dependent.
.It Va last-poweroff-cause
Cause of the last power-off.
Used internally by the OpenBoot PROM.
Default:
.Dq Li 0 .
.It Va load-base
Default address where client programs are loaded to.
It is unlikely that this value should ever be changed.
Default:
.Dq Li 16384 .
.It Va local-mac-address?
If set to
.Dq Li false ,
all Ethernet devices will use the system default MAC address.
If set to
.Dq Li true ,
Ethernet devices which have a unique MAC address will use it rather
than the system's default MAC address.
Default:
.Dq Li false .
.It Va mfg-mode
Manufacture test mode interpreted by the POST.
Possible values are
.Dq Li chamber
and
.Dq Li off .
Default:
.Dq Li off .
.It Va mfg-switch?
If set to
.Dq Li true ,
manufacturing tests are repeated until stopped by pressing STOP-A.
Default:
.Dq Li off .
.It Va net-timeout
If set to
.Dq Li 0 ,
the system will try to boot forever when the boot device used is a network
device.
Any non-zero value is interpreted as minutes to try a network boot.
Default:
.Dq Li 0 .
.It Va nvramrc
Contents of the NVRAMRC.
Default: empty string.
.Pp
While
.Va nvramrc
can be set using
.Nm ,
it is preferred to use
.Ic nvedit
in the boot monitor instead.
.It Va oem-banner
A string displayed at power-up, rather than the default banner.
Used when
.Va oem-banner?
is set to
.Dq Li true .
Default: system-dependent.
.It Va oem-banner?
If set to
.Dq Li true ,
the string stored in
.Va oem-banner
is displayed at power-up rather than the default banner.
Default: system-dependent.
.It Va oem-logo
A logo displayed at power-up when
.Va oem-logo?
is set to
.Dq Li true ,
rather than the default logo.
The logo has to be 512 bytes in size, containing a 64x64-bit monochrome image
in Sun Raster format without the leading 32-byte header.
Default: system-dependent.
.Pp
To set the logo with
.Nm ,
give the pathname of the file containing the image as the
.Ar value .
Using an empty
.Ar value
will remove the image.
.It Va oem-logo?
If set to
.Dq Li true ,
the logo stored in
.Va oem-logo
is displayed at power-up rather than the default logo.
.It Va output-device
One of the strings
.Dq Li screen ,
.Dq Li ttya ,
or
.Dq Li ttyb ,
specifying the default console output device.
Default:
.Dq Li screen
or
.Dq Li ttya
(system-dependent).
.It Va pcia-probe-list
Digits in the format
.Dq Li 1,2,3
specifying in which order to probe the devices on the PCI bus A.
Default: system-dependent.
.It Va pcib-probe-list
Like
.Va pcia-probe-list ,
but for PCI bus B.
Default: system-dependent.
.It Va #power-cycles
Number of power-cycles.
Automatically incremented on each power-cycle.
Default: system-dependent.
.It Va sbus-probe-list
Digits in the format
.Dq Li 0123
specifying in which order to probe the SBus slots at power-up.
Default: system-dependent.
.It Va screen-#columns
An integer specifying the screen width in characters per line.
Default:
.Dq Li 80 .
.It Va screen-#rows
An integer specifying the scren height in lines.
Default:
.Dq Li 34 .
.It Va scsi-initiator-id
The SCSI ID of SCSI controllers in the range of [0-7] or [0-f] (depending
on the controller).
A SCSI controller may or may not adhere to this setting, depending on its
FCode and device driver.
Default:
.Dq Li 7 .
.It Va security-#badlogins
Number of incorrect password attempts when
.Va security-mode
is set to
.Dq Li command
or
.Dq Li full .
Default:
.Dq Li 0 .
.It Va security-mode
Boot monitor security level.
One of the three possible values
.Dq Li full ,
.Dq Li command ,
or
.Dq Li none .
When set to
.Dq Li full ,
all boot monitor commands except for
.Ic go
require the password.
When set to
.Dq Li command ,
all boot monitor commands except for
.Ic boot
and
.Ic go
require the password.
When set to
.Dq Li none ,
no password is required.
Default:
.Dq Li none .
.Pp
When
.Nm
is used to set
.Va security-mode
to
.Dq Li full
or
.Dq Li command ,
you will be prompted for the password.
When
.Va security-mode
is set to
.Dq Li none ,
.Nm
will clear the password.
.It Va security-password
The password used when
.Va security-mode
is set to
.Dq Li full
or
.Dq Li command .
The maximum length for this password is 8 characters.
All characters exceeding this length will be ignored.
The value displayed for
.Va security-password
is always an empty string, even when a password is set.
Default: empty string.
.Pp
When
.Va security-mode
is set to
.Dq Li full
or
.Dq Li command ,
.Nm
can be used to enter a new password using any
.Ar value
for
.Va security-password
on the command line.
You will be prompted by
.Nm
to type in the new password in this case.
Trying to set
.Va security-password
when
.Va security-mode
is set to
.Dq Li none
using
.Nm
has no effect.
.It Va selftest-#megs
An integer specifying the number of megabytes of memory to test upon
power-up when
.Va diag-switch?
is set to
.Dq Li false .
Default:
.Dq Li 1 .
.It Va shutdown-temperature
Temperature at which the ASM issues an over-temperature shutdown.
Default: system-dependent.
.It Va silent-mode
If set to
.Dq Li true ,
memory test messages will not be displayed at power-up.
Default:
.Dq Li false .
.It Va sunmon-compat?
If set to
.Dq Li true ,
the old bootROM interface will be used while in the boot monitor,
rather than the OpenBoot PROM interface.
Default:
.Dq Li false .
.It Va system-board-date
Manufacturing date of the system board.
Default: system-dependent.
.It Va system-board-serial#
Serial number of the system board.
Default: system-dependent.
.It Va tpe-link-test?
Enable link test on 10baseT and 100baseTX Ethernet devices.
Default:
.Dq Li true .
.It Va ttya-mode
A string of five comma separated fields in the format
.Dq Li 9600,8,n,1,- .
The first field is the baud rate.
The second field is the number of data bits.
The third field is the parity; acceptable values for parity are
.Ql n
(none),
.Ql e
(even),
.Ql o
(odd),
.Ql m
(mark), and
.Ql s
(space).
The fourth field is the number of stop bits.
The fifth field is the
.Dq handshake
field; acceptable values are
.Ql -
(none),
.Ql h
(RTS/CTS), and
.Ql s
(Xon/Xoff).
Default:
.Dq Li 9600,8,n,1,- .
.It Va ttya-ignore-cd
If set to
.Dq Li true ,
the system will ignore carrier detect.
Default:
.Dq Li true .
.It Va ttya-rts-dtr-off
If set to
.Dq Li true ,
the system will ignore RTS/DTR.
Default:
.Dq Li false .
.It Va ttyb-mode
Like
.Va ttya-mode ,
but for ttyb.
Default:
.Dq Li 9600,8,n,1,- .
.It Va ttyb-ignore-cd
Like
.Va ttya-ignore-cd ,
but for ttyb.
Default:
.Dq Li true .
.It Va ttyb-rts-dtr-off
Like
.Va ttya-rts-dtr-off ,
but for ttyb.
Default:
.Dq Li false .
.It Va use-boot-table?
Use boot table defined by the OEM.
Default: system-dependent.
.It Va use-nvramrc?
If set to
.Dq Li true ,
the script stored in
.Va nvramrc
will be executed during start-up.
Default:
.Dq Li false .
.It Va warning-temperature
Temperature at which the ASM issues an over-temperature warning.
Default: system-dependent.
.It Va watchdog-enable
Enables or disables the system watchdog timer.
Default:
.Dq Li false .
.It Va watchdog-reboot?
If set to
.Dq Li true ,
the system will reboot upon terminal count of the system watchdog timer.
If set to
.Dq Li false ,
the system will fall into the boot monitor.
Default:
.Dq Li false .
.It Va watchdog-timeout
Expiry limit for the system watchdog timer.
Range and unit depend on the system model.
Default: system-dependent.
.El
.Sh EXAMPLES
Print all available configuration variables and their current values:
.Pp
.Dl "eeprom -a"
.Pp
Print the current value of the
.Va local-mac-address?
variable:
.Pp
.Dl "eeprom local-mac-address\e?"
.Pp
Set the value of the
.Va local-mac-address?
variable to
.Dq Li true :
.Pp
.Dl "eeprom local-mac-address\e?=true"
.Pp
Note that the
.Ql \e
in the above examples is used to keep the shell from interpreting the
.Ql \&? .
.Pp
Write an image to the
.Va oem-logo
variable:
.Pp
.Dl "eeprom oem-logo=/path/to/image.raw"
.Pp
Remove the image from the
.Va oem-logo
variable again:
.Pp
.Dl "eeprom oem-logo="
.Pp
Set the value of the
.Va security-mode
variable to
.Dq Li full ,
and set the password:
.Bd -literal -offset indent
eeprom security-mode=full
New password:
Retype new password:
.Ed
.Pp
Remember that the maximum length for the password is 8 characters.
All characters exceeding this length will be ignored.
.Pp
Set a new password when the
.Va security-mode
variable is set to
.Dq Li command
or
.Dq Li full :
.Bd -literal -offset indent
eeprom security-password=
New password:
Retype new password:
.Ed
.Sh SEE ALSO
.Xr ofwdump 8
.Sh HISTORY
The
.Nm
utility first appeared in
.Fx 5.3 .
It is inspired by the
.Nx
.Xr eeprom 8
and SunOS/Solaris
.Xr eeprom 1M
utilities.
.Sh BUGS
Currently,
.Nm
only supports systems equipped with Open Firmware and is only tested on Sun
Microsystems sun4u machines.

153
usr.sbin/eeprom/eeprom.c Normal file
View File

@ -0,0 +1,153 @@
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*
* from: NetBSD: main.c,v 1.15 2001/02/19 23:22:42 cgd Exp
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include "ofw_options.h"
static int action(char *);
static void dump_config(void);
static void usage(void);
static void
usage(void)
{
fprintf(stderr,
"usage: eeprom -a\n"
" eeprom [-] name[=value] ...\n");
exit(EX_USAGE);
}
int
main(int argc, char *argv[])
{
int do_stdin, opt;
int aflag, rv;
char *cp;
char line[BUFSIZ];
aflag = do_stdin = 0;
rv = EX_OK;
while ((opt = getopt(argc, argv, "-a")) != -1) {
switch (opt) {
case '-':
if (aflag)
usage();
do_stdin = 1;
break;
case 'a':
if (do_stdin)
usage();
aflag = 1;
break;
case '?':
default:
usage();
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if (aflag) {
if (argc != 0)
usage();
dump_config();
} else {
if (do_stdin) {
while (fgets(line, BUFSIZ, stdin) != NULL &&
rv == EX_OK) {
if (line[0] == '\n')
continue;
if ((cp = strrchr(line, '\n')) != NULL)
*cp = '\0';
rv = action(line);
}
if (ferror(stdin))
err(EX_NOINPUT, "stdin");
} else {
if (argc == 0)
usage();
while (argc && rv == EX_OK) {
rv = action(*argv);
++argv;
--argc;
}
}
}
return (rv);
}
static int
action(char *line)
{
int rv;
char *keyword, *arg;
keyword = strdup(line);
if (keyword == NULL)
err(EX_OSERR, "malloc() failed");
if ((arg = strrchr(keyword, '=')) != NULL)
*arg++ = '\0';
switch (rv = ofwo_action(keyword, arg)) {
case EX_UNAVAILABLE:
warnx("nothing available for '%s'.", keyword);
break;
case EX_DATAERR:
warnx("invalid value '%s' for '%s'.", arg, keyword);
break;
}
free(keyword);
return(rv);
}
static void
dump_config()
{
ofwo_dump();
}

View File

@ -0,0 +1,314 @@
/*-
* Copyright (c) 2004 Marius Strobl
* 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 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* Handlers for Open Firmware /options node.
*/
#include <sys/types.h>
#include <dev/ofw/openfirm.h>
#include <err.h>
#include <fcntl.h>
#include <readpassphrase.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include "ofw_options.h"
#include "ofw_util.h"
#define OFWO_LOGO 512
#define OFWO_MAXPROP 31
#define OFWO_MAXPWD 8
struct ofwo_extabent {
const char *ex_prop;
int (*ex_handler)(struct ofwo_extabent *, int, const void *,
int, const char *);
};
static int ofwo_oemlogo(struct ofwo_extabent *, int, const void *, int,
const char *);
static int ofwo_secmode(struct ofwo_extabent *, int, const void *, int,
const char *);
static int ofwo_secpwd(struct ofwo_extabent *, int, const void *, int,
const char *);
static struct ofwo_extabent ofwo_extab[] = {
{ "oem-logo", ofwo_oemlogo },
{ "security-mode", ofwo_secmode },
{ "security-password", ofwo_secpwd },
{ NULL, NULL }
};
static int ofwo_setpass(int);
static __inline void ofwo_printprop(const char *, const char*, int);
static int ofwo_setstr(int, const void *, int, const char *,
const char *);
static int
ofwo_oemlogo(struct ofwo_extabent *exent, int fd, const void *buf, int buflen,
const char *val)
{
int lfd;
char logo[OFWO_LOGO + 1];
if (val) {
if (val[0] == '\0')
ofw_setprop(fd, ofw_optnode(fd), exent->ex_prop, "", 1);
else {
if ((lfd = open(val, O_RDONLY)) == -1) {
warn("could not open '%s'", val);
return (EX_USAGE);
}
if (read(lfd, logo, OFWO_LOGO) != OFWO_LOGO ||
lseek(lfd, 0, SEEK_END) != OFWO_LOGO) {
close(lfd);
warnx("logo '%s' has wrong size.", val);
return (EX_USAGE);
}
close(lfd);
logo[OFWO_LOGO] = '\0';
if (ofw_setprop(fd, ofw_optnode(fd), exent->ex_prop,
logo, OFWO_LOGO + 1) != OFWO_LOGO)
errx(EX_IOERR, "writing logo failed.");
}
} else
if (buflen != 0)
printf("%s: <logo data>\n", exent->ex_prop);
else
ofwo_printprop(exent->ex_prop, (const char *)buf,
buflen);
return (EX_OK);
}
static int
ofwo_secmode(struct ofwo_extabent *exent, int fd, const void *buf, int buflen,
const char *val)
{
int res;
if (val) {
if (strcmp(val, "full") == 0 || strcmp(val, "command") == 0) {
if ((res = ofwo_setpass(fd)) != EX_OK)
return (res);
if ((res = ofwo_setstr(fd, buf, buflen, exent->ex_prop,
val)) != EX_OK)
ofw_setprop(fd, ofw_optnode(fd),
"security-password", "", 1);
return (res);
}
if (strcmp(val, "none") == 0) {
ofw_setprop(fd, ofw_optnode(fd), "security-password",
"", 1);
return (ofwo_setstr(fd, buf, buflen, exent->ex_prop,
val));
}
return (EX_DATAERR);
} else
ofwo_printprop(exent->ex_prop, (const char *)buf, buflen);
return (EX_OK);
}
static int
ofwo_secpwd(struct ofwo_extabent *exent, int fd __unused,
const void *buf __unused, __unused int buflen, const char *val)
{
void *pbuf;
int len, pblen, rv;
pblen = 0;
rv = EX_OK;
pbuf = NULL;
if (val) {
len = ofw_getprop_alloc(fd, ofw_optnode(fd), "security-mode",
&pbuf, &pblen, 1);
if (len <= 0 || strncmp("none", (char *)pbuf, len) == 0) {
rv = EX_CONFIG;
warnx("no security mode set.");
} else if (strncmp("command", (char *)pbuf, len) == 0 ||
strncmp("full", (char *)pbuf, len) == 0) {
rv = ofwo_setpass(fd);
} else {
rv = EX_CONFIG;
warnx("invalid security mode.");
}
} else
ofwo_printprop(exent->ex_prop, (const char *)buf, buflen);
if (pbuf != NULL)
free(pbuf);
return (rv);
}
static int
ofwo_setpass(int fd)
{
char pwd1[OFWO_MAXPWD + 1], pwd2[OFWO_MAXPWD + 1];
if (readpassphrase("New password:", pwd1, sizeof(pwd1),
RPP_ECHO_OFF | RPP_REQUIRE_TTY) == NULL ||
readpassphrase("Retype new password:", pwd2, sizeof(pwd2),
RPP_ECHO_OFF | RPP_REQUIRE_TTY) == NULL)
errx(EX_USAGE, "failed to get password.");
if (strlen(pwd1) == 0) {
printf("Password unchanged.\n");
return (EX_OK);
}
if (strcmp(pwd1, pwd2) != 0) {
printf("Mismatch - password unchanged.\n");
return (EX_USAGE);
}
ofw_setprop(fd, ofw_optnode(fd), "security-password", pwd1,
strlen(pwd1) + 1);
return (EX_OK);
}
static void
ofwo_printprop(const char *prop, const char* buf, int buflen)
{
printf("%s: %.*s\n", prop, buflen, buf);
}
static int
ofwo_setstr(int fd, const void *buf, int buflen, const char *prop,
const char *val)
{
void *pbuf;
int len, pblen, rv;
phandle_t optnode;
char *oval;
pblen = 0;
rv = EX_OK;
pbuf = NULL;
optnode = ofw_optnode(fd);
ofw_setprop(fd, optnode, prop, val, strlen(val) + 1);
len = ofw_getprop_alloc(fd, optnode, prop, &pbuf, &pblen, 1);
if (len < 0 || strncmp(val, (char *)pbuf, len) != 0) {
/*
* The value is too long for this property and the OFW has
* truncated it to fit or the value is illegal and a legal
* one has been written instead (e.g. attempted to write
* "foobar" to a "true"/"false"-property) - try to recover
* the old value.
*/
rv = EX_DATAERR;
if ((oval = malloc(buflen + 1)) == NULL)
err(EX_OSERR, "malloc() failed.");
strncpy(oval, buf, buflen);
oval[buflen] = '\0';
len = ofw_setprop(fd, optnode, prop, oval, buflen + 1);
if (len != buflen)
errx(EX_IOERR, "recovery of old value failed.");
free(oval);
goto out;
}
printf("%s: %.*s%s->%s%.*s\n", prop, buflen, (const char *)buf,
buflen > 0 ? " " : "", len > 0 ? " " : "", len, (char *)pbuf);
out:
if (pbuf != NULL)
free(pbuf);
return (rv);
}
void
ofwo_dump(void)
{
void *pbuf;
int fd, len, nlen, pblen;
phandle_t optnode;
char prop[OFWO_MAXPROP + 1];
struct ofwo_extabent *ex;
pblen = 0;
pbuf = NULL;
fd = ofw_open(O_RDONLY);
optnode = ofw_optnode(fd);
for (nlen = ofw_firstprop(fd, optnode, prop, sizeof(prop)); nlen != 0;
nlen = ofw_nextprop(fd, optnode, prop, prop, sizeof(prop))) {
len = ofw_getprop_alloc(fd, optnode, prop, &pbuf, &pblen, 1);
if (len < 0)
continue;
if (strcmp(prop, "name") == 0)
continue;
for (ex = ofwo_extab; ex->ex_prop != NULL; ++ex)
if (strcmp(ex->ex_prop, prop) == 0)
break;
if (ex->ex_prop != NULL)
(*ex->ex_handler)(ex, fd, pbuf, len, NULL);
else
ofwo_printprop(prop, (char *)pbuf, len);
}
if (pbuf != NULL)
free(pbuf);
ofw_close(fd);
}
int
ofwo_action(const char *prop, const char *val)
{
void *pbuf;
int fd, len, pblen, rv;
phandle_t optnode;
struct ofwo_extabent *ex;
pblen = 0;
rv = EX_OK;
pbuf = NULL;
if (strcmp(prop, "name") == 0)
return (EX_UNAVAILABLE);
if (val)
fd = ofw_open(O_RDWR);
else
fd = ofw_open(O_RDONLY);
optnode = ofw_optnode(fd);
len = ofw_getprop_alloc(fd, optnode, prop, &pbuf, &pblen, 1);
if (len < 0) {
rv = EX_UNAVAILABLE;
goto out;
}
for (ex = ofwo_extab; ex->ex_prop != NULL; ++ex)
if (strcmp(ex->ex_prop, prop) == 0)
break;
if (ex->ex_prop != NULL)
rv = (*ex->ex_handler)(ex, fd, pbuf, len, val);
else if (val)
rv = ofwo_setstr(fd, pbuf, len, prop, val);
else
ofwo_printprop(prop, (char *)pbuf, len);
out:
if (pbuf != NULL)
free(pbuf);
ofw_close(fd);
return (rv);
}

View File

@ -0,0 +1,34 @@
/*-
* Copyright (c) 2004 Marius Strobl
* 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 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$
*/
#ifndef OFW_OPTIONS_H
#define OFW_OPTIONS_H
void ofwo_dump(void);
int ofwo_action(const char *prop, const char *val);
#endif /* OFW_OPTIONS_H */