xref: /freebsd/usr.sbin/apm/apm.c (revision a316b26e50bbed7cf655fbba726ab87d8ab7599d)
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/apm0"
23 
24 int main_argc;
25 char **main_argv;
26 
27 void 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 
35 void 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 
43 void 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 
83 int 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'.\n", argv[0], argv[i]);
107 			exit(1);
108 		}
109 		for (j = 1; argv[i][j]; j++) {
110 			switch (argv[i][j]) {
111 			case 'z':
112 				sleep = 1;
113 				all_info = 0;
114 				break;
115 			case 'b':
116 				batt_status = 1;
117 				all_info = 0;
118 				break;
119 			case 'a':
120 				ac_status = 1;
121 				all_info = 0;
122 				break;
123 			case 'l':
124 				batt_life = 1;
125 				all_info = 0;
126 				break;
127 			default:
128 				fprintf(stderr, "%s Unknown option '%s'.\n", argv[0], argv[i]);
129 				exit(1);
130 			}
131 		}
132 	}
133 finish_option:
134 	fd = open(APMDEV, O_RDWR);
135 	if (fd == -1) {
136 		fprintf(stderr, "%s: Can't open %s.\n", argv[0], APMDEV);
137 		return 1;
138 	}
139 	if (sleep) {
140 		apm_suspend(fd);
141 	}
142 	else {
143 		struct apm_info	info;
144 
145 		apm_getinfo(fd, &info);
146 		if (all_info) {
147 			print_all_info(&info);
148 		}
149 		if (batt_status) {
150 			printf("%d\n", info.ai_batt_stat);
151 		}
152 		if (batt_life) {
153 			printf("%d\n", info.ai_batt_life);
154 		}
155 		if (ac_status) {
156 			printf("%d\n", info.ai_acline);
157 		}
158 	}
159 	close(fd);
160 	return 0;
161 }
162