/*
 * 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 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", 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;

	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);
		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;
}
