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