#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 <stdbool.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
};

const char *map_match_str[] = {
	"do not match",
	"match on all inputs",
	"match on everything"
};

/**
 * 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 */
	size_t length; /** length of the key map */
	int lineno; /** Line number rule was encounter on */
	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 = "isOwner",        .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 = "path",           .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 __attribute__ ((format(printf, 3, 4)))
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;
	char *key = m->name;
	char *value = m->data;
	data_type type = m->type;

	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 there is no policy file present,
	 * then it is not going to enforce the types against the policy so just return.
	 * User and name cannot really be checked.
	 */
	if (!pol.policy_file) {
		goto out;
	}
	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) {

	size_t 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) {

	size_t i;
	size_t j;
	int inputs_found = 0;
	int num_of_matched_inputs = 0;
	int input_mode = 0;
	size_t 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: name=%s data=%s\n", mA->name, mA->data);
				num_of_matched_inputs++;
			}

			/* Match found, move on */
			log_info("Matched lines: name=%s data=%s", mA->name, mA->data);
			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 __attribute__((unused)) /* only glibc builds, ignored otherwise */) {

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

/**
 * Checks a rule_map for any variation of KVP's that shouldn't be allowed.
 * Note that this function logs all errors.
 *
 * Current Checks:
 * 1. That a specified name entry should have a specified seinfo entry as well.
 * @param rm
 *  The rule map to check for validity.
 * @return
 *  true if the rule is valid, false otherwise.
 */
static bool rule_map_validate(const rule_map *rm) {

	size_t i;
	bool found_name = false;
	bool found_seinfo = false;
	char *name = NULL;
	const key_map *tmp;

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

		if(!strcmp(tmp->name, "name") && tmp->data) {
			name = tmp->data;
			found_name = true;
		}
		if(!strcmp(tmp->name, "seinfo") && tmp->data && strcmp(tmp->data, "default")) {
			found_seinfo = true;
		}
	}

	if(found_name && !found_seinfo) {
		log_error("No specific seinfo value specified with name=\"%s\", on line: %d:  insecure configuration!\n",
				name, rm->lineno);
		return false;
	}

	return true;
}

/**
 * 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[], size_t num_of_keys, int lineno) {

	size_t i = 0, j = 0;
	bool valid_rule;
	rule_map *new_map = NULL;
	kvp *k = NULL;
	key_map *r = NULL, *x = NULL;
	bool seen[KVP_NUM_OF_RULES];

	for (i = 0; i < KVP_NUM_OF_RULES; i++)
		seen[i] = false;

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

			if (seen[j]) {
					log_error("Duplicated key: %s\n", k->key);
					goto err;
			}
			seen[j] = true;

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

	valid_rule = rule_map_validate(new_map);
	if(!valid_rule) {
		/* Error message logged from rule_map_validate() */
		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);
		}
	}
	return NULL;
}

/**
 * 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 against the policy\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:sv")) != -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);
			}
		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;

	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_error("Duplicate line detected in file: %s\n"
			  "Lines %d and %d %s!\n",
			  out_file_name, tmp->r->lineno, rm->lineno,
			  map_match_str[cmp]);
		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];
	size_t 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);
		if (!r)
			goto err;
		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);
}
