1/*	$NetBSD: bootpref.c,v 1.5 2009/03/14 21:04:07 dsl 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
41static void	usage(void);
42static int	openNVRAM(void);
43static void	closeNVRAM(int);
44static u_char	readNVRAM(int, int);
45static void	writeNVRAM(int, int, u_char);
46static void	getNVpref(int, u_char[]);
47static void	setNVpref(int, u_char[], int, int);
48static void	showOS(u_char);
49static void	showLang(u_char);
50static void	showKbdLang(u_char);
51static void	showDateFmt(u_char);
52static void	showDateSep(u_char);
53static void	showVideo2(u_char);
54static void	showVideo1(u_char, u_char);
55static int	checkOS(u_char *, char *);
56static int	checkLang(u_char *, char *);
57static int	checkKbdLang(u_char *, char *);
58static int	checkInt(u_char *, char *, int, int);
59static int 	checkDateFmt(u_char *, char *);
60static void 	checkDateSep(u_char *, char *);
61static 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
83static const char	nvrdev[] = PATH_NVRAM;
84
85int
86main (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
292static void
293usage (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
304static int
305openNVRAM ()
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
315static void
316closeNVRAM (int fd)
317{
318	if (close (fd) < 0) {
319		err (EXIT_FAILURE, "%s", nvrdev);
320	}
321}
322
323static u_char
324readNVRAM (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
337static void
338writeNVRAM (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
348static void
349getNVpref (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
381static void
382setNVpref (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
461static void
462showOS (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
490static void
491showLang (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
517static void
518showKbdLang (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
552static void
553showDateFmt (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
580static void
581showDateSep (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
593static void
594showVideo2 (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
649static void
650showVideo1 (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
670static int
671checkOS (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
700static int
701checkLang (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
726static int
727checkKbdLang (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
764static int
765checkInt (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
775static int
776checkDateFmt (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
797static void
798checkDateSep (u_char *val, char *str)
799{
800	if (str[0] == '/') {
801		*val = 0;
802	} else {
803		*val = str[0];
804	}
805}
806
807static int
808checkColours (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