summaryrefslogtreecommitdiffstats
path: root/usr.sbin/apm/apm.c
blob: 2781a610a8303deef7beddf9296ccf1827759ae7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * LP (Laptop Package)
 *
 * Copyright (C) 1994 by HOSOKAWA Tatasumi <hosokawa@mt.cs.keio.ac.jp>
 *
 * This software may be used, modified, copied, distributed, and sold,
 * in both source and binary form provided that the above copyright and
 * these terms are retained. Under no circumstances is the author
 * responsible for the proper functioning of this software, nor does
 * the author assume any responsibility for damages incurred with its
 * use.
 *
 * Sep., 1994	Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
 */

#include <stdio.h>
#include <string.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <machine/apm_bios.h>

#define APMDEV	"/dev/apm0"

int main_argc;
char **main_argv;

void apm_suspend(int fd)
{
	if (ioctl(fd, APMIO_SUSPEND, NULL) == -1) {
		fprintf(stderr, "%s: ioctl APMIO_SUSPEND failed.\n", main_argv[0]);
		exit(1);
	}
}

void apm_getinfo(int fd, apm_info_t aip)
{
	if (ioctl(fd, APMIO_GETINFO, aip) == -1) {
		fprintf(stderr, "%s: ioctl APMIO_GETINFO failed.\n", main_argv[0]);
		exit(1);
	}
}

void print_all_info(apm_info_t aip)
{
	printf("APM version: %d.%d\n", aip->ai_major, aip->ai_minor);
	printf("AC Line status: ");
	if (aip->ai_acline == 255) {
		printf("unknown");
	}
	else if (aip->ai_acline > 1) {
		printf("invalid value (0x%x)", aip->ai_acline);
	}
	else {
		static char messages[][10] = {"off-line", "on-line"};
		printf("%s", messages[aip->ai_acline]);
	}
	printf("\n");
	printf("Battery status: ");
	if (aip->ai_batt_stat == 255) {
		printf("unknown");
	}
	else if (aip->ai_batt_stat > 3) {
		printf("invalid value (0x%x)", aip->ai_batt_stat);
	}
	else {
		static char messages[][10] = {"high", "low", "critical", "charging"};
		printf("%s", messages[aip->ai_batt_stat]);
	}
	printf("\n");
	printf("Remaining battery life: ");
	if (aip->ai_batt_life == 255) {
		printf("unknown");
	}
	else if (aip->ai_batt_life <= 100) {
		printf("%d%%", aip->ai_batt_life);
	}
	else {
		printf("invalid value (0x%x)", aip->ai_batt_life);
	}
	printf("\n");
}

int main(int argc, char *argv[])
{
	int i, j, fd;
	int sleep = 0, all_info = 1, batt_status = 0, batt_life = 0, ac_status = 0;
	char *cmdname;

	main_argc = argc;
	main_argv = argv;
	if ((cmdname = strrchr(argv[0], '/')) != NULL) {
		cmdname++;
	}
	else {
		cmdname = argv[0];
	}

	if (strcmp(cmdname, "zzz") == 0) {
		sleep = 1;
		all_info = 0;
		goto finish_option;
	}

	for (i = argc - 1; i >= 1; i--) {
		if (argv[i][0] != '-') {
			fprintf(stderr, "%s: Unknown option '%s'.\n", argv[0], argv[i]);
			exit(1);
		}
		for (j = 1; argv[i][j]; j++) {
			switch (argv[i][j]) {
			case 'z':
				sleep = 1;
				all_info = 0;
				break;
			case 'b':
				batt_status = 1;
				all_info = 0;
				break;
			case 'a':
				ac_status = 1;
				all_info = 0;
				break;
			case 'l':
				batt_life = 1;
				all_info = 0;
				break;
			default:
				fprintf(stderr, "%s Unknown option '%s'.\n", argv[0], argv[i]);
				exit(1);
			}
		}
	}
finish_option:
	fd = open(APMDEV, O_RDWR);
	if (fd == -1) {
		fprintf(stderr, "%s: Can't open %s.\n", argv[0], APMDEV);
		return 1;
	}
	if (sleep) {
		apm_suspend(fd);
	}
	else {
		struct apm_info	info;

		apm_getinfo(fd, &info);
		if (all_info) {
			print_all_info(&info);
		}
		if (batt_status) {
			printf("%d\n", info.ai_batt_stat);
		}
		if (batt_life) {
			printf("%d\n", info.ai_batt_life);
		}
		if (ac_status) {
			printf("%d\n", info.ai_acline);
		}
	}
	close(fd);
	return 0;
}
OpenPOWER on IntegriCloud