1 /* $OpenBSD: main.c,v 1.13 2005/05/02 02:29:27 djm Exp $ */
2 /* $NetBSD: main.c,v 1.3 1996/05/16 16:00:55 thorpej Exp $ */
3
4 /*-
5 * Copyright (c) 1996 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jason R. Thorpe.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #include <sys/param.h>
41 #include <err.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <unistd.h>
46
47 #ifdef __sparc__
48 #include <fcntl.h>
49 #include <limits.h>
50 #include <sys/sysctl.h>
51 #include <machine/cpu.h>
52
53 #include <machine/openpromio.h>
54
55 static char *sysimg = NULL;
56 #endif /* __sparc__ */
57
58 #include <machine/eeprom.h>
59
60 #include "defs.h"
61
62 __RCSID("$MirOS: src/usr.sbin/eeprom/main.c,v 1.3 2008/10/17 01:39:55 tg Exp $");
63
64 struct keytabent eekeytab[] = {
65 { "hwupdate", 0x10, ee_hwupdate },
66 { "memsize", 0x14, ee_num8 },
67 { "memtest", 0x15, ee_num8 },
68 #ifdef __sparc64__
69 { "scrsize", 0x16, ee_notsupp },
70 #else
71 { "scrsize", 0x16, ee_screensize },
72 #endif
73 { "watchdog_reboot", 0x17, ee_truefalse },
74 { "default_boot", 0x18, ee_truefalse },
75 { "bootdev", 0x19, ee_bootdev },
76 { "kbdtype", 0x1e, ee_kbdtype },
77 #ifdef __sparc64__
78 { "console", 0x1f, ee_notsupp },
79 #else
80 { "console", 0x1f, ee_constype },
81 #endif
82 { "keyclick", 0x21, ee_truefalse },
83 { "diagdev", 0x22, ee_bootdev },
84 { "diagpath", 0x28, ee_diagpath },
85 { "columns", 0x50, ee_num8 },
86 { "rows", 0x51, ee_num8 },
87 { "ttya_use_baud", 0x58, ee_truefalse },
88 { "ttya_baud", 0x59, ee_num16 },
89 { "ttya_no_rtsdtr", 0x5b, ee_truefalse },
90 { "ttyb_use_baud", 0x60, ee_truefalse },
91 { "ttyb_baud", 0x61, ee_num16 },
92 { "ttyb_no_rtsdtr", 0x63, ee_truefalse },
93 { "banner", 0x68, ee_banner },
94 { "secure", 0, ee_notsupp },
95 { "bad_login", 0, ee_notsupp },
96 { "password", 0, ee_notsupp },
97 { NULL, 0, ee_notsupp },
98 };
99
100 static void action(char *);
101 static void dump_prom(void);
102 static void usage(void);
103 #ifdef __sparc__
104 static int getcputype(void);
105 #endif /* __sparc__ */
106
107 char *path_eeprom = "/dev/eeprom";
108 char *path_openprom = "/dev/openprom";
109 int fix_checksum = 0;
110 int ignore_checksum = 0;
111 int update_checksums = 0;
112 int cksumfail = 0;
113 u_short writecount;
114 int eval = 0;
115 int use_openprom = 0;
116 int verbose = 0;
117
118 extern char *__progname;
119
120 int
main(int argc,char * argv[])121 main(int argc, char *argv[])
122 {
123 int ch, do_stdin = 0;
124 char *cp, line[BUFSIZE];
125 #ifdef __sparc__
126 gid_t gid;
127 char *optstring = "cf:ivN:-";
128 #else
129 char *optstring = "cf:i-";
130 #endif /* __sparc__ */
131
132 while ((ch = getopt(argc, argv, optstring)) != -1)
133 switch (ch) {
134 case '-':
135 do_stdin = 1;
136 break;
137
138 case 'c':
139 fix_checksum = 1;
140 break;
141
142 case 'f':
143 path_eeprom = path_openprom = optarg;
144 break;
145
146 case 'i':
147 ignore_checksum = 1;
148 break;
149 #ifdef __sparc__
150 case 'v':
151 verbose = 1;
152 break;
153
154 case 'N':
155 sysimg = optarg;
156 break;
157
158 #endif /* __sparc__ */
159
160 case '?':
161 default:
162 usage();
163 }
164 argc -= optind;
165 argv += optind;
166
167 #ifdef __sparc__
168 if (sysimg != NULL) {
169 gid = getgid();
170 if (setresgid(gid, gid, gid) == -1)
171 err(1, "setresgid");
172 }
173 if (getcputype() != CPU_SUN4)
174 use_openprom = 1;
175 #endif /* __sparc__ */
176
177 if (use_openprom == 0) {
178 ee_verifychecksums();
179 if (fix_checksum || cksumfail)
180 exit(cksumfail);
181 }
182
183 if (do_stdin) {
184 while (fgets(line, BUFSIZE, stdin) != NULL) {
185 if (line[0] == '\n')
186 continue;
187 if ((cp = strrchr(line, '\n')) != NULL)
188 *cp = '\0';
189 action(line);
190 }
191 if (ferror(stdin))
192 err(++eval, "stdin");
193 } else {
194 if (argc == 0) {
195 dump_prom();
196 exit(eval + cksumfail);
197 }
198
199 while (argc) {
200 action(*argv);
201 ++argv;
202 --argc;
203 }
204 }
205
206 if (use_openprom == 0)
207 if (update_checksums) {
208 ++writecount;
209 ee_updatechecksums();
210 }
211
212 exit(eval + cksumfail);
213 }
214
215 #ifdef __sparc__
216 static int
getcputype(void)217 getcputype(void)
218 {
219 int mib[2];
220 size_t len;
221 int cputype;
222
223 mib[0] = CTL_MACHDEP;
224 mib[1] = CPU_CPUTYPE;
225 len = sizeof(cputype);
226 if (sysctl(mib, 2, &cputype, &len, NULL, 0) < 0)
227 err(1, "sysctl(machdep.cputype)");
228
229 return (cputype);
230 }
231 #endif /* __sparc__ */
232
233 /*
234 * Separate the keyword from the argument (if any), find the keyword in
235 * the table, and call the corresponding handler function.
236 */
237 static void
action(char * line)238 action(char *line)
239 {
240 char *keyword, *arg, *cp;
241 struct keytabent *ktent;
242
243 keyword = strdup(line);
244 if (!keyword)
245 errx(1, "out of memory");
246 if ((arg = strrchr(keyword, '=')) != NULL)
247 *arg++ = '\0';
248
249 #ifdef __sparc__
250 if (use_openprom) {
251 /*
252 * The whole point of the Openprom is that one
253 * isn't required to know the keywords. With this
254 * in mind, we just dump the whole thing off to
255 * the generic op_handler.
256 */
257 if ((cp = op_handler(keyword, arg)) != NULL)
258 warnx("%s", cp);
259 return;
260 } else
261 #endif /* __sparc__ */
262 for (ktent = eekeytab; ktent->kt_keyword != NULL; ++ktent) {
263 if (strcmp(ktent->kt_keyword, keyword) == 0) {
264 (*ktent->kt_handler)(ktent, arg);
265 return;
266 }
267 }
268
269 warnx("unknown keyword %s", keyword);
270 ++eval;
271 }
272
273 /*
274 * Dump the contents of the prom corresponding to all known keywords.
275 */
276 static void
dump_prom(void)277 dump_prom(void)
278 {
279 struct keytabent *ktent;
280
281 #ifdef __sparc__
282 if (use_openprom) {
283 /*
284 * We have a special dump routine for this.
285 */
286 op_dump();
287 } else
288 #endif /* __sparc__ */
289 for (ktent = eekeytab; ktent->kt_keyword != NULL; ++ktent)
290 (*ktent->kt_handler)(ktent, NULL);
291 }
292
293 static void
usage(void)294 usage(void)
295 {
296
297 #ifdef __sparc__
298 fprintf(stderr, "usage: %s %s %s\n", __progname,
299 "[-] [-c] [-f device] [-i] [-v]",
300 "[-N system] [field[=value] ...]");
301 #else
302 fprintf(stderr, "usage: %s %s\n", __progname,
303 "[-] [-c] [-f device] [-i] [field[=value] ...]");
304 #endif /* __sparc__ */
305 exit(1);
306 }
307