1/* $NetBSD: tadpolectl.c,v 1.7 2008/04/28 20:24:17 martin Exp $ */
2
3/*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tim Rightnour.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <ctype.h>
33#include <err.h>
34#include <stdio.h>
35#include <string.h>
36#include <stdlib.h>
37#include <fcntl.h>
38#include <unistd.h>
39#include <sys/ioctl.h>
40#include <sys/types.h>
41#include <sys/envsys.h>
42#include <machine/apmvar.h>
43#include <machine/tctrl.h>
44
45#define TCTRL_DEV	"/dev/tctrl0"
46
47int aflag, nflag, wflag, dev;
48
49#define PROTO(x) int x __P((int, int, int));
50void usage __P((void));
51static void parse __P((char *));
52char *dashdot __P((const char *));
53int main __P((int, char *[]));
54PROTO(hw_version)
55PROTO(hw_microcontroller_version)
56PROTO(hw_poweroncycles)
57PROTO(hw_poweronseconds)
58PROTO(hw_power_mains)
59PROTO(hw_power_battery_int)
60PROTO(hw_power_battery_ext)
61PROTO(hw_power_battery_int_chargerate)
62PROTO(hw_power_battery_ext_chargerate)
63PROTO(hw_power_battery_int_chargelevel)
64PROTO(hw_power_battery_ext_chargelevel)
65PROTO(hw_video_external)
66PROTO(hw_video_lid)
67PROTO(hw_video_syncinva)
68PROTO(hw_video_syncinvb)
69PROTO(hw_video_compsync)
70PROTO(hw_video_tft_brightness)
71PROTO(hw_speaker_freq)
72PROTO(hw_speaker_volume)
73PROTO(hw_kbd_repeat_delay)
74PROTO(hw_kbd_repeat_speed)
75PROTO(hw_mouse_recalibrate)
76PROTO(hw_power_battery_chargedisabled)
77PROTO(hw_mouse_disable)
78PROTO(hw_kbd_click)
79PROTO(hw_mouse_intclick)
80PROTO(hw_mouse_extclick)
81PROTO(hw_mouse_sensitivity)
82PROTO(hw_serial_power)
83
84#define NUM_MIBS 29
85#define TABLE(n) { __STRING(n), 0, n }
86
87struct {
88	const char *mib;
89	int value;
90	int (*funcptr)(int, int, int);
91} table[NUM_MIBS] = {
92	TABLE(hw_microcontroller_version),
93	TABLE(hw_version),
94	TABLE(hw_poweroncycles),
95	TABLE(hw_poweronseconds),
96	TABLE(hw_power_mains),
97	TABLE(hw_power_battery_int),
98	TABLE(hw_power_battery_ext),
99	TABLE(hw_power_battery_chargedisabled),
100	TABLE(hw_power_battery_int_chargerate),
101	TABLE(hw_power_battery_ext_chargerate),
102	TABLE(hw_power_battery_int_chargelevel),
103	TABLE(hw_power_battery_ext_chargelevel),
104	TABLE(hw_video_external),
105	TABLE(hw_video_lid),
106	TABLE(hw_video_syncinva),
107	TABLE(hw_video_syncinvb),
108	TABLE(hw_video_compsync),
109	TABLE(hw_video_tft_brightness),
110	TABLE(hw_speaker_freq),
111	TABLE(hw_speaker_volume),
112	TABLE(hw_kbd_repeat_delay),
113	TABLE(hw_kbd_repeat_speed),
114	TABLE(hw_kbd_click),
115	TABLE(hw_mouse_recalibrate),
116	TABLE(hw_mouse_disable),
117	TABLE(hw_mouse_intclick),
118	TABLE(hw_mouse_extclick),
119	TABLE(hw_mouse_sensitivity),
120	TABLE(hw_serial_power),
121};
122
123#define FUNC(x) \
124int \
125x(readflg, new, num) \
126	int readflg, new, num;
127
128#define READ_REQ(a, b, c) \
129	req.cmdbuf[0] = a; \
130	req.cmdlen = b; \
131	req.rsplen = c; \
132	ioctl(dev, TCTRL_CMD_REQ, &req)
133
134#define WRITE_REQ(a, b, c) \
135	req.cmdbuf[0] = a; \
136	req.cmdlen = b; \
137	req.rsplen = c; \
138	ioctl(dev, TCTRL_CMD_REQ, &req)
139
140#define READ_ONLY \
141	if (!readflg) \
142		return(0)
143
144/* hardware functions */
145
146FUNC(hw_mouse_sensitivity)
147{
148	struct tctrl_req req;
149
150	req.cmdbuf[1] = 0xff;
151	req.cmdbuf[2] = 0x00;
152	READ_REQ(0x2c, 3, 2);
153	table[num].value = req.rspbuf[0];
154	if (readflg)
155		return(1);
156	if (new == 0)
157		req.cmdbuf[2] = 0x00;
158	else if (new > 255)
159		req.cmdbuf[2] = 0xff;
160	else
161		req.cmdbuf[2] = new;
162	req.cmdbuf[1] = 0x00;
163	WRITE_REQ(0x2c, 3, 2);
164	req.cmdbuf[1] = 0xff;
165	req.cmdbuf[2] = 0x00;
166	READ_REQ(0x2c, 3, 2);
167	table[num].value = req.rspbuf[0];
168	return(1);
169}
170
171FUNC(hw_power_battery_chargedisabled)
172{
173	struct tctrl_req req;
174
175	req.cmdbuf[1] = 0xff;
176	req.cmdbuf[2] = 0x00;
177	READ_REQ(0x22, 3, 2);
178	table[num].value = req.rspbuf[0]&0x01 ? 1 : 0;
179	if (readflg)
180		return(1);
181	if (new == 0)
182		req.cmdbuf[2] = 0x00;
183	else
184		req.cmdbuf[2] = 0x01;
185	req.cmdbuf[1] = ~0x01;
186	WRITE_REQ(0x22, 3, 2);
187	req.cmdbuf[1] = 0xff;
188	req.cmdbuf[2] = 0x00;
189	READ_REQ(0x22, 3, 2);
190	table[num].value = req.rspbuf[0]&0x01 ? 1 : 0;
191	return(1);
192}
193
194FUNC(hw_mouse_disable)
195{
196	struct tctrl_req req;
197
198	req.cmdbuf[1] = 0xff;
199	req.cmdbuf[2] = 0x00;
200	READ_REQ(0x22, 3, 2);
201	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
202	if (readflg)
203		return(1);
204	if (new == 0)
205		req.cmdbuf[2] = 0x00;
206	else
207		req.cmdbuf[2] = 0x02;
208	req.cmdbuf[1] = ~0x02;
209	WRITE_REQ(0x22, 3, 2);
210	req.cmdbuf[1] = 0xff;
211	req.cmdbuf[2] = 0x00;
212	READ_REQ(0x22, 3, 2);
213	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
214	return(1);
215}
216
217FUNC(hw_kbd_click)
218{
219	struct tctrl_req req;
220
221	req.cmdbuf[1] = 0xff;
222	req.cmdbuf[2] = 0x00;
223	READ_REQ(0x22, 3, 2);
224	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
225	if (readflg)
226		return(1);
227	if (new == 0)
228		req.cmdbuf[2] = 0x00;
229	else
230		req.cmdbuf[2] = 0x04;
231	req.cmdbuf[1] = ~0x04;
232	WRITE_REQ(0x22, 3, 2);
233	req.cmdbuf[1] = 0xff;
234	req.cmdbuf[2] = 0x00;
235	READ_REQ(0x22, 3, 2);
236	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
237	return(1);
238}
239
240FUNC(hw_mouse_intclick)
241{
242	struct tctrl_req req;
243
244	req.cmdbuf[1] = 0xff;
245	req.cmdbuf[2] = 0x00;
246	READ_REQ(0x22, 3, 2);
247	table[num].value = req.rspbuf[0]&0x08 ? 1 : 0;
248	if (readflg)
249		return(1);
250	if (new == 0)
251		req.cmdbuf[2] = 0x00;
252	else
253		req.cmdbuf[2] = 0x08;
254	req.cmdbuf[1] = ~0x08;
255	WRITE_REQ(0x22, 3, 2);
256	req.cmdbuf[1] = 0xff;
257	req.cmdbuf[2] = 0x00;
258	READ_REQ(0x22, 3, 2);
259	table[num].value = req.rspbuf[0]&0x08 ? 1 : 0;
260	return(1);
261}
262
263FUNC(hw_mouse_extclick)
264{
265	struct tctrl_req req;
266
267	req.cmdbuf[1] = 0xff;
268	req.cmdbuf[2] = 0x00;
269	READ_REQ(0x22, 3, 2);
270	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
271	if (readflg)
272		return(1);
273	if (new == 0)
274		req.cmdbuf[2] = 0x00;
275	else
276		req.cmdbuf[2] = 0x10;
277	req.cmdbuf[1] = ~0x10;
278	WRITE_REQ(0x22, 3, 2);
279	req.cmdbuf[1] = 0xff;
280	req.cmdbuf[2] = 0x00;
281	READ_REQ(0x22, 3, 2);
282	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
283	return(1);
284}
285
286/* ARGSUSED */
287FUNC(hw_mouse_recalibrate)
288{
289	struct tctrl_req req;
290
291	table[num].value = 0;
292	if (readflg)
293		return(1);
294	READ_REQ(0x36, 1, 1);
295	return(1);
296}
297
298FUNC(hw_kbd_repeat_delay)
299{
300	struct tctrl_req req;
301
302	req.cmdbuf[1] = 0xff;
303	req.cmdbuf[2] = 0x00;
304	READ_REQ(0x28, 3, 2);
305	table[num].value = req.rspbuf[0];
306	if (readflg)
307		return(1);
308	if (new == 0)
309		req.cmdbuf[2] = 0x00;
310	else if (new > 255)
311		req.cmdbuf[2] = 0xff;
312	else
313		req.cmdbuf[2] = new;
314	req.cmdbuf[1] = 0x00;
315	WRITE_REQ(0x28, 3, 2);
316	req.cmdbuf[1] = 0xff;
317	req.cmdbuf[2] = 0x00;
318	READ_REQ(0x28, 3, 2);
319	table[num].value = req.rspbuf[0];
320	return(1);
321}
322
323FUNC(hw_kbd_repeat_speed)
324{
325	struct tctrl_req req;
326
327	req.cmdbuf[1] = 0xff;
328	req.cmdbuf[2] = 0x00;
329	READ_REQ(0x29, 3, 2);
330	table[num].value = req.rspbuf[0];
331	if (readflg)
332		return(1);
333	if (new == 0)
334		req.cmdbuf[2] = 0x00;
335	else if (new > 255)
336		req.cmdbuf[2] = 0xff;
337	else
338		req.cmdbuf[2] = new;
339	req.cmdbuf[1] = 0x00;
340	WRITE_REQ(0x29, 3, 2);
341	req.cmdbuf[1] = 0xff;
342	req.cmdbuf[2] = 0x00;
343	READ_REQ(0x29, 3, 2);
344	table[num].value = req.rspbuf[0];
345	return(1);
346}
347
348FUNC(hw_speaker_freq)
349{
350	struct tctrl_req req;
351
352	table[num].value = 0;
353	if (readflg)
354		return(1);
355	req.cmdbuf[1] = new * 256;
356	req.cmdbuf[2] = new % 256;
357	WRITE_REQ(0x37, 3, 1);
358	return(1);
359}
360
361FUNC(hw_speaker_volume)
362{
363	struct tctrl_req req;
364
365	req.cmdbuf[1] = 0xff;
366	req.cmdbuf[2] = 0x00;
367	READ_REQ(0x23, 3, 2);
368	table[num].value = req.rspbuf[0];
369	if (readflg)
370		return(1);
371	if (new == 0)
372		req.cmdbuf[2] = 0x00;
373	else if (new > 255)
374		req.cmdbuf[2] = 0xff;
375	else
376		req.cmdbuf[2] = new;
377	req.cmdbuf[1] = 0x00;
378	WRITE_REQ(0x23, 3, 2);
379	req.cmdbuf[1] = 0xff;
380	req.cmdbuf[2] = 0x00;
381	READ_REQ(0x23, 3, 2);
382	table[num].value = req.rspbuf[0];
383	return(1);
384}
385
386FUNC(hw_video_tft_brightness)
387{
388	struct tctrl_req req;
389
390	req.cmdbuf[1] = 0xff;
391	req.cmdbuf[2] = 0x00;
392	READ_REQ(0x24, 3, 2);
393	table[num].value = req.rspbuf[0];
394	if (readflg)
395		return(1);
396	if (new == 0)
397		req.cmdbuf[2] = 0x00;
398	else if (new > 255)
399		req.cmdbuf[2] = 0xff;
400	else
401		req.cmdbuf[2] = new;
402	req.cmdbuf[1] = 0x00;
403	WRITE_REQ(0x24, 3, 2);
404	req.cmdbuf[1] = 0xff;
405	req.cmdbuf[2] = 0x00;
406	READ_REQ(0x24, 3, 2);
407	table[num].value = req.rspbuf[0];
408	return(1);
409}
410
411FUNC(hw_video_syncinva)
412{
413	struct tctrl_req req;
414
415	req.cmdbuf[1] = 0xff;
416	req.cmdbuf[2] = 0x00;
417	READ_REQ(0x21, 3, 2);
418	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
419	if (readflg)
420		return(1);
421	if (new == 0)
422		req.cmdbuf[2] = 0x00;
423	else
424		req.cmdbuf[2] = 0x02;
425	req.cmdbuf[1] = ~0x02;
426	WRITE_REQ(0x21, 3, 2);
427	req.cmdbuf[1] = 0xff;
428	req.cmdbuf[2] = 0x00;
429	READ_REQ(0x21, 3, 2);
430	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
431	return(1);
432}
433
434FUNC(hw_video_syncinvb)
435{
436	struct tctrl_req req;
437
438	req.cmdbuf[1] = 0xff;
439	req.cmdbuf[2] = 0x00;
440	READ_REQ(0x21, 3, 2);
441	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
442	if (readflg)
443		return(1);
444	if (new == 0)
445		req.cmdbuf[2] = 0x00;
446	else
447		req.cmdbuf[2] = 0x04;
448	req.cmdbuf[1] = ~0x04;
449	WRITE_REQ(0x21, 3, 2);
450	req.cmdbuf[1] = 0xff;
451	req.cmdbuf[2] = 0x00;
452	READ_REQ(0x21, 3, 2);
453	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
454	return(1);
455}
456
457FUNC(hw_video_compsync)
458{
459	struct tctrl_req req;
460
461	req.cmdbuf[1] = 0xff;
462	req.cmdbuf[2] = 0x00;
463	READ_REQ(0x21, 3, 2);
464	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
465	if (readflg)
466		return(1);
467	if (new == 0)
468		req.cmdbuf[2] = 0x00;
469	else
470		req.cmdbuf[2] = 0x10;
471	req.cmdbuf[1] = ~0x10;
472	WRITE_REQ(0x21, 3, 2);
473	req.cmdbuf[1] = 0xff;
474	req.cmdbuf[2] = 0x00;
475	READ_REQ(0x21, 3, 2);
476	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
477	return(1);
478}
479
480/* ARGSUSED */
481FUNC(hw_video_lid)
482{
483	struct tctrl_req req;
484	short i;
485
486	READ_ONLY;
487	READ_REQ(0x11, 1, 3);
488	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
489	table[num].value = i&0x0040 ? 0 : 1;
490	return(1);
491}
492
493/* ARGSUSED */
494FUNC(hw_video_external)
495{
496	struct tctrl_req req;
497	short i;
498
499	READ_ONLY;
500	READ_REQ(0x11, 1, 3);
501	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
502	table[num].value = i&0x0008 ? 1 : 0;
503	return(1);
504}
505
506/* ARGSUSED */
507FUNC(hw_power_battery_int_chargelevel)
508{
509	struct tctrl_req req;
510
511	READ_ONLY;
512	READ_REQ(0x7a, 1, 3);
513	table[num].value = req.rspbuf[0] == 0xfb ? 0 : req.rspbuf[0];
514	return(1);
515
516}
517
518/* ARGSUSED */
519FUNC(hw_power_battery_ext_chargelevel)
520{
521	struct tctrl_req req;
522
523	READ_ONLY;
524	READ_REQ(0x7b, 1, 3);
525	table[num].value = req.rspbuf[0] == 0xfb ? 0 : req.rspbuf[0];
526	return(1);
527}
528
529FUNC(hw_power_battery_int_chargerate)
530{
531	struct tctrl_req req;
532
533	READ_REQ(0x18, 1, 2);
534	table[num].value = req.rspbuf[0];
535	if (readflg)
536		return(1);
537	req.cmdbuf[1] = new < 255 ? new : 255;
538	WRITE_REQ(0x39, 2, 1);
539	READ_REQ(0x18, 1, 2);
540	table[num].value = req.rspbuf[0];
541	return(1);
542}
543
544FUNC(hw_power_battery_ext_chargerate)
545{
546	struct tctrl_req req;
547
548	READ_REQ(0x18, 1, 2);
549	table[num].value = req.rspbuf[0];
550	if (readflg)
551		return(1);
552	req.cmdbuf[1] = new < 255 ? new : 255;
553	WRITE_REQ(0x39, 2, 1);
554	READ_REQ(0x18, 1, 2);
555	table[num].value = req.rspbuf[0];
556	return(1);
557}
558
559/* ARGSUSED */
560FUNC(hw_power_battery_ext)
561{
562	int i;
563	struct tctrl_req req;
564
565	READ_ONLY;
566	READ_REQ(0x11, 1, 3);
567	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
568	table[num].value = i&0x0004 ? 1 : 0;
569	return(1);
570}
571
572/* ARGSUSED */
573FUNC(hw_power_battery_int)
574{
575	int i;
576	struct tctrl_req req;
577
578	READ_ONLY;
579	READ_REQ(0x11, 1, 3);
580	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
581	table[num].value = i&0x0002 ? 1 : 0;
582	return(1);
583}
584
585/* ARGSUSED */
586FUNC(hw_power_mains)
587{
588	int i;
589	struct tctrl_req req;
590
591	READ_ONLY;
592	READ_REQ(0x11, 1, 3);
593	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
594	table[num].value = i&0x0001 ? 1 : 0;
595	return(1);
596}
597
598/* ARGSUSED */
599FUNC(hw_poweroncycles)
600{
601	struct tctrl_req req;
602
603	READ_ONLY;
604	READ_REQ(0x09, 1, 5);
605	table[num].value = (req.rspbuf[0]<<24)+(req.rspbuf[1]<<16)+
606	    (req.rspbuf[2]<<8)+req.rspbuf[3];
607	return(1);
608}
609
610/* ARGSUSED */
611FUNC(hw_poweronseconds)
612{
613	struct tctrl_req req;
614
615	READ_ONLY;
616	READ_REQ(0x0a, 1, 5);
617	table[num].value = (req.rspbuf[0]<<24)+(req.rspbuf[1]<<16)+
618	    (req.rspbuf[2]<<8)+req.rspbuf[3];
619	return(1);
620}
621
622/* ARGSUSED */
623FUNC(hw_microcontroller_version)
624{
625	char buf[BUFSIZ];
626	struct tctrl_req req;
627
628	READ_ONLY;
629	READ_REQ(0x04, 1, 3);
630	snprintf(buf, sizeof(buf), "%d%d", req.rspbuf[0]*1000,
631	    req.rspbuf[1]*10);
632	table[num].value = atoi(strdup(buf));
633	return(1);
634}
635
636
637/* ARGSUSED */
638FUNC(hw_version)
639{
640	char buf[BUFSIZ];
641	struct tctrl_req req;
642
643	READ_ONLY;
644	READ_REQ(0x03, 1, 3);
645	snprintf(buf, sizeof(buf), "%d%d", req.rspbuf[0]*1000,
646	    req.rspbuf[1]*10);
647	table[num].value = atoi(strdup(buf));
648	return(1);
649}
650
651FUNC(hw_serial_power)
652{
653	struct tctrl_pwr pwrreq;
654
655	if (!readflg) {
656		pwrreq.rw = 0x00;
657		pwrreq.state = new;
658		ioctl(dev, TCTRL_SERIAL_PWR, &pwrreq);
659	}
660	pwrreq.rw = 0x01;
661	ioctl(dev, TCTRL_SERIAL_PWR, &pwrreq);
662	table[num].value = pwrreq.state;
663	return(1);
664}
665
666void
667usage()
668{
669	(void)fprintf(stderr,
670	    "usage: tadpolectl [-n] name ...\n"
671	    "       tadpolectl [-n] -w name=value\n"
672	    "       tadpolectl [-n] -a\n");
673	exit(1);
674}
675
676static void
677parse(string)
678	char *string;
679{
680	char *cp, buf[BUFSIZ];
681	int newval = 0;
682	int i, j, ret;
683
684	string = dashdot(string);
685	snprintf(buf, (size_t)BUFSIZ, "%s", string);
686	if ((cp = strchr(string, '=')) != NULL) {
687		if (!wflag)
688			errx(2, "Must specify -w to set variables");
689		*strchr(buf, '=') = '\0';
690		*cp++ = '\0';
691		while (isspace((unsigned char) *cp))
692			cp++;
693		newval = atoi(cp);
694	}
695	for (j=0,i=-1; j < NUM_MIBS; j++) {
696		if (strcmp(string, table[j].mib) == 0) {
697			i = j;
698			break;
699		}
700	}
701	if (i == -1)
702		errx(2, "Named value does not exist");
703
704	if (wflag) {
705		ret = (*table[i].funcptr)(0, newval, i);
706		if (!ret)
707			errx(2, "Cannot modify this value");
708	} else
709		ret = (*table[i].funcptr)(1, 0, i);
710	if (nflag)
711		printf("%d\n", table[i].value);
712	else
713		printf("%s = %d\n", dashdot(table[i].mib), table[i].value);
714}
715
716char *
717dashdot(string)
718	const char *string;
719{
720	char *p;
721	char *save;
722
723	p = strdup(string);
724	save = p;
725
726	for (; (*p = *string) != '\0'; ++p, ++string) {
727		if (*p == '.')
728			*p = '_';
729		else if (*p == '_')
730			*p = '.';
731	}
732	return(save);
733}
734
735int
736main(argc, argv)
737	int argc;
738	char *argv[];
739{
740	int ch, j;
741
742	while ((ch = getopt(argc, argv, "anw")) != -1) {
743		switch (ch) {
744
745		case 'a':
746			aflag = 1;
747			break;
748		case 'n':
749			nflag = 1;
750			break;
751		case 'w':
752			wflag = 1;
753			break;
754		default:
755			usage();
756		}
757	}
758	argc -= optind;
759	argv += optind;
760
761	if ((dev = open(TCTRL_DEV, O_RDONLY, NULL)) == -1)
762		err(1, "%s", TCTRL_DEV);
763
764	if (aflag) {
765		for (j=0; j < NUM_MIBS; j++) {
766			(void)(*table[j].funcptr)(1, 0, j);
767			if (nflag)
768				printf("%d\n", table[j].value);
769			else
770				printf("%s = %d\n", dashdot(table[j].mib),
771				    table[j].value);
772		}
773		return(0);
774	}
775	if (argc == 0)
776		usage();
777	while (argc-- > 0)
778		parse(*argv++);
779	return(0);
780}
781