apm.c revision 3259
1/*
2 * LP (Laptop Package)
3 *
4 * Copyright (C) 1994 by HOSOKAWA Tatasumi <hosokawa@mt.cs.keio.ac.jp>
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 <stdio.h>
17#include <string.h>
18#include <sys/file.h>
19#include <sys/ioctl.h>
20#include <machine/apm_bios.h>
21
22#define APMDEV	"/dev/apm"
23
24int main_argc;
25char **main_argv;
26
27void apm_suspend(int fd)
28{
29	if (ioctl(fd, APMIO_SUSPEND, NULL) == -1) {
30		fprintf(stderr, "%s: ioctl APMIO_SUSPEND failed.\n", main_argv[0]);
31		exit(1);
32	}
33}
34
35void apm_getinfo(int fd, apm_info_t aip)
36{
37	if (ioctl(fd, APMIO_GETINFO, aip) == -1) {
38		fprintf(stderr, "%s: ioctl APMIO_GETINFO failed.\n", main_argv[0]);
39		exit(1);
40	}
41}
42
43void print_all_info(apm_info_t aip)
44{
45	printf("APM version: %d.%d\n", aip->ai_major, aip->ai_minor);
46	printf("AC Line status: ");
47	if (aip->ai_acline == 255) {
48		printf("unknown");
49	}
50	else if (aip->ai_acline > 1) {
51		printf("invalid value (0x%x)", aip->ai_acline);
52	}
53	else {
54		static char messages[][10] = {"off-line", "on-line"};
55		printf("%s", messages[aip->ai_acline]);
56	}
57	printf("\n");
58	printf("Battery status: ");
59	if (aip->ai_batt_stat == 255) {
60		printf("unknown");
61	}
62	else if (aip->ai_batt_stat > 3) {
63		printf("invalid value (0x%x)", aip->ai_batt_stat);
64	}
65	else {
66		static char messages[][10] = {"high", "low", "critical", "charging"};
67		printf("%s", messages[aip->ai_batt_stat]);
68	}
69	printf("\n");
70	printf("Remaining battery life: ");
71	if (aip->ai_batt_life == 255) {
72		printf("unknown");
73	}
74	else if (aip->ai_batt_life <= 100) {
75		printf("%d%%", aip->ai_batt_life);
76	}
77	else {
78		printf("invalid value (0x%x)", aip->ai_batt_life);
79	}
80	printf("\n");
81}
82
83int main(int argc, char *argv[])
84{
85	int i, j, fd;
86	int sleep = 0, all_info = 1, batt_status = 0, batt_life = 0, ac_status = 0;
87	char *cmdname;
88
89	main_argc = argc;
90	main_argv = argv;
91	if ((cmdname = strrchr(argv[0], '/')) != NULL) {
92		cmdname++;
93	}
94	else {
95		cmdname = argv[0];
96	}
97
98	if (strcmp(cmdname, "zzz") == 0) {
99		sleep = 1;
100		all_info = 0;
101		goto finish_option;
102	}
103
104	for (i = argc - 1; i >= 1; i--) {
105		if (argv[i][0] != '-') {
106			fprintf(stderr, "%s: Unknown option '%s'.", argv[0], argv[i]);
107		}
108		for (j = 1; argv[i][j]; j++) {
109			switch (argv[i][j]) {
110			case 'z':
111				sleep = 1;
112				all_info = 0;
113				break;
114			case 'b':
115				batt_status = 1;
116				all_info = 0;
117				break;
118			case 'a':
119				ac_status = 1;
120				all_info = 0;
121				break;
122			case 'l':
123				batt_life = 1;
124				all_info = 0;
125				break;
126			}
127		}
128	}
129finish_option:
130	fd = open(APMDEV, O_RDWR);
131	if (fd == -1) {
132		fprintf(stderr, "%s: Can't open %s.\n", argv[0], APMDEV);
133		return 1;
134	}
135	if (sleep) {
136		apm_suspend(fd);
137	}
138	else {
139		struct apm_info	info;
140
141		apm_getinfo(fd, &info);
142		if (all_info) {
143			print_all_info(&info);
144		}
145		if (batt_status) {
146			printf("%d\n", info.ai_batt_stat);
147		}
148		if (batt_life) {
149			printf("%d\n", info.ai_batt_life);
150		}
151		if (ac_status) {
152			printf("%d\n", info.ai_acline);
153		}
154	}
155	close(fd);
156	return 0;
157}
158