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