/*
 * avcstat - Display SELinux avc statistics.
 *
 * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2,
 * as published by the Free Software Foundation.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/limits.h>

#define DEF_STAT_FILE	"/avc/cache_stats"
#define DEF_BUF_SIZE	8192
#define HEADERS		"lookups hits misses allocations reclaims frees"

struct avc_cache_stats {
	unsigned long long lookups;
	unsigned long long hits;
	unsigned long long misses;
	unsigned long long allocations;
	unsigned long long reclaims;
	unsigned long long frees;
};

static int interval;
static int rows;
static char *progname;
static char buf[DEF_BUF_SIZE];

/* selinuxfs mount point */
extern char *selinux_mnt;

static __attribute__((__format__(printf,1,2))) void die(const char *msg, ...)
{
	va_list args;

	fputs("ERROR: ", stderr);

	va_start(args, msg);
	vfprintf(stderr, msg, args);
	va_end(args);

	if (errno)
		fprintf(stderr, ": %s", strerror(errno));

	fputc('\n', stderr);
	exit(1);
}

static void usage(void)
{
	printf("\nUsage: %s [-c] [-f status_file] [interval]\n\n", progname);
	printf
	    ("Display SELinux AVC statistics.  If the interval parameter is specified, the\n");
	printf
	    ("program will loop, displaying updated statistics every \'interval\' seconds.\n");
	printf
	    ("Relative values are displayed by default. Use the -c option to specify the\n");
	printf
	    ("display of cumulative values.  The -f option specifies the location of the\n");
	printf("AVC statistics file, defaulting to \'%s%s\'.\n\n", selinux_mnt,
	       DEF_STAT_FILE);
}

static void set_window_rows(void)
{
	int ret;
	struct winsize ws;

	ret = ioctl(fileno(stdout), TIOCGWINSZ, &ws);
	if (ret < 0 || ws.ws_row < 3)
		ws.ws_row = 24;
	rows = ws.ws_row;
}

static void sighandler(int num)
{
	if (num == SIGWINCH)
		set_window_rows();
}

int main(int argc, char **argv)
{
	struct avc_cache_stats tot, rel, last;
	int fd, i, cumulative = 0;
	struct sigaction sa;
	char avcstatfile[PATH_MAX];
	snprintf(avcstatfile, sizeof avcstatfile, "%s%s", selinux_mnt,
		 DEF_STAT_FILE);
	progname = basename(argv[0]);

	memset(&last, 0, sizeof(last));

	while ((i = getopt(argc, argv, "cf:h?-")) != -1) {
		switch (i) {
		case 'c':
			cumulative = 1;
			break;
		case 'f':
			strncpy(avcstatfile, optarg, sizeof avcstatfile);
			break;
		case 'h':
		case '-':
			usage();
			exit(0);
		default:
			usage();
			die("unrecognized parameter '%c'", i);
		}
	}

	if (optind < argc) {
		char *arg = argv[optind];
		unsigned int n = strtoul(arg, NULL, 10);

		if (errno == ERANGE) {
			usage();
			die("invalid interval \'%s\'", arg);
		}
		if (n == 0) {
			usage();
			exit(0);
		}
		interval = n;
	}

	sa.sa_handler = sighandler;
	sa.sa_flags = SA_RESTART;
	sigemptyset(&sa.sa_mask);

	i = sigaction(SIGWINCH, &sa, NULL);
	if (i < 0)
		die("sigaction");

	set_window_rows();
	fd = open(avcstatfile, O_RDONLY);
	if (fd < 0)
		die("open: \'%s\'", avcstatfile);

	for (i = 0;; i++) {
		char *line;
		ssize_t ret, parsed = 0;

		memset(buf, 0, DEF_BUF_SIZE);
		ret = read(fd, buf, DEF_BUF_SIZE-1);
		if (ret < 0)
			die("read");

		if (ret == 0)
			die("read: \'%s\': unexpected end of file",
			    avcstatfile);

		line = strtok(buf, "\n");
		if (!line)
			die("unable to parse \'%s\': end of line not found",
			    avcstatfile);

		if (strcmp(line, HEADERS))
			die("unable to parse \'%s\': invalid headers",
			    avcstatfile);

		if (!i || !(i % (rows - 2)))
			printf("%10s %10s %10s %10s %10s %10s\n", "lookups",
			       "hits", "misses", "allocs", "reclaims", "frees");

		memset(&tot, 0, sizeof(tot));

		while ((line = strtok(NULL, "\n"))) {
			struct avc_cache_stats tmp;

			ret = sscanf(line, "%llu %llu %llu %llu %llu %llu",
				     &tmp.lookups,
				     &tmp.hits,
				     &tmp.misses,
				     &tmp.allocations,
				     &tmp.reclaims, &tmp.frees);
			if (ret != 6)
				die("unable to parse \'%s\': scan error",
				    avcstatfile);

			tot.lookups += tmp.lookups;
			tot.hits += tmp.hits;
			tot.misses += tmp.misses;
			tot.allocations += tmp.allocations;
			tot.reclaims += tmp.reclaims;
			tot.frees += tmp.frees;
			parsed = 1;
		}

		if (!parsed)
			die("unable to parse \'%s\': no data", avcstatfile);

		if (cumulative || (!cumulative && !i))
			printf("%10Lu %10Lu %10Lu %10Lu %10Lu %10Lu\n",
			       tot.lookups, tot.hits, tot.misses,
			       tot.allocations, tot.reclaims, tot.frees);
		else {
			rel.lookups = tot.lookups - last.lookups;
			rel.hits = tot.hits - last.hits;
			rel.misses = tot.misses - last.misses;
			rel.allocations = tot.allocations - last.allocations;
			rel.reclaims = tot.reclaims - last.reclaims;
			rel.frees = tot.frees - last.frees;
			printf("%10Lu %10Lu %10Lu %10Lu %10Lu %10Lu\n",
			       rel.lookups, rel.hits, rel.misses,
			       rel.allocations, rel.reclaims, rel.frees);
		}

		if (!interval)
			break;

		memcpy(&last, &tot, sizeof(last));
		sleep(interval);

		ret = lseek(fd, 0, 0);
		if (ret < 0)
			die("lseek");
	}

	close(fd);
	return 0;
}
