#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 = "levelFrom",      .type = dt_string,   .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
 * @return
 * 	1 if valid, 0 if invalid
 */
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 (!strcasecmp(key, "levelFrom") &&
	    (strcasecmp(value, "none") && strcasecmp(value, "all") &&
	     strcasecmp(value, "app") && strcasecmp(value, "user"))) {
		log_error("Unknown levelFrom=%s on line: %d in file: %s\n",
			  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);
	}

/* hdestroy() frees comparsion keys for non glibc */
#ifdef __GLIBC__
	if(s == rule_map_destroy_key && rm->key)
		free(rm->key);
#endif

	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);
/*  hdestroy() frees comparsion keys for non glibc */
#ifdef __GLIBC__
			free(rm->key);
#endif
			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);
}
