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