apm.c revision 21363
13259Sdg/*
221363Snate * apm / zzz	APM BIOS utility for FreeBSD
33259Sdg *
421363Snate * Copyright (C) 1994-1996 by HOSOKAWA Tatasumi <hosokawa@mt.cs.keio.ac.jp>
53259Sdg *
63259Sdg * This software may be used, modified, copied, distributed, and sold,
73259Sdg * in both source and binary form provided that the above copyright and
88857Srgrimes * these terms are retained. Under no circumstances is the author
98857Srgrimes * responsible for the proper functioning of this software, nor does
108857Srgrimes * the author assume any responsibility for damages incurred with its
113259Sdg * use.
123259Sdg *
133259Sdg * Sep., 1994	Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
143259Sdg */
153259Sdg
163259Sdg#include <stdio.h>
1721363Snate#include <stdlib.h>
183259Sdg#include <string.h>
193259Sdg#include <sys/file.h>
203259Sdg#include <sys/ioctl.h>
2121363Snate#include <unistd.h>
224075Sphk#include <machine/apm_bios.h>
233259Sdg
2414674Snate#define APMDEV	"/dev/apm"
253259Sdg
2621363Snatestatic char *cmdname;
273259Sdg
2821363Snatevoid
2921363Snateusage()
303259Sdg{
3121363Snate	fprintf(stderr, "usage: %s [-ablsz] [-d 1|0]\n", cmdname);
3221363Snate	exit(1);
3321363Snate}
3421363Snate
3521363Snatevoid
3621363Snateapm_suspend(int fd)
3721363Snate{
383259Sdg	if (ioctl(fd, APMIO_SUSPEND, NULL) == -1) {
3921363Snate		perror(cmdname);
403259Sdg		exit(1);
413259Sdg	}
423259Sdg}
433259Sdg
4421363Snatevoid
4521363Snateapm_getinfo(int fd, apm_info_t aip)
463259Sdg{
473259Sdg	if (ioctl(fd, APMIO_GETINFO, aip) == -1) {
4821363Snate		perror(cmdname);
493259Sdg		exit(1);
503259Sdg	}
513259Sdg}
523259Sdg
5321363Snatevoid
5421363Snateprint_all_info(apm_info_t aip)
553259Sdg{
563259Sdg	printf("APM version: %d.%d\n", aip->ai_major, aip->ai_minor);
5721363Snate	printf("APM Managment: %s\n", (aip->ai_status ? "Enabled" : "Disabled"));
583259Sdg	printf("AC Line status: ");
5921363Snate	if (aip->ai_acline == 255)
603259Sdg		printf("unknown");
6121363Snate	else if (aip->ai_acline > 1)
623259Sdg		printf("invalid value (0x%x)", aip->ai_acline);
633259Sdg	else {
643259Sdg		static char messages[][10] = {"off-line", "on-line"};
653259Sdg		printf("%s", messages[aip->ai_acline]);
663259Sdg	}
673259Sdg	printf("\n");
683259Sdg	printf("Battery status: ");
6921363Snate	if (aip->ai_batt_stat == 255)
703259Sdg		printf("unknown");
7121363Snate	else if (aip->ai_batt_stat > 3)
7221363Snate			printf("invalid value (0x%x)", aip->ai_batt_stat);
733259Sdg	else {
7421363Snate		char messages[][10] = {"high", "low", "critical", "charging"};
753259Sdg		printf("%s", messages[aip->ai_batt_stat]);
763259Sdg	}
773259Sdg	printf("\n");
783259Sdg	printf("Remaining battery life: ");
7921363Snate	if (aip->ai_batt_life == 255)
803259Sdg		printf("unknown");
8121363Snate	else if (aip->ai_batt_life <= 100)
8221363Snate			printf("%d%%", aip->ai_batt_life);
8321363Snate	else
843259Sdg		printf("invalid value (0x%x)", aip->ai_batt_life);
853259Sdg	printf("\n");
863259Sdg}
873259Sdg
8821363Snate
8921363Snate/*
9021363Snate * currently, it can turn off the display, but the display never comes
9121363Snate * back until the machine suspend/resumes :-).
9221363Snate */
9321363Snatevoid
9421363Snateapm_display(int fd, int newstate)
953259Sdg{
9621363Snate	if (ioctl(fd, APMIO_DISPLAY, &newstate) == -1) {
9721363Snate		perror(cmdname);
9821363Snate		exit(1);
9921363Snate	}
10021363Snate}
1018857Srgrimes
10221363Snate
10321363Snateextern char *optarg;
10421363Snateextern int optind;
10521363Snate
10621363Snateint
10721363Snatemain(int argc, char *argv[])
10821363Snate{
10921363Snate	int	c, fd;
11021363Snate	int     sleep = 0, all_info = 1, apm_status = 0, batt_status = 0;
11121363Snate	int     display = 0, batt_life = 0, ac_status = 0;
11221363Snate
11321363Snate	if ((cmdname = strrchr(argv[0], '/')) != NULL)
1143259Sdg		cmdname++;
11521363Snate	else
1163259Sdg		cmdname = argv[0];
1173259Sdg
1183259Sdg	if (strcmp(cmdname, "zzz") == 0) {
1193259Sdg		sleep = 1;
1203259Sdg		all_info = 0;
1213259Sdg		goto finish_option;
1223259Sdg	}
12321363Snate	while ((c = getopt(argc, argv, "ablszd:")) != EOF) {
12421363Snate		switch (c) {
12521363Snate		case 'a':
12621363Snate			ac_status = 1;
12721363Snate			all_info = 0;
12821363Snate			break;
12921363Snate		case 'b':
13021363Snate			batt_status = 1;
13121363Snate			all_info = 0;
13221363Snate			break;
13321363Snate		case 'd':
13421363Snate			display = *optarg - '0';
13521363Snate			if (display < 0 || display > 1) {
13621363Snate				fprintf(stderr, "%s: Argument of option '-%c' is invalid.\n", cmdname, c);
13721363Snate				usage();
1383259Sdg			}
13921363Snate			display++;
14021363Snate			all_info = 0;
14121363Snate			break;
14221363Snate		case 'l':
14321363Snate			batt_life = 1;
14421363Snate			all_info = 0;
14521363Snate			break;
14621363Snate		case 's':
14721363Snate			apm_status = 1;
14821363Snate			all_info = 0;
14921363Snate			break;
15021363Snate		case 'z':
15121363Snate			sleep = 1;
15221363Snate			all_info = 0;
15321363Snate			break;
15421363Snate		case '?':
15521363Snate		default:
15621363Snate			usage();
1573259Sdg		}
15821363Snate		argc -= optind;
15921363Snate		argv += optind;
1603259Sdg	}
1613259Sdgfinish_option:
1623259Sdg	fd = open(APMDEV, O_RDWR);
1633259Sdg	if (fd == -1) {
16421363Snate		fprintf(stderr, "%s: Can't open %s.\n", cmdname, APMDEV);
1653259Sdg		return 1;
1663259Sdg	}
16721363Snate	if (sleep)
1683259Sdg		apm_suspend(fd);
16921363Snate	else {
17021363Snate		struct apm_info info;
1713259Sdg
1723259Sdg		apm_getinfo(fd, &info);
17321363Snate		if (all_info)
1743259Sdg			print_all_info(&info);
17521363Snate		if (batt_status)
1763259Sdg			printf("%d\n", info.ai_batt_stat);
17721363Snate		if (batt_life)
1783259Sdg			printf("%d\n", info.ai_batt_life);
17921363Snate		if (ac_status)
1803259Sdg			printf("%d\n", info.ai_acline);
18121363Snate		if (apm_status)
18214609Snate			printf("%d\n", info.ai_status);
18321363Snate		if (display)
18421363Snate			apm_display(fd, display - 1);
1853259Sdg	}
1863259Sdg	close(fd);
1873259Sdg	return 0;
1883259Sdg}
189