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