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