1 /* $OpenBSD: main.c,v 1.19 2014/07/24 19:19:26 miod 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 <sys/param.h> 34 #include <err.h> 35 #include <string.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <unistd.h> 39 40 #if defined(__sparc__) && !defined(__sparc64__) 41 #include <fcntl.h> 42 #include <limits.h> 43 #include <sys/sysctl.h> 44 #include <machine/cpu.h> 45 #include <machine/eeprom.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 gid_t gid; 115 char *optstring = "cf:ipvN:-"; 116 117 while ((ch = getopt(argc, argv, optstring)) != -1) 118 switch (ch) { 119 case '-': 120 do_stdin = 1; 121 break; 122 123 case 'c': 124 fix_checksum = 1; 125 break; 126 127 case 'f': 128 path_eeprom = path_openprom = optarg; 129 break; 130 131 case 'i': 132 ignore_checksum = 1; 133 break; 134 135 case 'p': 136 print_tree = 1; 137 break; 138 139 case 'v': 140 verbose = 1; 141 break; 142 143 #if defined(__sparc__) && !defined(__sparc64__) 144 case 'N': 145 nlistf = optarg; 146 break; 147 #endif /* __sparc__ && !__sparc64__ */ 148 149 case '?': 150 default: 151 usage(); 152 } 153 argc -= optind; 154 argv += optind; 155 156 #if defined(__sparc__) && !defined(__sparc64__) 157 if (nlistf != NULL) { 158 gid = getgid(); 159 if (setresgid(gid, gid, gid) == -1) 160 err(1, "setresgid"); 161 } 162 if (getcputype() != CPU_SUN4) 163 #endif /* __sparc__ && !__sparc64__ */ 164 use_openprom = 1; 165 if (print_tree && use_openprom) { 166 op_tree(); 167 exit(0); 168 } 169 170 #if defined(__sparc__) && !defined(__sparc64__) 171 if (use_openprom == 0) { 172 ee_verifychecksums(); 173 if (fix_checksum || cksumfail) 174 exit(cksumfail); 175 } 176 #endif /* __sparc__ && !__sparc64__ */ 177 178 if (do_stdin) { 179 while (fgets(line, BUFSIZE, stdin) != NULL) { 180 if (line[0] == '\n') 181 continue; 182 if ((cp = strrchr(line, '\n')) != NULL) 183 *cp = '\0'; 184 action(line); 185 } 186 if (ferror(stdin)) 187 err(++eval, "stdin"); 188 } else { 189 if (argc == 0) { 190 dump_prom(); 191 exit(eval + cksumfail); 192 } 193 194 while (argc) { 195 action(*argv); 196 ++argv; 197 --argc; 198 } 199 } 200 201 #if defined(__sparc__) && !defined(__sparc64__) 202 if (use_openprom == 0) 203 if (update_checksums) { 204 ++writecount; 205 ee_updatechecksums(); 206 } 207 #endif /* __sparc__ && !__sparc64__ */ 208 209 exit(eval + cksumfail); 210 } 211 212 #if defined(__sparc__) && !defined(__sparc64__) 213 static int 214 getcputype(void) 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__ && !__sparc64__ */ 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(char *line) 236 { 237 char *keyword, *arg, *cp; 238 struct keytabent *ktent; 239 240 keyword = strdup(line); 241 if (!keyword) 242 errx(1, "out of memory"); 243 if ((arg = strrchr(keyword, '=')) != NULL) 244 *arg++ = '\0'; 245 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 } 257 #if defined(__sparc__) && !defined(__sparc64__) 258 else 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 #endif /* __sparc__ && !__sparc64__ */ 266 267 warnx("unknown keyword %s", keyword); 268 ++eval; 269 } 270 271 /* 272 * Dump the contents of the prom corresponding to all known keywords. 273 */ 274 static void 275 dump_prom(void) 276 { 277 struct keytabent *ktent; 278 279 if (use_openprom) { 280 /* 281 * We have a special dump routine for this. 282 */ 283 op_dump(); 284 } 285 #if defined(__sparc__) && !defined(__sparc64__) 286 else 287 for (ktent = eekeytab; ktent->kt_keyword != NULL; ++ktent) 288 (*ktent->kt_handler)(ktent, NULL); 289 #endif /* __sparc__ && !__sparc64__ */ 290 } 291 292 static void 293 usage(void) 294 { 295 296 #if defined(__sparc__) && !defined(__sparc64__) 297 fprintf(stderr, 298 "usage: %s [-cipv] [-f device] [-N system] [field[=value] ...]\n", 299 __progname); 300 #else 301 fprintf(stderr, 302 "usage: %s [-cipv] [-f device] [field[=value] ...]\n", 303 __progname); 304 #endif /* __sparc__ && !__sparc64__ */ 305 exit(1); 306 } 307