Blame kacpimon/kacpimon.c

Packit Service 26469c
/*
Packit Service 26469c
 *  kacpimon - Kernel ACPI Event Monitor
Packit Service 26469c
 *
Packit Service 26469c
 *  Monitors kernel ACPI events from multiple interfaces and reports them
Packit Service 26469c
 *  to the console.
Packit Service 26469c
 *
Packit Service 26469c
 *  Inspired by (and in some cases blatantly lifted from) Vojtech Pavlik's
Packit Service 26469c
 *  evtest.c, Zhang Rui's acpi_genl, and Alexey Kuznetsov's libnetlink.
Packit Service 26469c
 *
Packit Service 26469c
 *  Copyright (C) 2008, Ted Felix (www.tedfelix.com)
Packit Service 26469c
 *
Packit Service 26469c
 *  This program is free software; you can redistribute it and/or modify
Packit Service 26469c
 *  it under the terms of the GNU General Public License as published by
Packit Service 26469c
 *  the Free Software Foundation; either version 2 of the License, or
Packit Service 26469c
 *  (at your option) any later version.
Packit Service 26469c
 *
Packit Service 26469c
 *  This program is distributed in the hope that it will be useful,
Packit Service 26469c
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 26469c
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 26469c
 *  GNU General Public License for more details.
Packit Service 26469c
 *
Packit Service 26469c
 *  You should have received a copy of the GNU General Public License
Packit Service 26469c
 *  along with this program; if not, write to the Free Software
Packit Service 26469c
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit Service 26469c
 *
Packit Service 26469c
 *  (tabs at 4)
Packit Service 26469c
 */
Packit Service 26469c
Packit Service 26469c
/* system */
Packit Service 26469c
#include <stdio.h>
Packit Service 26469c
#include <unistd.h>
Packit Service 26469c
#include <fcntl.h>
Packit Service 26469c
#include <sys/select.h>
Packit Service 26469c
#include <string.h>
Packit Service 26469c
#include <errno.h>
Packit Service 26469c
#include <malloc.h>
Packit Service 26469c
Packit Service 26469c
/* local */
Packit Service 26469c
#include "libnetlink.h"
Packit Service 26469c
#include "genetlink.h"
Packit Service 26469c
#include "acpi_genetlink.h"
Packit Service 26469c
Packit Service 26469c
#include "acpi_ids.h"
Packit Service 26469c
#include "connection_list.h"
Packit Service 26469c
#include "input_layer.h"
Packit Service 26469c
#include "netlink.h"
Packit Service 26469c
Packit Service 26469c
#include "kacpimon.h"
Packit Service 26469c
Packit Service 26469c
/* ??? Isn't this in a system header someplace? */
Packit Service 26469c
#define max(a, b)  (((a)>(b))?(a):(b))
Packit Service 26469c
Packit Service 26469c
/*********************************************************************/
Packit Service 26469c
Packit Service 26469c
/* Exit flag that can be set by any of the functions to cause the */
Packit Service 26469c
/* program to exit.  */
Packit Service 26469c
int exitflag = 0;
Packit Service 26469c
Packit Service 26469c
/****************************************************************
Packit Service 26469c
 *  Old /proc/acpi/event interface
Packit Service 26469c
 ****************************************************************/
Packit Service 26469c
Packit Service 26469c
static void process_proc(int fd)
Packit Service 26469c
{
Packit Service 26469c
	const int buffsize = 1024;
Packit Service 26469c
	char buffer[buffsize];
Packit Service 26469c
	ssize_t nbytes;
Packit Service 26469c
Packit Service 26469c
	for (;;)
Packit Service 26469c
	{
Packit Service 26469c
		nbytes = read(fd, buffer, buffsize - 1);
Packit Service 26469c
Packit Service 26469c
		/* ??? Do we need to worry about partial messages? */
Packit Service 26469c
		
Packit Service 26469c
		/* If there are no data to read, bail. */
Packit Service 26469c
		if (nbytes <= 0)
Packit Service 26469c
			break;
Packit Service 26469c
Packit Service 26469c
		/* Ensure we have a zero terminator */
Packit Service 26469c
		buffer[nbytes] = 0;
Packit Service 26469c
		
Packit Service 26469c
		printf("/proc/acpi/event: %s", buffer);
Packit Service 26469c
	}
Packit Service 26469c
}
Packit Service 26469c
Packit Service 26469c
// ---------------------------------------------------------------
Packit Service 26469c
Packit Service 26469c
static void open_proc(void)
Packit Service 26469c
{
Packit Service 26469c
	char *filename = "/proc/acpi/event";
Packit Service 26469c
	int fd;
Packit Service 26469c
	struct connection c;
Packit Service 26469c
Packit Service 26469c
	fd = open(filename, O_RDONLY | O_NONBLOCK);
Packit Service 26469c
	if (fd >= 0)
Packit Service 26469c
	{
Packit Service 26469c
		printf("%s opened successfully\n", filename);
Packit Service 26469c
Packit Service 26469c
		/* Add a connection to the list. */
Packit Service 26469c
		c.fd = fd;
Packit Service 26469c
		c.process = process_proc;
Packit Service 26469c
		add_connection(&c);
Packit Service 26469c
	}
Packit Service 26469c
	else
Packit Service 26469c
	{
Packit Service 26469c
		int errno2 = errno;
Packit Service 26469c
		printf("open for %s: %s (%d)\n", 
Packit Service 26469c
			filename, strerror(errno2), errno2);
Packit Service 26469c
		if (errno2 == EACCES)
Packit Service 26469c
			printf("  (try running as root)\n");
Packit Service 26469c
		if (errno2 == ENOENT)
Packit Service 26469c
			printf("  (ACPI proc filesystem may not be present)\n");
Packit Service 26469c
		if (errno2 == EBUSY)
Packit Service 26469c
			printf("  (ACPI proc filesystem is in use.  "
Packit Service 26469c
				"You might need to kill acpid.)\n");
Packit Service 26469c
	}
Packit Service 26469c
}
Packit Service 26469c
Packit Service 26469c
/****************************************************************
Packit Service 26469c
 *  Main Program Functions
Packit Service 26469c
 ****************************************************************/
Packit Service 26469c
Packit Service 26469c
static void monitor(void)
Packit Service 26469c
{
Packit Service 26469c
	while (exitflag == 0)
Packit Service 26469c
	{
Packit Service 26469c
		fd_set readfds;
Packit Service 26469c
		int nready;
Packit Service 26469c
		int i;
Packit Service 26469c
Packit Service 26469c
		/* It's going to get clobbered, so use a copy. */
Packit Service 26469c
		readfds = *get_fdset();
Packit Service 26469c
Packit Service 26469c
		/* Wait on data. */
Packit Service 26469c
		nready = select(get_highestfd() + 1, &readfds, NULL, NULL, NULL);
Packit Service 26469c
Packit Service 26469c
		/* If something goes wrong, bail. */
Packit Service 26469c
		if (nready <= 0)
Packit Service 26469c
			break;
Packit Service 26469c
Packit Service 26469c
		/* For each connection */
Packit Service 26469c
		for (i = 0; i <= get_number_of_connections(); ++i)
Packit Service 26469c
		{
Packit Service 26469c
			int fd;
Packit Service 26469c
			struct connection *p;
Packit Service 26469c
Packit Service 26469c
			p = get_connection(i);
Packit Service 26469c
Packit Service 26469c
			/* If this connection is invalid, bail. */
Packit Service 26469c
			if (!p)
Packit Service 26469c
				break;
Packit Service 26469c
Packit Service 26469c
			/* Get the file descriptor */
Packit Service 26469c
			fd = p -> fd;
Packit Service 26469c
Packit Service 26469c
			/* If this file descriptor has data waiting, */
Packit Service 26469c
			if (FD_ISSET(fd, &readfds))
Packit Service 26469c
			{
Packit Service 26469c
				p->process(fd);
Packit Service 26469c
			}
Packit Service 26469c
		}
Packit Service 26469c
	}
Packit Service 26469c
}
Packit Service 26469c
Packit Service 26469c
// ---------------------------------------------------------------
Packit Service 26469c
Packit Service 26469c
static void close_all(void)
Packit Service 26469c
{
Packit Service 26469c
	int i = 0;
Packit Service 26469c
Packit Service 26469c
	/* For each connection */
Packit Service 26469c
	for (i = 0; i <= get_number_of_connections(); ++i)
Packit Service 26469c
	{
Packit Service 26469c
		struct connection *p;
Packit Service 26469c
Packit Service 26469c
		p = get_connection(i);
Packit Service 26469c
Packit Service 26469c
		/* If this connection is invalid, try the next. */
Packit Service 26469c
		if (p == 0)
Packit Service 26469c
			continue;
Packit Service 26469c
Packit Service 26469c
		close(p -> fd);
Packit Service 26469c
	}
Packit Service 26469c
}
Packit Service 26469c
Packit Service 26469c
// ---------------------------------------------------------------
Packit Service 26469c
Packit Service 26469c
int main(void)
Packit Service 26469c
{
Packit Service 26469c
	printf("Kernel ACPI Event Monitor...\n");
Packit Service 26469c
Packit Service 26469c
	open_proc();
Packit Service 26469c
	open_input();
Packit Service 26469c
	open_netlink();
Packit Service 26469c
Packit Service 26469c
	printf("Press Escape to exit, or Ctrl-C if that doesn't work.\n");
Packit Service 26469c
Packit Service 26469c
	monitor();
Packit Service 26469c
Packit Service 26469c
	printf("Closing files...\n");
Packit Service 26469c
Packit Service 26469c
	close_all();
Packit Service 26469c
Packit Service 26469c
	printf("Goodbye\n");
Packit Service 26469c
Packit Service 26469c
	return 0;
Packit Service 26469c
}