#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <search.h>
#include <sepol/sepol.h>
#include <sepol/policydb/policydb.h>

#define TABLE_SIZE 1024
#define KVP_NUM_OF_RULES (sizeof(rules) / sizeof(key_map))
#define log_set_verbose() do { logging_verbose = 1; log_info("Enabling verbose\n"); } while(0)
#define log_error(fmt, ...) log_msg(stderr, "Error: ", fmt, ##__VA_ARGS__)
#define log_warn(fmt, ...) log_msg(stderr, "Warning: ", fmt, ##__VA_ARGS__)
#define log_info(fmt, ...) if (logging_verbose ) { log_msg(stdout, "Info: ", fmt, ##__VA_ARGS__); }

typedef struct line_order_list line_order_list;
typedef struct hash_entry hash_entry;
typedef enum key_dir key_dir;
typedef enum data_type data_type;
typedef enum rule_map_switch rule_map_switch;
typedef enum map_match map_match;
typedef struct key_map key_map;
typedef struct kvp kvp;
typedef struct rule_map rule_map;
typedef struct policy_info policy_info;

enum map_match {
	map_no_matches,
	map_input_matched,
	map_matched
};

/**
 * Whether or not the "key" from a key vaue pair is considered an
 * input or an output.
 */
enum key_dir {
	dir_in, dir_out
};

/**
 * Used as options to rule_map_free()
 *
 * This is needed to get around the fact that GNU C's hash_map doesn't copy the key, so
 * we cannot free a key when overrding rule_map's in the table.
 */
enum rule_map_switch {
	rule_map_preserve_key, /** Used to preserve the key in the rule_map, ie don't free it*/
	rule_map_destroy_key   /** Used when you need a full free of the rule_map structure*/
};

/**
 * The expected "type" of data the value in the key
 * value pair should be.
 */
enum data_type {
	dt_bool, dt_string
};

/**
 * This list is used to store a double pointer to each
 * hash table / line rule combination. This way a replacement
 * in the hash table automatically updates the list. The list
 * is also used to keep "first encountered" ordering amongst
 * the encountered key value pairs in the rules file.
 */
struct line_order_list {
	hash_entry *e;
	line_order_list *next;
};

/**
 * The workhorse of the logic. This struct maps key value pairs to
 * an associated set of meta data maintained in rule_map_new()
 */
struct key_map {
	char *name;
	key_dir dir;
	data_type type;
	char *data;
};

/**
 * Key value pair struct, this represents the raw kvp values coming
 * from the rules files.
 */
struct kvp {
	char *key;
	char *value;
};

/**
 * Rules are made up of meta data and an associated set of kvp stored in a
 * key_map array.
 */
struct rule_map {
	char *key; /** key value before hashing */
	int length; /** length of the key map */
	int lineno; /** Line number rule was encounter on */
	rule_map *next; /** next pointer used in hash table for chaining on collision */
	key_map m[]; /** key value mapping */
};

struct hash_entry {
	rule_map *r; /** The rule map to store at that location */
};

/**
 * Data associated for a policy file
 */
struct policy_info {

	char *policy_file_name; /** policy file path name */
	FILE *policy_file;      /** file handle to the policy file */
	sepol_policydb_t *db;
	sepol_policy_file_t *pf;
	sepol_handle_t *handle;
	sepol_context_t *con;
};

/** Set to !0 to enable verbose logging */
static int logging_verbose = 0;

/** file handle to the output file */
static FILE *output_file = NULL;

/** file handle to the input file */
static FILE *input_file = NULL;

/** output file path name */
static char *out_file_name = NULL;

/** input file path name */
static char *in_file_name = NULL;

static policy_info pol = {
	.policy_file_name = NULL,
	.policy_file = NULL,
	.db = NULL,
	.pf = NULL,
	.handle = NULL,
	.con = NULL
};

/**
 * The heart of the mapping process, this must be updated if a new key value pair is added
 * to a rule.
 */
key_map rules[] = {
                /*Inputs*/
                { .name = "isSystemServer", .type = dt_bool,   .dir = dir_in,  .data = NULL },
                { .name = "user",           .type = dt_string, .dir = dir_in,  .data = NULL },
                { .name = "seinfo",         .type = dt_string, .dir = dir_in,  .data = NULL },
                { .name = "name",           .type = dt_string, .dir = dir_in,  .data = NULL },
                { .name = "sebool",         .type = dt_string, .dir = dir_in,  .data = NULL },
                /*Outputs*/
                { .name = "domain",         .type = dt_string, .dir = dir_out, .data = NULL },
                { .name = "type",           .type = dt_string, .dir = dir_out, .data = NULL },
                { .name = "levelFromUid",   .type = dt_bool,   .dir = dir_out, .data = NULL },
                { .name = "level",          .type = dt_string, .dir = dir_out, .data = NULL },
			};

/**
 * Head pointer to a linked list of
 * rule map table entries, used for
 * preserving the order of entries
 * based on "first encounter"
 */
static line_order_list *list_head = NULL;

/**
 * Pointer to the tail of the list for
 * quick appends to the end of the list
 */
static line_order_list *list_tail = NULL;

/**
 * Send a logging message to a file
 * @param out
 * 	Output file to send message too
 * @param prefix
 * 	A special prefix to write to the file, such as "Error:"
 * @param fmt
 * 	The printf style formatter to use, such as "%d"
 */
static void log_msg(FILE *out, const char *prefix, const char *fmt, ...) {
	fprintf(out, "%s", prefix);
	va_list args;
	va_start(args, fmt);
	vfprintf(out, fmt, args);
	va_end(args);
}

/**
 * Checks for a type in the policy.
 * @param db
 * 	The policy db to search
 * @param type
 * 	The type to search for
 * @return
 * 	1 if the type is found, 0 otherwise.
 * @warning
 * 	This function always returns 1 if libsepol is not linked
 * 	statically to this executable and LINK_SEPOL_STATIC is not
 * 	defined.
 */
int check_type(sepol_policydb_t *db, char *type) {

	int rc = 1;
#if defined(LINK_SEPOL_STATIC)
	policydb_t *d = (policydb_t *)db;
	hashtab_datum_t dat;
	dat = hashtab_search(d->p_types.table, type);
	rc = (dat == NULL) ? 0 : 1;
#endif
	return rc;
}

/**
 * Validates a key_map against a set of enforcement rules, this
 * function exits the application on a type that cannot be properly
 * checked
 *
 * @param m
 * 	The key map to check
 * @param lineno
 * 	The line number in the source file for the corresponding key map
 */
static int key_map_validate(key_map *m, int lineno) {

	int rc = 1;
	int ret = 1;
	int resp;
	char *key = m->name;
	char *value = m->data;
	data_type type = m->type;
	sepol_bool_key_t *se_key;

	log_info("Validating %s=%s\n", key, value);

	 /* Booleans can always be checked for sanity */
	if (type == dt_bool && (!strcmp("true", value) || !strcmp("false", value))) {
		goto out;
	}
	else if (type == dt_bool) {
		log_error("Expected boolean value got: %s=%s on line: %d in file: %s\n",
				key, value, lineno, out_file_name);
		rc = 0;
		goto out;
	}

	/*
	 * If their is no policy file present,
	 * then it is not in strict mode so just return.
	 * User and name cannot really be checked.
	 */
	if (!pol.policy_file) {
		goto out;
	}
	else if (!strcasecmp(key, "sebool")) {

		ret = sepol_bool_key_create(pol.handle, value, &se_key);
		if (ret < 0) {
			log_error("Could not create selinux boolean key, error: %s\n",
					strerror(errno));
			rc = 0;
			goto out;
		}

		ret = sepol_bool_exists(pol.handle, pol.db, se_key, &resp);
		if (ret < 0) {
			log_error("Could not check selinux boolean, error: %s\n",
					strerror(errno));
			rc = 0;
			sepol_bool_key_free(se_key);
			goto out;
		}

		if(!resp) {
			log_error("Could not find selinux boolean \"%s\" on line: %d in file: %s\n",
					value, lineno, out_file_name);
			rc = 0;
			sepol_bool_key_free(se_key);
			goto out;
		}
		sepol_bool_key_free(se_key);
	}
	else if (!strcasecmp(key, "type") || !strcasecmp(key, "domain")) {

		if(!check_type(pol.db, value)) {
			log_error("Could not find selinux type \"%s\" on line: %d in file: %s\n", value,
					lineno, out_file_name);
			rc = 0;
		}
		goto out;
	}
	else if (!strcasecmp(key, "level")) {

		ret = sepol_mls_check(pol.handle, pol.db, value);
		if (ret < 0) {
			log_error("Could not find selinux level \"%s\", on line: %d in file: %s\n", value,
					lineno, out_file_name);
			rc = 0;
			goto out;
		}
	}

out:
	log_info("Key map validate returning: %d\n", rc);
	return rc;
}

/**
 * Prints a rule map back to a file
 * @param fp
 * 	The file handle to print too
 * @param r
 * 	The rule map to print
 */
static void rule_map_print(FILE *fp, rule_map *r) {

	int i;
	key_map *m;

	for (i = 0; i < r->length; i++) {
		m = &(r->m[i]);
		if (i < r->length - 1)
			fprintf(fp, "%s=%s ", m->name, m->data);
		else
			fprintf(fp, "%s=%s", m->name, m->data);
	}
}

/**
 * Compare two rule maps for equality
 * @param rmA
 * 	a rule map to check
 * @param rmB
 * 	a rule map to check
 * @return
 *  a map_match enum indicating the result
 */
static map_match rule_map_cmp(rule_map *rmA, rule_map *rmB) {

	int i;
	int j;
	int inputs_found = 0;
	int num_of_matched_inputs = 0;
	int input_mode = 0;
	int matches = 0;
	key_map *mA;
	key_map *mB;

	if (rmA->length != rmB->length)
		return map_no_matches;

	for (i = 0; i < rmA->length; i++) {
		mA = &(rmA->m[i]);

		for (j = 0; j < rmB->length; j++) {
			mB = &(rmB->m[j]);
			input_mode = 0;

			if (mA->type != mB->type)
				continue;

			if (strcmp(mA->name, mB->name))
				continue;

			if (strcmp(mA->data, mB->data))
				continue;

			if (mB->dir != mA->dir)
				continue;
			else if (mB->dir == dir_in) {
				input_mode = 1;
				inputs_found++;
			}

			if (input_mode) {
				log_info("Matched input lines: type=%s name=%s data=%s dir=%d\n", mA->type, mA->name, mA->data, mA->dir);
				num_of_matched_inputs++;
			}

			/* Match found, move on */
			log_info("Matched lines: type=%s name=%s data=%s dir=%d\n", mA->type, mA->name, mA->data, mA->dir);
			matches++;
			break;
		}
	}

	/* If they all matched*/
	if (matches == rmA->length) {
		log_info("Rule map cmp MATCH\n");
		return map_matched;
	}

	/* They didn't all match but the input's did */
	else if (num_of_matched_inputs == inputs_found) {
		log_info("Rule map cmp INPUT MATCH\n");
		return map_input_matched;
	}

	/* They didn't all match, and the inputs didn't match, ie it didn't
	 * match */
	else {
		log_info("Rule map cmp NO MATCH\n");
		return map_no_matches;
	}
}

/**
 * Frees a rule map
 * @param rm
 * 	rule map to be freed.
 */
static void rule_map_free(rule_map *rm, rule_map_switch s) {

	int i;
	int len = rm->length;
	for (i = 0; i < len; i++) {
		key_map *m = &(rm->m[i]);
		free(m->data);
	}

	if(s == rule_map_destroy_key && rm->key)
		free(rm->key);

	free(rm);
}

static void free_kvp(kvp *k) {
	free(k->key);
	free(k->value);
}

/**
 * Given a set of key value pairs, this will construct a new rule map.
 * On error this function calls exit.
 * @param keys
 * 	Keys from a rule line to map
 * @param num_of_keys
 * 	The length of the keys array
 * @param lineno
 * 	The line number the keys were extracted from
 * @return
 * 	A rule map pointer.
 */
static rule_map *rule_map_new(kvp keys[], unsigned int num_of_keys, int lineno) {

	unsigned int i = 0, j = 0;
	rule_map *new_map = NULL;
	kvp *k = NULL;
	key_map *r = NULL, *x = NULL;

	new_map = calloc(1, (num_of_keys * sizeof(key_map)) + sizeof(rule_map));
	if (!new_map)
		goto oom;

	new_map->length = num_of_keys;
	new_map->lineno = lineno;

	/* For all the keys in a rule line*/
	for (i = 0; i < num_of_keys; i++) {
		k = &(keys[i]);
		r = &(new_map->m[i]);

		for (j = 0; j < KVP_NUM_OF_RULES; j++) {
			x = &(rules[j]);

			/* Only assign key name to map name */
			if (strcasecmp(k->key, x->name)) {
				if (i == KVP_NUM_OF_RULES) {
					log_error("No match for key: %s\n", k->key);
					goto err;
				}
				continue;
			}

			memcpy(r, x, sizeof(key_map));

			/* Assign rule map value to one from file */
			r->data = strdup(k->value);
			if (!r->data)
				goto oom;

			/* Enforce type check*/
			log_info("Validating keys!\n");
			if (!key_map_validate(r, lineno)) {
				log_error("Could not validate\n");
				goto err;
			}

			/* Only build key off of inputs*/
			if (r->dir == dir_in) {
				char *tmp;
				int key_len = strlen(k->key);
				int val_len = strlen(k->value);
				int l = (new_map->key) ? strlen(new_map->key) : 0;
				l = l + key_len + val_len;
				l += 1;

				tmp = realloc(new_map->key, l);
				if (!tmp)
					goto oom;

				if (!new_map->key)
					memset(tmp, 0, l);

				new_map->key = tmp;

				strncat(new_map->key, k->key, key_len);
				strncat(new_map->key, k->value, val_len);
			}
			break;
		}
		free_kvp(k);
	}

	if (new_map->key == NULL) {
		log_error("Strange, no keys found, input file corrupt perhaps?\n");
		goto err;
	}

	return new_map;

oom:
	log_error("Out of memory!\n");
err:
	if(new_map) {
		rule_map_free(new_map, rule_map_destroy_key);
		for (; i < num_of_keys; i++) {
			k = &(keys[i]);
			free_kvp(k);
		}
	}
	exit(EXIT_FAILURE);
}

/**
 * Print the usage of the program
 */
static void usage() {
	printf(
	        "checkseapp [options] <input file>\n"
		        "Processes an seapp_contexts file specified by argument <input file> (default stdin) "
		        "and allows later declarations to override previous ones on a match.\n"
		        "Options:\n"
		        "-h - print this help message\n"
		        "-v - enable verbose debugging informations\n"
		        "-p policy file - specify policy file for strict checking of output selectors\n"
		        "-o output file - specify output file, default is stdout\n");
}

static void init() {

	/* If not set on stdin already */
	if(!input_file) {
		log_info("Opening input file: %s\n", in_file_name);
		input_file = fopen(in_file_name, "r");
		if (!input_file) {
			log_error("Could not open file: %s error: %s\n", in_file_name, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/* If not set on std out already */
	if(!output_file) {
		output_file = fopen(out_file_name, "w+");
		if (!output_file) {
			log_error("Could not open file: %s error: %s\n", out_file_name, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	if (pol.policy_file_name) {

		log_info("Opening policy file: %s\n", pol.policy_file_name);
		pol.policy_file = fopen(pol.policy_file_name, "rb");
		if (!pol.policy_file) {
			log_error("Could not open file: %s error: %s\n",
					pol.policy_file_name, strerror(errno));
			exit(EXIT_FAILURE);
		}

		pol.handle = sepol_handle_create();
		if (!pol.handle) {
			log_error("Could not create sepolicy handle: %s\n",
					strerror(errno));
			exit(EXIT_FAILURE);
		}

		if (sepol_policy_file_create(&pol.pf) < 0) {
			log_error("Could not create sepolicy file: %s!\n",
					strerror(errno));
			exit(EXIT_FAILURE);
		}

		sepol_policy_file_set_fp(pol.pf, pol.policy_file);
		sepol_policy_file_set_handle(pol.pf, pol.handle);

		if (sepol_policydb_create(&pol.db) < 0) {
			log_error("Could not create sepolicy db: %s!\n",
					strerror(errno));
			exit(EXIT_FAILURE);
		}

		if (sepol_policydb_read(pol.db, pol.pf) < 0) {
			log_error("Could not lod policy file to db: %s!\n",
					strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	log_info("Policy file set to: %s\n", (pol.policy_file_name == NULL) ? "None" : pol.policy_file_name);
	log_info("Input file set to: %s\n", (in_file_name == NULL) ? "stdin" : in_file_name);
	log_info("Output file set to: %s\n", (out_file_name == NULL) ? "stdout" : out_file_name);

#if !defined(LINK_SEPOL_STATIC)
	log_warn("LINK_SEPOL_STATIC is not defined\n""Not checking types!");
#endif

}

/**
 * Handle parsing and setting the global flags for the command line
 * options. This function calls exit on failure.
 * @param argc
 * 	argument count
 * @param argv
 * 	argument list
 */
static void handle_options(int argc, char *argv[]) {

	int c;
	int num_of_args;

	while ((c = getopt(argc, argv, "ho:p:v")) != -1) {
		switch (c) {
		case 'h':
			usage();
			exit(EXIT_SUCCESS);
		case 'o':
			out_file_name = optarg;
			break;
		case 'p':
			pol.policy_file_name = optarg;
			break;
		case 'v':
			log_set_verbose();
			break;
		case '?':
			if (optopt == 'o' || optopt == 'p')
				log_error("Option -%c requires an argument.\n", optopt);
			else if (isprint (optopt))
				log_error("Unknown option `-%c'.\n", optopt);
			else {
				log_error(
						"Unknown option character `\\x%x'.\n",
						optopt);
				exit(EXIT_FAILURE);
			}
			break;
		default:
			exit(EXIT_FAILURE);
		}
	}

	num_of_args = argc - optind;

	if (num_of_args > 1) {
		log_error("Too many arguments, expected 0 or 1, argument, got %d\n", num_of_args);
		usage();
		exit(EXIT_FAILURE);
	} else if (num_of_args == 1) {
		in_file_name = argv[argc - 1];
	} else {
		input_file = stdin;
		in_file_name = "stdin";
	}

	if (!out_file_name) {
		output_file = stdout;
		out_file_name = "stdout";
	}
}

/**
 * Adds a rule_map double pointer, ie the hash table pointer to the list.
 * By using a double pointer, the hash table can have a line be overridden
 * and the value is updated in the list. This function calls exit on failure.
 * @param rm
 * 	the rule_map to add.
 */
static void list_add(hash_entry *e) {

	line_order_list *node = malloc(sizeof(line_order_list));
	if (node == NULL)
		goto oom;

	node->next = NULL;
	node->e = e;

	if (list_head == NULL)
		list_head = list_tail = node;
	else {
		list_tail->next = node;
		list_tail = list_tail->next;
	}
	return;

oom:
	log_error("Out of memory!\n");
	exit(EXIT_FAILURE);
}

/**
 * Free's the rule map list, which ultimatley contains
 * all the malloc'd rule_maps.
 */
static void list_free() {
	line_order_list *cursor, *tmp;
	hash_entry *e;

	cursor = list_head;
	while (cursor) {
		e = cursor->e;
		rule_map_free(e->r, rule_map_destroy_key);
		tmp = cursor;
		cursor = cursor->next;
		free(e);
		free(tmp);
	}
}

/**
 * Adds a rule to the hash table and to the ordered list if needed.
 * @param rm
 * 	The rule map to add.
 */
static void rule_add(rule_map *rm) {

	map_match cmp;
	ENTRY e;
	ENTRY *f;
	hash_entry *entry;
	hash_entry *tmp;
	char *preserved_key;

	e.key = rm->key;

	log_info("Searching for key: %s\n", e.key);
	/* Check to see if it has already been added*/
	f = hsearch(e, FIND);

	/*
	 * Since your only hashing on a partial key, the inputs we need to handle
	 * when you want to override the outputs for a given input set, as well as
	 * checking for duplicate entries.
	 */
	if(f) {
		log_info("Existing entry found!\n");
		tmp = (hash_entry *)f->data;
		cmp = rule_map_cmp(rm, tmp->r);
		log_info("Comparing on rule map ret: %d\n", cmp);
		/* Override be freeing the old rule map and updating
		   the pointer */
		if(cmp != map_matched) {

			/*
			 * DO NOT free key pointers given to the hash map, instead
			 * free the new key. The ordering here is critical!
			 */
			preserved_key = tmp->r->key;
			rule_map_free(tmp->r, rule_map_preserve_key);
			free(rm->key);
			rm->key = preserved_key;
			tmp->r = rm;
		}
		/* Duplicate */
		else {
			log_error("Duplicate line detected in file: %s\n"
					"Lines %d and %d match!\n",
					out_file_name, tmp->r->lineno, rm->lineno);
			rule_map_free(rm, rule_map_destroy_key);
			goto err;
		}
	}
	/* It wasn't found, just add the rule map to the table */
	else {

		entry = malloc(sizeof(hash_entry));
		if (!entry)
			goto oom;

		entry->r = rm;
		e.data = entry;

		f = hsearch(e, ENTER);
		if(f == NULL) {
			goto oom;
		}

		/* new entries must be added to the ordered list */
		entry->r = rm;
		list_add(entry);
	}

	return;
oom:
	if (e.key)
		free(e.key);
	if (entry)
		free(entry);
	if (rm)
		free(rm);
	log_error("Out of memory in function: %s\n", __FUNCTION__);
err:
	exit(EXIT_FAILURE);
}

/**
 * Parses the seapp_contexts file and adds them to the
 * hash table and ordered list entries when it encounters them.
 * Calls exit on failure.
 */
static void parse() {

	char line_buf[BUFSIZ];
	char *token;
	unsigned lineno = 0;
	char *p, *name = NULL, *value = NULL, *saveptr;
	size_t len;
	kvp keys[KVP_NUM_OF_RULES];
	int token_cnt = 0;

	while (fgets(line_buf, sizeof line_buf - 1, input_file)) {

		lineno++;
		log_info("Got line %d\n", lineno);
		len = strlen(line_buf);
		if (line_buf[len - 1] == '\n')
			line_buf[len - 1] = 0;
		p = line_buf;
		while (isspace(*p))
			p++;
		if (*p == '#' || *p == 0)
			continue;

		token = strtok_r(p, " \t", &saveptr);
		if (!token)
			goto err;

		token_cnt = 0;
		memset(keys, 0, sizeof(kvp) * KVP_NUM_OF_RULES);
		while (1) {

			name = token;
			value = strchr(name, '=');
			if (!value)
				goto err;
			*value++ = 0;

			keys[token_cnt].key = strdup(name);
			if (!keys[token_cnt].key)
				goto oom;

			keys[token_cnt].value = strdup(value);
			if (!keys[token_cnt].value)
				goto oom;

			token_cnt++;

			token = strtok_r(NULL, " \t", &saveptr);
			if (!token)
				break;

		} /*End token parsing */

		rule_map *r = rule_map_new(keys, token_cnt, lineno);
		rule_add(r);

	} /* End file parsing */
	return;

err:
	log_error("reading %s, line %u, name %s, value %s\n",
			in_file_name, lineno, name, value);
	exit(EXIT_FAILURE);
oom:
	log_error("In function %s:  Out of memory\n", __FUNCTION__);
	exit(EXIT_FAILURE);
}

/**
 * Should be called after parsing to cause the printing of the rule_maps
 * stored in the ordered list, head first, which preserves the "first encountered"
 * ordering.
 */
static void output() {

	rule_map *r;
	line_order_list *cursor;
	cursor = list_head;

	while (cursor) {
		r = cursor->e->r;
		rule_map_print(output_file, r);
		cursor = cursor->next;
		fprintf(output_file, "\n");
	}
}

/**
 * This function is registered to the at exit handler and should clean up
 * the programs dynamic resources, such as memory and fd's.
 */
static void cleanup() {

	/* Only close this when it was opened by me and not the crt */
	if (out_file_name && output_file) {
		log_info("Closing file: %s\n", out_file_name);
		fclose(output_file);
	}

	/* Only close this when it was opened by me  and not the crt */
	if (in_file_name && input_file) {
		log_info("Closing file: %s\n", in_file_name);
		fclose(input_file);
	}

	if (pol.policy_file) {

		log_info("Closing file: %s\n", pol.policy_file_name);
		fclose(pol.policy_file);

		if (pol.db)
			sepol_policydb_free(pol.db);

		if (pol.pf)
			sepol_policy_file_free(pol.pf);

		if (pol.handle)
			sepol_handle_destroy(pol.handle);
	}

	log_info("Freeing list\n");
	list_free();
	hdestroy();
}

int main(int argc, char *argv[]) {
	if (!hcreate(TABLE_SIZE)) {
		log_error("Could not create hash table: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	atexit(cleanup);
	handle_options(argc, argv);
	init();
	log_info("Starting to parse\n");
	parse();
	log_info("Parsing completed, generating output\n");
	output();
	log_info("Success, generated output\n");
	exit(EXIT_SUCCESS);
}
