xref: /freebsd/usr.sbin/apm/apm.c (revision f9bc005b8ef3b507a5ecbc2d7fe4411ef70eff38)
1 /*
2  * APM BIOS utility for FreeBSD
3  *
4  * Copyright (C) 1994-1996 by Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org>
5  *
6  * This software may be used, modified, copied, distributed, and sold,
7  * in both source and binary form provided that the above copyright and
8  * these terms are retained. Under no circumstances is the author
9  * responsible for the proper functioning of this software, nor does
10  * the author assume any responsibility for damages incurred with its
11  * use.
12  *
13  * Sep., 1994	Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
14  */
15 
16 #include <sys/ioctl.h>
17 
18 #include <machine/apm_bios.h>
19 
20 #include <err.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 
27 #define APMDEV	"/dev/apm"
28 
29 #define APM_UNKNOWN	255
30 
31 static void
32 usage(void)
33 {
34 	fprintf(stderr,
35 		"usage: apm [-abltzZ]\n");
36 	exit(1);
37 }
38 
39 static void
40 apm_suspend(int fd)
41 {
42 	if (ioctl(fd, APMIO_SUSPEND, NULL) == -1)
43 		err(1, "ioctl(APMIO_SUSPEND)");
44 }
45 
46 static void
47 apm_standby(int fd)
48 {
49 	if (ioctl(fd, APMIO_STANDBY, NULL) == -1)
50 		err(1, "ioctl(APMIO_STANDBY)");
51 }
52 
53 static void
54 apm_getinfo(int fd, apm_info_t aip)
55 {
56 	if (ioctl(fd, APMIO_GETINFO, aip) == -1)
57 		err(1, "ioctl(APMIO_GETINFO)");
58 }
59 
60 static void
61 print_batt_time(int batt_time)
62 {
63 	printf("Remaining battery time: ");
64 	if (batt_time == -1)
65 		printf("unknown\n");
66 	else {
67 		int h, m, s;
68 
69 		h = batt_time;
70 		s = h % 60;
71 		h /= 60;
72 		m = h % 60;
73 		h /= 60;
74 		printf("%2d:%02d:%02d\n", h, m, s);
75 	}
76 }
77 
78 static void
79 print_batt_life(u_int batt_life)
80 {
81 	printf("Remaining battery life: ");
82 	if (batt_life == APM_UNKNOWN)
83 		printf("unknown\n");
84 	else if (batt_life <= 100)
85 		printf("%d%%\n", batt_life);
86 	else
87 		printf("invalid value (0x%x)\n", batt_life);
88 }
89 
90 static void
91 print_batt_stat(u_int batt_stat)
92 {
93 	const char *batt_msg[] = { "high", "low", "critical", "charging" };
94 
95 	printf("Battery Status: ");
96 	if (batt_stat == APM_UNKNOWN)
97 		printf("unknown\n");
98 	else if (batt_stat > 3)
99 		printf("invalid value (0x%x)\n", batt_stat);
100 	else
101 		printf("%s\n", batt_msg[batt_stat]);
102 }
103 
104 static void
105 print_all_info(int fd, apm_info_t aip)
106 {
107 	const char *line_msg[] = { "off-line", "on-line" , "backup power"};
108 
109 	printf("APM version: %d.%d\n", aip->ai_major, aip->ai_minor);
110 	printf("APM Management: %s\n", aip->ai_status ? "Enabled" : "Disabled");
111 	printf("AC Line status: ");
112 	if (aip->ai_acline == APM_UNKNOWN)
113 		printf("unknown\n");
114 	else if (aip->ai_acline > 2)
115 		printf("invalid value (0x%x)\n", aip->ai_acline);
116 	else
117 		printf("%s\n", line_msg[aip->ai_acline]);
118 
119 	print_batt_stat(aip->ai_batt_stat);
120 	print_batt_life(aip->ai_batt_life);
121 	print_batt_time(aip->ai_batt_time);
122 
123 	if (aip->ai_infoversion >= 1) {
124 		printf("Number of batteries: ");
125 		if (aip->ai_batteries == ~0U)
126 			printf("unknown\n");
127 		else {
128 			u_int i;
129 			struct apm_pwstatus aps;
130 
131 			printf("%d\n", aip->ai_batteries);
132 			for (i = 0; i < aip->ai_batteries; ++i) {
133 				bzero(&aps, sizeof(aps));
134 				aps.ap_device = PMDV_BATT0 + i;
135 				if (ioctl(fd, APMIO_GETPWSTATUS, &aps) == -1)
136 					continue;
137 				printf("Battery %d:\n", i);
138 				if (aps.ap_batt_flag & APM_BATT_NOT_PRESENT) {
139 					printf("not present\n");
140 					continue;
141 				}
142 				printf("\t");
143 				print_batt_stat(aps.ap_batt_stat);
144 				printf("\t");
145 				print_batt_life(aps.ap_batt_life);
146 				printf("\t");
147 				print_batt_time(aps.ap_batt_time);
148 			}
149 		}
150 	}
151 
152 	if (aip->ai_infoversion >= 1) {
153 		if (aip->ai_capabilities == 0xff00)
154 		    return;
155 		printf("APM Capabilities:\n");
156 		if (aip->ai_capabilities & 0x01)
157 			printf("\tglobal standby state\n");
158 		if (aip->ai_capabilities & 0x02)
159 			printf("\tglobal suspend state\n");
160 		if (aip->ai_capabilities & 0x04)
161 			printf("\tresume timer from standby\n");
162 		if (aip->ai_capabilities & 0x08)
163 			printf("\tresume timer from suspend\n");
164 		if (aip->ai_capabilities & 0x10)
165 			printf("\tRI resume from standby\n");
166 		if (aip->ai_capabilities & 0x20)
167 			printf("\tRI resume from suspend\n");
168 		if (aip->ai_capabilities & 0x40)
169 			printf("\tPCMCIA RI resume from standby\n");
170 		if (aip->ai_capabilities & 0x80)
171 			printf("\tPCMCIA RI resume from suspend\n");
172 	}
173 
174 }
175 
176 int
177 main(int argc, char *argv[])
178 {
179 	int	c, fd;
180 	int     dosleep = 0, all_info = 1, batt_status = 0;
181 	int     batt_life = 0, ac_status = 0, standby = 0;
182 	int	batt_time = 0;
183 
184 	while ((c = getopt(argc, argv, "abltzZ")) != -1) {
185 		switch (c) {
186 		case 'a':
187 			ac_status = 1;
188 			all_info = 0;
189 			break;
190 		case 'b':
191 			batt_status = 1;
192 			all_info = 0;
193 			break;
194 		case 'l':
195 			batt_life = 1;
196 			all_info = 0;
197 			break;
198 		case 't':
199 			batt_time = 1;
200 			all_info = 0;
201 			break;
202 		case 'z':
203 			dosleep = 1;
204 			all_info = 0;
205 			break;
206 		case 'Z':
207 			standby = 1;
208 			all_info = 0;
209 			break;
210 		case '?':
211 		default:
212 			usage();
213 		}
214 		argc -= optind;
215 		argv += optind;
216 	}
217 	if (dosleep || standby)
218 		fd = open(APMDEV, O_RDWR);
219 	else
220 		fd = open(APMDEV, O_RDONLY);
221 	if (fd == -1)
222 		err(1, "can't open %s", APMDEV);
223 	if (dosleep)
224 		apm_suspend(fd);
225 	else if (standby)
226 		apm_standby(fd);
227 	else {
228 		struct apm_info info;
229 
230 		apm_getinfo(fd, &info);
231 		if (all_info)
232 			print_all_info(fd, &info);
233 		if (ac_status)
234 			printf("%d\n", info.ai_acline);
235 		if (batt_status)
236 			printf("%d\n", info.ai_batt_stat);
237 		if (batt_life)
238 			printf("%d\n", info.ai_batt_life);
239 		if (batt_time)
240 			printf("%d\n", info.ai_batt_time);
241 	}
242 	close(fd);
243 	exit(0);
244 }
245