Home | History | Annotate | Line # | Download | only in bootpref
bootpref.c revision 1.2
      1 /*	$NetBSD: bootpref.c,v 1.2 1998/06/17 11:45:12 leo Exp $	*/
      2 /*-
      3  * Copyright (c) 1998 The NetBSD Foundation, Inc.
      4  * All rights reserved.
      5  *
      6  * This code is derived from software contributed to The NetBSD Foundation
      7  * by Julian Coleman.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *        This product includes software developed by the NetBSD
     20  *        Foundation, Inc. and its contributors.
     21  * 4. Neither the name of The NetBSD Foundation nor the names of its
     22  *    contributors may be used to endorse or promote products derived
     23  *    from this software without specific prior written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     26  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 #include <sys/types.h>
     38 #include <unistd.h>
     39 #include <string.h>
     40 #include <stdlib.h>
     41 #include <stdio.h>
     42 #include <fcntl.h>
     43 #include <errno.h>
     44 #include <err.h>
     45 #include <sys/mman.h>
     46 #include "bootpref.h"
     47 
     48 static void	usage __P ((void));
     49 static int	openNVRAM __P ((void));
     50 static void	closeNVRAM __P ((int));
     51 static u_char	readNVRAM __P ((int, int));
     52 static void	writeNVRAM __P ((int, int, u_char));
     53 static void	getNVpref __P ((int, u_char[]));
     54 static void	setNVpref __P ((int, u_char[], int, int));
     55 static void	showOS __P ((u_char));
     56 static void	showLang __P ((u_char));
     57 static void	showKbdLang __P ((u_char));
     58 static void	showDateFmt __P ((u_char));
     59 static void	showDateSep __P ((u_char));
     60 static void	showVideo2 __P ((u_char));
     61 static void	showVideo1 __P ((u_char, u_char));
     62 static int	checkOS __P ((u_char *, char *));
     63 static int	checkLang __P ((u_char *, char *));
     64 static int	checkKbdLang __P ((u_char *, char *));
     65 static int	checkInt __P ((u_char *, char *, int, int));
     66 static int 	checkDateFmt __P ((u_char *, char *));
     67 static void 	checkDateSep __P ((u_char *, char *));
     68 static int 	checkColours __P ((u_char *, char *));
     69 
     70 #define SET_OS		0x001
     71 #define SET_LANG	0x002
     72 #define SET_KBDLANG	0x004
     73 #define SET_HOSTID	0x008
     74 #define SET_DATIME	0x010
     75 #define SET_DATESEP	0x020
     76 #define SET_BOOTDLY	0x040
     77 #define SET_VID1	0x080
     78 #define SET_VID2	0x100
     79 
     80 #define ARRAY_OS	0
     81 #define ARRAY_LANG	1
     82 #define ARRAY_KBDLANG	2
     83 #define ARRAY_HOSTID	3
     84 #define ARRAY_DATIME	4
     85 #define ARRAY_DATESEP	5
     86 #define ARRAY_BOOTDLY	6
     87 #define ARRAY_VID1	7
     88 #define ARRAY_VID2	8
     89 
     90 static const char	nvrdev[] = PATH_NVRAM;
     91 
     92 int
     93 main (argc, argv)
     94 	int	argc;
     95 	char	*argv[];
     96 {
     97 	int	c, set = 0, verbose = 0;
     98 	int	fd;
     99 	u_char	bootpref[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
    100 	u_char	check_hour = 0, check_video1 = 0, check_video2 = 0;
    101 
    102 	fd = openNVRAM ();
    103 	bootpref[ARRAY_VID2] = readNVRAM (fd, NVRAM_VID2);
    104 	bootpref[ARRAY_VID1] = readNVRAM (fd, NVRAM_VID1);
    105 	/* parse options */
    106 	while ((c = getopt (argc, argv, "Vb:d:k:l:s:f:12e:c:nptv48oOxXiI")) != -1) {
    107 		switch (c) {
    108 		case 'V':
    109 			verbose = 1;
    110 			break;
    111 		case 'b':
    112 			if (checkOS (&bootpref[ARRAY_OS], optarg))
    113 				set |= SET_OS;
    114 			else
    115 				usage ();
    116 			break;
    117 		case 'd':
    118 			if (checkInt (&bootpref[ARRAY_BOOTDLY], optarg,
    119 			   0, 255))
    120 				set |= SET_BOOTDLY;
    121 			else
    122 				usage ();
    123 			break;
    124 		case 'k':
    125 			if (checkKbdLang (&bootpref[ARRAY_KBDLANG], optarg))
    126 				set |= SET_KBDLANG;
    127 			else
    128 				usage ();
    129 			break;
    130 		case 'l':
    131 			if (checkLang (&bootpref[ARRAY_LANG], optarg))
    132 				set |= SET_LANG;
    133 			else
    134 				usage ();
    135 			break;
    136 		case 's':
    137 			if (checkInt (&bootpref[ARRAY_HOSTID], optarg,
    138 			    0, 7))
    139 				set |= SET_HOSTID;
    140 			else
    141 				usage ();
    142 			break;
    143 		case 'f':
    144 			if (checkDateFmt (&bootpref[ARRAY_DATIME], optarg))
    145 				set |= SET_DATIME;
    146 			else
    147 				usage ();
    148 			break;
    149 		case '1':
    150 			if (check_hour & DATIME_24H) {
    151 				usage();
    152 			} else {
    153 				bootpref[ARRAY_DATIME] &= ~DATIME_24H;
    154 				set |= SET_DATIME;
    155 				check_hour |= DATIME_24H;
    156 			}
    157 			break;
    158 		case '2':
    159 			if (check_hour & DATIME_24H) {
    160 				usage();
    161 			} else {
    162 				bootpref[ARRAY_DATIME] |= DATIME_24H;
    163 				set |= SET_DATIME;
    164 				check_hour |= DATIME_24H;
    165 			}
    166 			break;
    167 		case 'e':
    168 			checkDateSep (&bootpref[ARRAY_DATESEP], optarg);
    169 			set |= SET_DATESEP;
    170 			break;
    171 		case 'c':
    172 			if (checkColours (&bootpref[ARRAY_VID2], optarg))
    173 				set |= SET_VID2;
    174 			else
    175 				usage ();
    176 			break;
    177 		case 'n':
    178 			if (check_video2 & VID2_PAL) {
    179 				usage();
    180 			} else {
    181 				bootpref[ARRAY_VID2] &= ~VID2_PAL;
    182 				set |= SET_VID2;
    183 				check_video2 |= VID2_PAL;
    184 			}
    185 			break;
    186 		case 'p':
    187 			if (check_video2 & VID2_PAL) {
    188 				usage();
    189 			} else {
    190 				bootpref[ARRAY_VID2] |= VID2_PAL;
    191 				set |= SET_VID2;
    192 				check_video2 |= VID2_PAL;
    193 			}
    194 			break;
    195 		case 't':
    196 			if (check_video2 & VID2_VGA) {
    197 				usage();
    198 			} else {
    199 				bootpref[ARRAY_VID2] &= ~VID2_VGA;
    200 				set |= SET_VID2;
    201 				check_video2 |= VID2_VGA;
    202 			}
    203 			break;
    204 		case 'v':
    205 			if (check_video2 & VID2_VGA) {
    206 				usage();
    207 			} else {
    208 				bootpref[ARRAY_VID2] |= VID2_VGA;
    209 				set |= SET_VID2;
    210 				check_video2 |= VID2_VGA;
    211 			}
    212 			break;
    213 		case '4':
    214 			if (check_video2 & VID2_80CLM) {
    215 				usage();
    216 			} else {
    217 				bootpref[ARRAY_VID2] &= ~VID2_80CLM;
    218 				set |= SET_VID2;
    219 				check_video2 |= VID2_80CLM;
    220 			}
    221 			break;
    222 		case '8':
    223 			if (check_video2 & VID2_80CLM) {
    224 				usage();
    225 			} else {
    226 				bootpref[ARRAY_VID2] |= VID2_80CLM;
    227 				set |= SET_VID2;
    228 				check_video2 |= VID2_80CLM;
    229 			}
    230 			break;
    231 		case 'o':
    232 			if (check_video2 & VID2_OVERSCAN) {
    233 				usage();
    234 			} else {
    235 				bootpref[ARRAY_VID2] |= VID2_OVERSCAN;
    236 				set |= SET_VID2;
    237 				check_video2 |= VID2_OVERSCAN;
    238 			}
    239 			break;
    240 		case 'O':
    241 			if (check_video2 & VID2_OVERSCAN) {
    242 				usage();
    243 			} else {
    244 				bootpref[ARRAY_VID2] &= ~VID2_OVERSCAN;
    245 				set |= SET_VID2;
    246 				check_video2 |= VID2_OVERSCAN;
    247 			}
    248 			break;
    249 		case 'x':
    250 			if (check_video2 & VID2_COMPAT) {
    251 				usage();
    252 			} else {
    253 				bootpref[ARRAY_VID2] |= VID2_COMPAT;
    254 				set |= SET_VID2;
    255 				check_video2 |= VID2_COMPAT;
    256 			}
    257 			break;
    258 		case 'X':
    259 			if (check_video2 & VID2_COMPAT) {
    260 				usage();
    261 			} else {
    262 				bootpref[ARRAY_VID2] &= ~VID2_COMPAT;
    263 				set |= SET_VID2;
    264 				check_video2 |= VID2_COMPAT;
    265 			}
    266 			break;
    267 		case 'i':
    268 			if (check_video1 & VID1_INTERLACE) {
    269 				usage();
    270 			} else {
    271 				bootpref[ARRAY_VID1] |= VID1_INTERLACE;
    272 				set |= SET_VID1;
    273 				check_video1 |= VID1_INTERLACE;
    274 			}
    275 			break;
    276 		case 'I':
    277 			if (check_video1 & VID1_INTERLACE) {
    278 				usage();
    279 			} else {
    280 				bootpref[ARRAY_VID1] &= ~VID1_INTERLACE;
    281 				set |= SET_VID1;
    282 				check_video1 |= VID1_INTERLACE;
    283 			}
    284 			break;
    285 		default:
    286 			usage ();
    287 		}
    288 	}
    289 	if (optind != argc) {
    290 		usage ();
    291 	}
    292 	if (set) {
    293 		setNVpref (fd, bootpref, set, verbose);
    294 	} else {
    295 		getNVpref (fd, bootpref);
    296 	}
    297 	closeNVRAM (fd);
    298 	return (EXIT_SUCCESS);
    299 }
    300 
    301 static void
    302 usage (void)
    303 {
    304 	fprintf (stderr,
    305 		"usage: bootpref [-V] [-b os] [-d delay] [-k kbd] [-l lang] "
    306 		"[-s id]\n"
    307 		"\t[-f fmt] [-1] [-2] [-e sep]\n"
    308 		"\t[-c colours] [-n] [-p] [-t] [-v] [-4] [-8]\n"
    309 		"\t[-o] [-O] [-x] [-X] [-i] [-I]\n");
    310 	exit (EXIT_FAILURE);
    311 }
    312 
    313 static int
    314 openNVRAM ()
    315 {
    316 	int fd;
    317 
    318 	if ((fd = open (nvrdev, O_RDWR)) < 0) {
    319 		err (EXIT_FAILURE, "%s", nvrdev);
    320 	}
    321 	return (fd);
    322 }
    323 
    324 static void
    325 closeNVRAM (fd)
    326 	int fd;
    327 {
    328 	if (close (fd) < 0) {
    329 		err (EXIT_FAILURE, "%s", nvrdev);
    330 	}
    331 }
    332 
    333 static u_char
    334 readNVRAM (fd, pos)
    335 	int fd, pos;
    336 {
    337 	u_char val;
    338 
    339 	if (lseek(fd, (off_t)pos, SEEK_SET) != pos) {
    340 		err(EXIT_FAILURE, "%s", nvrdev);
    341 	}
    342 	if (read (fd, &val, (size_t)1) != 1) {
    343 		err(EXIT_FAILURE, "%s", nvrdev);
    344 	}
    345 	return (val);
    346 }
    347 
    348 static void
    349 writeNVRAM (fd, pos, val)
    350 	int fd, pos;
    351 	u_char val;
    352 {
    353 	if (lseek(fd, (off_t)pos, SEEK_SET) != pos) {
    354 		err(EXIT_FAILURE, "%s", nvrdev);
    355 	}
    356 	if (write (fd, &val, (size_t)1) != 1) {
    357 		err(EXIT_FAILURE, "%s", nvrdev);
    358 	}
    359 }
    360 
    361 static void
    362 getNVpref (fd, bootpref)
    363 	int fd;
    364 	u_char bootpref[];
    365 {
    366 	/* Boot OS */
    367 	printf ("Boot OS is ");
    368 	showOS (readNVRAM (fd, NVRAM_BOOTPREF));
    369 	/* Boot Delay */
    370 	printf ("Boot delay is %d seconds\n", readNVRAM (fd, NVRAM_BOOTDLY));
    371 	/* TOS Language */
    372 	printf ("Language is ");
    373 	showLang (readNVRAM (fd, NVRAM_LANG));
    374 	/* Keyboard Language */
    375 	printf ("Keyboard is ");
    376 	showKbdLang (readNVRAM (fd, NVRAM_KBDLANG));
    377 	/* SCSI Host ID */
    378 	printf ("SCSI host ID is ");
    379 	if (readNVRAM (fd, NVRAM_HOSTID) & HOSTID_VALID) {
    380 		printf ("%d\n", readNVRAM (fd, NVRAM_HOSTID) ^ HOSTID_VALID);
    381 	} else {
    382 		printf ("invalid");
    383 	}
    384 	/* Date format/separator */
    385 	printf ("Date format is ");
    386 	showDateFmt (readNVRAM (fd, NVRAM_DATIME));
    387 	printf ("Date separator is ");
    388 	showDateSep (readNVRAM (fd, NVRAM_DATESEP));
    389 	/* Video */
    390 	printf ("Video is (0x%02x, 0x%02x) :\n", readNVRAM (fd, NVRAM_VID2),
    391 	    readNVRAM (fd, NVRAM_VID1));
    392 	showVideo2 (readNVRAM (fd, NVRAM_VID2));
    393 	showVideo1 (readNVRAM (fd, NVRAM_VID1), readNVRAM (fd, NVRAM_VID2));
    394 }
    395 
    396 static void
    397 setNVpref (fd, bootpref, set, verbose)
    398 	int fd;
    399 	u_char bootpref[];
    400 	int verbose;
    401 {
    402 	/* Boot OS */
    403 	if (set & SET_OS) {
    404 		writeNVRAM (fd, NVRAM_BOOTPREF, bootpref[ARRAY_OS]);
    405 		if (verbose) {
    406 			printf ("Boot OS set to ");
    407 			showOS (readNVRAM (fd, NVRAM_BOOTPREF));
    408 		}
    409 	}
    410 	/* Boot Delay */
    411 	if (set & SET_BOOTDLY) {
    412 		writeNVRAM (fd, NVRAM_BOOTDLY, bootpref[ARRAY_BOOTDLY]);
    413 		if (verbose) {
    414 			printf ("Boot delay set to %d seconds\n", readNVRAM (fd,
    415 			    NVRAM_BOOTDLY));
    416 		}
    417 	}
    418 	/* TOS Language */
    419 	if (set & SET_LANG) {
    420 		writeNVRAM (fd, NVRAM_LANG, bootpref[ARRAY_LANG]);
    421 		if (verbose) {
    422 			printf ("Language set to ");
    423 			showLang (readNVRAM (fd, NVRAM_LANG));
    424 		}
    425 	}
    426 	/* Keyboard Language */
    427 	if (set & SET_KBDLANG) {
    428 		writeNVRAM (fd, NVRAM_KBDLANG, bootpref[ARRAY_KBDLANG]);
    429 		if (verbose) {
    430 			printf ("Keyboard set to ");
    431 			showKbdLang (readNVRAM (fd, NVRAM_KBDLANG));
    432 		}
    433 	}
    434 	/* SCSI Host ID */
    435 	if (set & SET_HOSTID) {
    436 		writeNVRAM (fd, NVRAM_HOSTID, bootpref[ARRAY_HOSTID] |
    437 		    HOSTID_VALID);
    438 		if (verbose) {
    439 			printf ("SCSI host ID set to ");
    440 			printf ("%d\n", readNVRAM (fd, NVRAM_HOSTID) ^
    441 				HOSTID_VALID);
    442 		}
    443 	}
    444 	/* Date format/separator */
    445 	if (set & SET_DATIME) {
    446 		writeNVRAM (fd, NVRAM_DATIME, bootpref[ARRAY_DATIME]);
    447 		if (verbose) {
    448 			printf ("Date format set to ");
    449 			showDateFmt (readNVRAM (fd, NVRAM_DATIME));
    450 			printf ("\n");
    451 		}
    452 	}
    453 	if (set & SET_DATESEP) {
    454 		writeNVRAM (fd, NVRAM_DATESEP, bootpref[ARRAY_DATESEP]);
    455 		if (verbose) {
    456 			printf ("Date separator set to ");
    457 			showDateSep (readNVRAM (fd, NVRAM_DATESEP));
    458 		}
    459 	}
    460 	/* Video */
    461 	if ((set & SET_VID2) || (set & SET_VID1)) {
    462 		if (set & SET_VID2) {
    463 			writeNVRAM (fd, NVRAM_VID2, bootpref[ARRAY_VID2]);
    464 		}
    465 		if (set & SET_VID1) {
    466 			writeNVRAM (fd, NVRAM_VID1, bootpref[ARRAY_VID1]);
    467 		}
    468 		if (verbose) {
    469 			printf ("Video set to (0x%02x, 0x%02x) :\n",
    470 			    readNVRAM (fd, NVRAM_VID2),
    471 			    readNVRAM (fd, NVRAM_VID1));
    472 			showVideo2 (readNVRAM (fd, NVRAM_VID2));
    473 			showVideo1 (readNVRAM (fd, NVRAM_VID1),
    474 			    readNVRAM (fd, NVRAM_VID2));
    475 		}
    476 	}
    477 }
    478 
    479 static void
    480 showOS (bootos)
    481 	u_char bootos;
    482 {
    483 	switch (bootos) {
    484 	case BOOTPREF_NETBSD:
    485 		printf ("NetBSD");
    486 		break;
    487 	case BOOTPREF_TOS:
    488 		printf ("TOS");
    489 		break;
    490 	case BOOTPREF_MAGIC:
    491 		printf ("MAGIC");
    492 		break;
    493 	case BOOTPREF_LINUX:
    494 		printf ("Linux");
    495 		break;
    496 	case BOOTPREF_SYSV:
    497 		printf ("System V");
    498 		break;
    499 	case BOOTPREF_NONE:
    500 		printf ("none");
    501 		break;
    502 	default:
    503 		printf ("unknown");
    504 		break;
    505 	}
    506 	printf (" (0x%x).\n", bootos);
    507 }
    508 
    509 static void
    510 showLang (lang)
    511 	u_char lang;
    512 {
    513 	switch (lang) {
    514 	case LANG_USA:
    515 	case LANG_GB:
    516 		printf ("English");
    517 		break;
    518 	case LANG_D:
    519 		printf ("German");
    520 		break;
    521 	case LANG_FR:
    522 		printf ("French");
    523 		break;
    524 	case LANG_ESP:
    525 		printf ("Spanish");
    526 		break;
    527 	case LANG_I:
    528 		printf ("Italian");
    529 		break;
    530 	default:
    531 		printf ("unknown");
    532 		break;
    533 	}
    534 	printf (" (0x%x).\n", lang);
    535 }
    536 
    537 static void
    538 showKbdLang (lang)
    539 	u_char lang;
    540 {
    541 	switch (lang) {
    542 	case KBDLANG_USA:
    543 		printf ("American");
    544 		break;
    545 	case KBDLANG_D:
    546 		printf ("German");
    547 		break;
    548 	case KBDLANG_FR:
    549 		printf ("French");
    550 		break;
    551 	case KBDLANG_GB:
    552 		printf ("British");
    553 		break;
    554 	case KBDLANG_ESP:
    555 		printf ("Spanish");
    556 		break;
    557 	case KBDLANG_I:
    558 		printf ("Italian");
    559 		break;
    560 	case KBDLANG_CHF:
    561 		printf ("Swiss (French)");
    562 		break;
    563 	case KBDLANG_CHD:
    564 		printf ("Swiss (German)");
    565 		break;
    566 	default:
    567 		printf ("unknown");
    568 		break;
    569 	}
    570 	printf (" (0x%x).\n", lang);
    571 }
    572 
    573 static void
    574 showDateFmt (fmt)
    575 	u_char fmt;
    576 {
    577 	if (fmt & DATIME_24H) {
    578 		printf ("24 hour clock, ");
    579 	} else {
    580 		printf ("12 hour clock, ");
    581 	}
    582 	switch (fmt & ~DATIME_24H) {
    583 	case DATIME_MMDDYY:
    584 		printf ("MMDDYY");
    585 		break;
    586 	case DATIME_DDMMYY:
    587 		printf ("DDMMYY");
    588 		break;
    589 	case DATIME_YYMMDD:
    590 		printf ("YYMMDD");
    591 		break;
    592 	case DATIME_YYDDMM:
    593 		printf ("YYDDMM");
    594 		break;
    595 	default:
    596 		printf ("unknown");
    597 		break;
    598 	}
    599 	printf (" (0x%02x)\n", fmt);
    600 }
    601 
    602 static void
    603 showDateSep (sep)
    604 	u_char sep;
    605 {
    606 	if (sep) {
    607 		if (sep >= 0x20) {
    608 			printf ("\"%c\" ", sep);
    609 		}
    610 	} else {
    611 		printf ("\"/\" ");
    612 	}
    613 	printf ("(0x%02x)\n", sep);
    614 }
    615 
    616 static void
    617 showVideo2 (vid2)
    618 	u_char vid2;
    619 {
    620 	u_char colours;
    621 
    622 	colours = vid2 & 0x07;
    623 	printf ("\t");
    624 	switch (colours) {
    625 	case VID2_2COL:
    626 		printf ("2");
    627 		break;
    628 	case VID2_4COL:
    629 		printf ("4");
    630 		break;
    631 	case VID2_16COL:
    632 		printf ("16");
    633 		break;
    634 	case VID2_256COL:
    635 		printf ("256");
    636 		break;
    637 	case VID2_65535COL:
    638 		printf ("65535");
    639 		break;
    640 	}
    641 	printf (" colours, ");
    642 	if (vid2 & VID2_80CLM) {
    643 		printf ("80");
    644 	} else {
    645 		printf ("40");
    646 	}
    647 	printf (" column, ");
    648 	if (vid2 & VID2_VGA) {
    649 		printf ("VGA");
    650 	} else {
    651 		printf ("TV");
    652 	}
    653 	printf (", ");
    654 	if (vid2 & VID2_PAL) {
    655 		printf ("PAL\n");
    656 	} else {
    657 		printf ("NTSC\n");
    658 	}
    659 	printf ("\tOverscan ");
    660 	if (vid2 & VID2_OVERSCAN) {
    661 		printf ("on\n");
    662 	} else {
    663 		printf ("off\n");
    664 	}
    665 	printf ("\tST compatibility ");
    666 	if (vid2 & VID2_COMPAT) {
    667 		printf ("on\n");
    668 	} else {
    669 		printf ("off\n");
    670 	}
    671 }
    672 
    673 static void
    674 showVideo1 (vid1, vid2)
    675 	u_char vid1, vid2;
    676 {
    677 	if (vid2 & VID2_VGA) {
    678 		printf ("\tDouble line ");
    679 		if (vid1 & VID1_INTERLACE) {
    680 			printf ("on");
    681 		} else {
    682 			printf ("off");
    683 		}
    684 	} else {
    685 		printf ("\tInterlace ");
    686 		if (vid1 & VID1_INTERLACE) {
    687 			printf ("on");
    688 		} else {
    689 			printf ("off");
    690 		}
    691 	}
    692 	printf ("\n");
    693 }
    694 
    695 static int
    696 checkOS (val, str)
    697 	u_char *val;
    698 	char *str;
    699 {
    700 	if (!strncasecmp (str, "ne", 2)) {
    701 		*val = BOOTPREF_NETBSD;
    702 		return (1);
    703 	}
    704 	if (!strncasecmp (str, "t", 1)) {
    705 		*val = BOOTPREF_TOS;
    706 		return (1);
    707 	}
    708 	if (!strncasecmp (str, "m", 1)) {
    709 		*val = BOOTPREF_MAGIC;
    710 		return (1);
    711 	}
    712 	if (!strncasecmp (str, "l", 1)) {
    713 		*val = BOOTPREF_LINUX;
    714 		return (1);
    715 	}
    716 	if (!strncasecmp (str, "s", 1)) {
    717 		*val = BOOTPREF_SYSV;
    718 		return (1);
    719 	}
    720 	if (!strncasecmp (str, "no", 2)) {
    721 		*val = BOOTPREF_NONE;
    722 		return (1);
    723 	}
    724 	return (0);
    725 }
    726 
    727 static int
    728 checkLang (val, str)
    729 	u_char *val;
    730 	char *str;
    731 {
    732 	if (!strncasecmp (str, "e", 1)) {
    733 		*val = LANG_GB;
    734 		return (1);
    735 	}
    736 	if (!strncasecmp (str, "g", 1)) {
    737 		*val = LANG_D;
    738 		return (1);
    739 	}
    740 	if (!strncasecmp (str, "f", 1)) {
    741 		*val = LANG_FR;
    742 		return (1);
    743 	}
    744 	if (!strncasecmp (str, "s", 1)) {
    745 		*val = LANG_ESP;
    746 		return (1);
    747 	}
    748 	if (!strncasecmp (str, "i", 1)) {
    749 		*val = LANG_I;
    750 		return (1);
    751 	}
    752 	return (0);
    753 }
    754 
    755 static int
    756 checkKbdLang (val, str)
    757 	u_char *val;
    758 	char *str;
    759 {
    760 	if (!strncasecmp (str, "a", 1)) {
    761 		*val = KBDLANG_USA;
    762 		return (1);
    763 	}
    764 	if (!strncasecmp (str, "g", 1)) {
    765 		*val = KBDLANG_D;
    766 		return (1);
    767 	}
    768 	if (!strncasecmp (str, "f", 1)) {
    769 		*val = KBDLANG_FR;
    770 		return (1);
    771 	}
    772 	if (!strncasecmp (str, "b", 1)) {
    773 		*val = KBDLANG_GB;
    774 		return (1);
    775 	}
    776 	if (!strncasecmp (str, "sp", 2)) {
    777 		*val = KBDLANG_ESP;
    778 		return (1);
    779 	}
    780 	if (!strncasecmp (str, "i", 1)) {
    781 		*val = KBDLANG_I;
    782 		return (1);
    783 	}
    784 	if (!strncasecmp (str, "swiss f", 7) || !strncasecmp (str, "sw f", 4)) {
    785 		*val = KBDLANG_CHF;
    786 		return (1);
    787 	}
    788 	if (!strncasecmp (str, "swiss g", 7) || !strncasecmp (str, "sw g", 4)) {
    789 		*val = KBDLANG_CHD;
    790 		return (1);
    791 	}
    792 	return (0);
    793 }
    794 
    795 static int
    796 checkInt (val, str, min, max)
    797 	u_char *val;
    798 	char *str;
    799 	int min, max;
    800 {
    801 	int num;
    802 	if (1 == sscanf (str, "%d", &num) && num >= min && num <= max) {
    803 		*val = num;
    804 		return (1);
    805 	}
    806 	return (0);
    807 }
    808 
    809 static int
    810 checkDateFmt (val, str)
    811 	u_char *val;
    812 	char *str;
    813 {
    814 	if (!strncasecmp (str, "m", 1)) {
    815 		*val |= DATIME_MMDDYY;
    816 		return (1);
    817 	}
    818 	if (!strncasecmp (str, "d", 1)) {
    819 		*val |= DATIME_DDMMYY;
    820 		return (1);
    821 	}
    822 	if (!strncasecmp (str, "yym", 3)) {
    823 		*val |= DATIME_YYMMDD;
    824 		return (1);
    825 	}
    826 	if (!strncasecmp (str, "yyd", 3)) {
    827 		*val |= DATIME_YYDDMM;
    828 		return (1);
    829 	}
    830 	return (0);
    831 }
    832 
    833 static void
    834 checkDateSep (val, str)
    835 	u_char *val;
    836 	char *str;
    837 {
    838 	if (str[0] == '/') {
    839 		*val = 0;
    840 	} else {
    841 		*val = str[0];
    842 	}
    843 }
    844 
    845 static int
    846 checkColours (val, str)
    847 	u_char *val;
    848 	char *str;
    849 {
    850 	*val &= ~0x07;
    851 	if (!strncasecmp (str, "6", 1)) {
    852 		*val |= VID2_65535COL;
    853 		return (1);
    854 	}
    855 	if (!strncasecmp (str, "25", 2)) {
    856 		*val |= VID2_256COL;
    857 		return (1);
    858 	}
    859 	if (!strncasecmp (str, "1", 1)) {
    860 		*val |= VID2_16COL;
    861 		return (1);
    862 	}
    863 	if (!strncasecmp (str, "4", 1)) {
    864 		*val |= VID2_4COL;
    865 		return (1);
    866 	}
    867 	if (!strncasecmp (str, "2", 1)) {
    868 		*val |= VID2_2COL;
    869 		return (1);
    870 	}
    871 	return (0);
    872 }
    873