1 /* $OpenBSD: main.c,v 1.10 2002/12/08 16:50:07 millert 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 <string.h> 43 #include <stdio.h> 44 #include <unistd.h> 45 46 #ifdef __sparc__ 47 #include <fcntl.h> 48 #include <limits.h> 49 #include <sys/sysctl.h> 50 #include <machine/cpu.h> 51 52 #include <machine/openpromio.h> 53 54 static char *system = NULL; 55 #endif /* __sparc__ */ 56 57 #include <machine/eeprom.h> 58 59 #include "defs.h" 60 61 struct keytabent eekeytab[] = { 62 { "hwupdate", 0x10, ee_hwupdate }, 63 { "memsize", 0x14, ee_num8 }, 64 { "memtest", 0x15, ee_num8 }, 65 #ifdef __sparc64__ 66 { "scrsize", 0x16, ee_notsupp }, 67 #else 68 { "scrsize", 0x16, ee_screensize }, 69 #endif 70 { "watchdog_reboot", 0x17, ee_truefalse }, 71 { "default_boot", 0x18, ee_truefalse }, 72 { "bootdev", 0x19, ee_bootdev }, 73 { "kbdtype", 0x1e, ee_kbdtype }, 74 #ifdef __sparc64__ 75 { "console", 0x1f, ee_notsupp }, 76 #else 77 { "console", 0x1f, ee_constype }, 78 #endif 79 { "keyclick", 0x21, ee_truefalse }, 80 { "diagdev", 0x22, ee_bootdev }, 81 { "diagpath", 0x28, ee_diagpath }, 82 { "columns", 0x50, ee_num8 }, 83 { "rows", 0x51, ee_num8 }, 84 { "ttya_use_baud", 0x58, ee_truefalse }, 85 { "ttya_baud", 0x59, ee_num16 }, 86 { "ttya_no_rtsdtr", 0x5b, ee_truefalse }, 87 { "ttyb_use_baud", 0x60, ee_truefalse }, 88 { "ttyb_baud", 0x61, ee_num16 }, 89 { "ttyb_no_rtsdtr", 0x63, ee_truefalse }, 90 { "banner", 0x68, ee_banner }, 91 { "secure", 0, ee_notsupp }, 92 { "bad_login", 0, ee_notsupp }, 93 { "password", 0, ee_notsupp }, 94 { NULL, 0, ee_notsupp }, 95 }; 96 97 static void action(char *); 98 static void dump_prom(void); 99 static void usage(void); 100 #ifdef __sparc__ 101 static int getcputype(void); 102 #endif /* __sparc__ */ 103 104 char *path_eeprom = "/dev/eeprom"; 105 char *path_openprom = "/dev/openprom"; 106 int fix_checksum = 0; 107 int ignore_checksum = 0; 108 int update_checksums = 0; 109 int cksumfail = 0; 110 u_short writecount; 111 int eval = 0; 112 int use_openprom = 0; 113 int verbose = 0; 114 115 extern char *__progname; 116 117 int 118 main(argc, argv) 119 int argc; 120 char **argv; 121 { 122 int ch, do_stdin = 0; 123 char *cp, line[BUFSIZE]; 124 #ifdef __sparc__ 125 char *optstring = "cf:ivN:-"; 126 #else 127 char *optstring = "cf:i-"; 128 #endif /* __sparc__ */ 129 130 while ((ch = getopt(argc, argv, optstring)) != -1) 131 switch (ch) { 132 case '-': 133 do_stdin = 1; 134 break; 135 136 case 'c': 137 fix_checksum = 1; 138 break; 139 140 case 'f': 141 path_eeprom = path_openprom = optarg; 142 break; 143 144 case 'i': 145 ignore_checksum = 1; 146 break; 147 #ifdef __sparc__ 148 case 'v': 149 verbose = 1; 150 break; 151 152 case 'N': 153 system = optarg; 154 break; 155 156 #endif /* __sparc__ */ 157 158 case '?': 159 default: 160 usage(); 161 } 162 argc -= optind; 163 argv += optind; 164 165 #ifdef __sparc__ 166 if (system != NULL) { 167 setegid(getgid()); 168 setgid(getgid()); 169 } 170 if (getcputype() != CPU_SUN4) 171 use_openprom = 1; 172 #endif /* __sparc__ */ 173 174 if (use_openprom == 0) { 175 ee_verifychecksums(); 176 if (fix_checksum || cksumfail) 177 exit(cksumfail); 178 } 179 180 if (do_stdin) { 181 while (fgets(line, BUFSIZE, stdin) != NULL) { 182 if (line[0] == '\n') 183 continue; 184 if ((cp = strrchr(line, '\n')) != NULL) 185 *cp = '\0'; 186 action(line); 187 } 188 if (ferror(stdin)) 189 err(++eval, "stdin"); 190 } else { 191 if (argc == 0) { 192 dump_prom(); 193 exit(eval + cksumfail); 194 } 195 196 while (argc) { 197 action(*argv); 198 ++argv; 199 --argc; 200 } 201 } 202 203 if (use_openprom == 0) 204 if (update_checksums) { 205 ++writecount; 206 ee_updatechecksums(); 207 } 208 209 exit(eval + cksumfail); 210 } 211 212 #ifdef __sparc__ 213 static int 214 getcputype() 215 { 216 int mib[2]; 217 size_t len; 218 int cputype; 219 220 mib[0] = CTL_MACHDEP; 221 mib[1] = CPU_CPUTYPE; 222 len = sizeof(cputype); 223 if (sysctl(mib, 2, &cputype, &len, NULL, 0) < 0) 224 err(1, "sysctl(machdep.cputype)"); 225 226 return (cputype); 227 } 228 #endif /* __sparc__ */ 229 230 /* 231 * Separate the keyword from the argument (if any), find the keyword in 232 * the table, and call the corresponding handler function. 233 */ 234 static void 235 action(line) 236 char *line; 237 { 238 char *keyword, *arg, *cp; 239 struct keytabent *ktent; 240 241 keyword = strdup(line); 242 if ((arg = strrchr(keyword, '=')) != NULL) 243 *arg++ = '\0'; 244 245 #ifdef __sparc__ 246 if (use_openprom) { 247 /* 248 * The whole point of the Openprom is that one 249 * isn't required to know the keywords. With this 250 * in mind, we just dump the whole thing off to 251 * the generic op_handler. 252 */ 253 if ((cp = op_handler(keyword, arg)) != NULL) 254 warnx("%s", cp); 255 return; 256 } else 257 #endif /* __sparc__ */ 258 for (ktent = eekeytab; ktent->kt_keyword != NULL; ++ktent) { 259 if (strcmp(ktent->kt_keyword, keyword) == 0) { 260 (*ktent->kt_handler)(ktent, arg); 261 return; 262 } 263 } 264 265 warnx("unknown keyword %s", keyword); 266 ++eval; 267 } 268 269 /* 270 * Dump the contents of the prom corresponding to all known keywords. 271 */ 272 static void 273 dump_prom() 274 { 275 struct keytabent *ktent; 276 277 #ifdef __sparc__ 278 if (use_openprom) { 279 /* 280 * We have a special dump routine for this. 281 */ 282 op_dump(); 283 } else 284 #endif /* __sparc__ */ 285 for (ktent = eekeytab; ktent->kt_keyword != NULL; ++ktent) 286 (*ktent->kt_handler)(ktent, NULL); 287 } 288 289 static void 290 usage() 291 { 292 293 #ifdef __sparc__ 294 fprintf(stderr, "usage: %s %s %s\n", __progname, 295 "[-] [-c] [-f device] [-i] [-v]", 296 "[-N system] [field[=value] ...]"); 297 #else 298 fprintf(stderr, "usage: %s %s\n", __progname, 299 "[-] [-c] [-f device] [-i] [field[=value] ...]"); 300 #endif /* __sparc__ */ 301 exit(1); 302 } 303