/* Copyright (C) 2005 Red Hat, Inc. */

/* Object: dbase_file_t (File)
 * Extends: dbase_llist_t (Linked List) 
 * Implements: dbase_t (Database)
 */

struct dbase_file;
typedef struct dbase_file dbase_t;
#define DBASE_DEFINED

#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdio_ext.h>
#include "debug.h"
#include "handle.h"
#include "parse_utils.h"
#include "database_file.h"
#include "database_llist.h"
#include "semanage_store.h"

/* FILE dbase */
struct dbase_file {

	/* Parent object - must always be 
	 * the first field - here we are using
	 * a linked list to store the records */
	dbase_llist_t llist;

	/* Backing path for read-only[0] and transaction[1] */
	const char *path[2];

	/* FILE extension */
	record_file_table_t *rftable;
};

static int dbase_file_cache(semanage_handle_t * handle, dbase_file_t * dbase)
{

	record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
	record_file_table_t *rftable = dbase->rftable;

	record_t *process_record = NULL;
	int pstatus = STATUS_SUCCESS;

	parse_info_t *parse_info = NULL;
	const char *fname = NULL;

	/* Already cached */
	if (!dbase_llist_needs_resync(handle, &dbase->llist))
		return STATUS_SUCCESS;

	/* Update cache serial */
	dbase_llist_cache_init(&dbase->llist);
	if (dbase_llist_set_serial(handle, &dbase->llist) < 0)
		goto err;

	fname = dbase->path[handle->is_in_transaction];

	if (parse_init(handle, fname, NULL, &parse_info) < 0)
		goto err;

	if (parse_open(handle, parse_info) < 0)
		goto err;

	/* Main processing loop */
	do {

		/* Create record */
		if (rtable->create(handle, &process_record) < 0)
			goto err;

		/* Parse record */
		pstatus = rftable->parse(handle, parse_info, process_record);

		/* Parse error */
		if (pstatus < 0)
			goto err;

		/* End of file */
		else if (pstatus == STATUS_NODATA)
			break;

		/* Prepend to cache */
		if (dbase_llist_cache_prepend(handle, &dbase->llist,
					      process_record) < 0)
			goto err;

		rtable->free(process_record);
		process_record = NULL;

	} while (pstatus != STATUS_NODATA);

	rtable->free(process_record);
	parse_close(parse_info);
	parse_release(parse_info);
	return STATUS_SUCCESS;

      err:
	ERR(handle, "could not cache file database");
	rtable->free(process_record);
	if (parse_info) {
		parse_close(parse_info);
		parse_release(parse_info);
	}
	dbase_llist_drop_cache(&dbase->llist);
	return STATUS_ERR;
}

/* Flush database to file */
static int dbase_file_flush(semanage_handle_t * handle, dbase_file_t * dbase)
{

	record_file_table_t *rftable = dbase->rftable;

	cache_entry_t *ptr;
	const char *fname = NULL;
	FILE *str = NULL;
	mode_t mask;

	if (!dbase_llist_is_modified(&dbase->llist))
		return STATUS_SUCCESS;

	fname = dbase->path[handle->is_in_transaction];

	mask = umask(0077);
	str = fopen(fname, "w");
	umask(mask);
	if (!str) {
		ERR(handle, "could not open %s for writing: %s",
		    fname, strerror(errno));
		goto err;
	}
	__fsetlocking(str, FSETLOCKING_BYCALLER);

	if (fprintf(str, "# This file is auto-generated by libsemanage\n"
		    "# Do not edit directly.\n\n") < 0) {

		ERR(handle, "could not write file header for %s", fname);
		goto err;
	}

	for (ptr = dbase->llist.cache_tail; ptr != NULL; ptr = ptr->prev) {
		if (rftable->print(handle, ptr->data, str) < 0)
			goto err;
	}

	dbase_llist_set_modified(&dbase->llist, 0);
	fclose(str);
	return STATUS_SUCCESS;

      err:
	if (str != NULL)
		fclose(str);

	ERR(handle, "could not flush database to file");
	return STATUS_ERR;
}

int dbase_file_init(semanage_handle_t * handle,
		    const char *path_ro,
		    const char *path_rw,
		    record_table_t * rtable,
		    record_file_table_t * rftable, dbase_file_t ** dbase)
{

	dbase_file_t *tmp_dbase = (dbase_file_t *) malloc(sizeof(dbase_file_t));

	if (!tmp_dbase)
		goto omem;

	tmp_dbase->path[0] = path_ro;
	tmp_dbase->path[1] = path_rw;
	tmp_dbase->rftable = rftable;
	dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_FILE_DTABLE);

	*dbase = tmp_dbase;

	return STATUS_SUCCESS;

      omem:
	ERR(handle, "out of memory, could not initialize file database");
	free(tmp_dbase);
	return STATUS_ERR;
}

/* Release dbase resources */
void dbase_file_release(dbase_file_t * dbase)
{

	dbase_llist_drop_cache(&dbase->llist);
	free(dbase);
}

/* FILE dbase - method table implementation */
dbase_table_t SEMANAGE_FILE_DTABLE = {

	/* Cache/Transactions */
	.cache = dbase_file_cache,
	.drop_cache = (void *)dbase_llist_drop_cache,
	.flush = dbase_file_flush,
	.is_modified = (void *)dbase_llist_is_modified,

	/* Database API */
	.iterate = (void *)dbase_llist_iterate,
	.exists = (void *)dbase_llist_exists,
	.list = (void *)dbase_llist_list,
	.add = (void *)dbase_llist_add,
	.set = (void *)dbase_llist_set,
	.del = (void *)dbase_llist_del,
	.clear = (void *)dbase_llist_clear,
	.modify = (void *)dbase_llist_modify,
	.query = (void *)dbase_llist_query,
	.count = (void *)dbase_llist_count,

	/* Polymorphism */
	.get_rtable = (void *)dbase_llist_get_rtable
};
