Blame src/database_activedb.c

Packit 366192
/* Copyright (C) 2005 Red Hat, Inc. */
Packit 366192
Packit 366192
/* Object: dbase_activedb_t (Active/Kernel)
Packit 366192
 * Extends: dbase_llist_t (Linked List) 
Packit 366192
 * Implements: dbase_t (Database)
Packit 366192
 */
Packit 366192
Packit 366192
struct dbase_activedb;
Packit 366192
typedef struct dbase_activedb dbase_t;
Packit 366192
#define DBASE_DEFINED
Packit 366192
Packit 366192
#include <stdlib.h>
Packit 366192
#include <string.h>
Packit 366192
#include <errno.h>
Packit 366192
#include "debug.h"
Packit 366192
#include "handle.h"
Packit 366192
#include "database_activedb.h"
Packit 366192
#include "database_llist.h"
Packit 366192
Packit 366192
/* ACTIVEDB dbase */
Packit 366192
struct dbase_activedb {
Packit 366192
Packit 366192
	/* Parent object - must always be 
Packit 366192
	 * the first field - here we are using
Packit 366192
	 * a linked list to store the records */
Packit 366192
	dbase_llist_t llist;
Packit 366192
Packit 366192
	/* ACTIVEDB extension */
Packit 366192
	record_activedb_table_t *ratable;
Packit 366192
};
Packit 366192
Packit 366192
static int dbase_activedb_cache(semanage_handle_t * handle,
Packit 366192
				dbase_activedb_t * dbase)
Packit 366192
{
Packit 366192
Packit 366192
	record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
Packit 366192
	record_activedb_table_t *ratable = dbase->ratable;
Packit 366192
Packit 366192
	record_t **records = NULL;
Packit 366192
	unsigned int rcount = 0;
Packit 366192
	unsigned int i = 0;
Packit 366192
Packit 366192
	/* Already cached */
Packit 366192
	if (!dbase_llist_needs_resync(handle, &dbase->llist))
Packit 366192
		return STATUS_SUCCESS;
Packit 366192
Packit 366192
	/* Update cache serial */
Packit 366192
	dbase_llist_cache_init(&dbase->llist);
Packit 366192
	if (dbase_llist_set_serial(handle, &dbase->llist) < 0)
Packit 366192
		goto err;
Packit 366192
Packit 366192
	/* Fetch the entire list */
Packit 366192
	if (ratable->read_list(handle, &records, &rcount) < 0)
Packit 366192
		goto err;
Packit 366192
Packit 366192
	/* Add records one by one */
Packit 366192
	for (; i < rcount; i++) {
Packit 366192
		if (dbase_llist_cache_prepend(handle, &dbase->llist, records[i])
Packit 366192
		    < 0)
Packit 366192
			goto err;
Packit 366192
		rtable->free(records[i]);
Packit 366192
	}
Packit 366192
Packit 366192
	free(records);
Packit 366192
	return STATUS_SUCCESS;
Packit 366192
Packit 366192
      err:
Packit 366192
	ERR(handle, "could not cache active database");
Packit 366192
	for (; i < rcount; i++)
Packit 366192
		rtable->free(records[i]);
Packit 366192
	dbase_llist_drop_cache(&dbase->llist);
Packit 366192
	free(records);
Packit 366192
	return STATUS_ERR;
Packit 366192
}
Packit 366192
Packit 366192
static int dbase_activedb_flush(semanage_handle_t * handle,
Packit 366192
				dbase_activedb_t * dbase)
Packit 366192
{
Packit 366192
Packit 366192
	record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
Packit 366192
	record_activedb_table_t *ratable = dbase->ratable;
Packit 366192
Packit 366192
	record_t **records = NULL;
Packit 366192
	unsigned int rcount = 0;
Packit 366192
	unsigned int i;
Packit 366192
Packit 366192
	/* Not cached, or not modified - flush is not necessary */
Packit 366192
	if (!dbase_llist_is_modified(&dbase->llist))
Packit 366192
		return STATUS_SUCCESS;
Packit 366192
Packit 366192
	/* Fetch list */
Packit 366192
	if (dbase_llist_list(handle, &dbase->llist, &records, &rcount) < 0)
Packit 366192
		goto err;
Packit 366192
Packit 366192
	/* Commit */
Packit 366192
	if (ratable->commit_list(handle, records, rcount) < 0)
Packit 366192
		goto err;
Packit 366192
Packit 366192
	for (i = 0; i < rcount; i++)
Packit 366192
		rtable->free(records[i]);
Packit 366192
	free(records);
Packit 366192
	dbase_llist_set_modified(&dbase->llist, 0);
Packit 366192
	return STATUS_SUCCESS;
Packit 366192
Packit 366192
      err:
Packit 366192
	for (i = 0; i < rcount; i++)
Packit 366192
		rtable->free(records[i]);
Packit 366192
	free(records);
Packit 366192
	ERR(handle, "could not flush active database");
Packit 366192
	return STATUS_ERR;
Packit 366192
}
Packit 366192
Packit 366192
int dbase_activedb_init(semanage_handle_t * handle,
Packit 366192
			record_table_t * rtable,
Packit 366192
			record_activedb_table_t * ratable,
Packit 366192
			dbase_activedb_t ** dbase)
Packit 366192
{
Packit 366192
Packit 366192
	dbase_activedb_t *tmp_dbase =
Packit 366192
	    (dbase_activedb_t *) malloc(sizeof(dbase_activedb_t));
Packit 366192
Packit 366192
	if (!tmp_dbase)
Packit 366192
		goto omem;
Packit 366192
Packit 366192
	tmp_dbase->ratable = ratable;
Packit 366192
	dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_ACTIVEDB_DTABLE);
Packit 366192
Packit 366192
	*dbase = tmp_dbase;
Packit 366192
Packit 366192
	return STATUS_SUCCESS;
Packit 366192
Packit 366192
      omem:
Packit 366192
	ERR(handle, "out of memory, could not initialize active database");
Packit 366192
	free(tmp_dbase);
Packit 366192
	return STATUS_ERR;
Packit 366192
}
Packit 366192
Packit 366192
/* Release dbase resources */
Packit 366192
void dbase_activedb_release(dbase_activedb_t * dbase)
Packit 366192
{
Packit 366192
Packit 366192
	dbase_llist_drop_cache(&dbase->llist);
Packit 366192
	free(dbase);
Packit 366192
}
Packit 366192
Packit 366192
/* ACTIVEDB dbase - method table implementation */
Packit 366192
dbase_table_t SEMANAGE_ACTIVEDB_DTABLE = {
Packit 366192
Packit 366192
	/* Cache/Transactions */
Packit 366192
	.cache = dbase_activedb_cache,
Packit 366192
	.drop_cache = (void *)dbase_llist_drop_cache,
Packit 366192
	.flush = dbase_activedb_flush,
Packit 366192
	.is_modified = (void *)dbase_llist_is_modified,
Packit 366192
Packit 366192
	/* Database API */
Packit 366192
	.iterate = (void *)dbase_llist_iterate,
Packit 366192
	.exists = (void *)dbase_llist_exists,
Packit 366192
	.list = (void *)dbase_llist_list,
Packit 366192
	.add = (void *)dbase_llist_add,
Packit 366192
	.set = (void *)dbase_llist_set,
Packit 366192
	.del = (void *)dbase_llist_del,
Packit 366192
	.clear = (void *)dbase_llist_clear,
Packit 366192
	.modify = (void *)dbase_llist_modify,
Packit 366192
	.query = (void *)dbase_llist_query,
Packit 366192
	.count = (void *)dbase_llist_count,
Packit 366192
Packit 366192
	/* Polymorphism */
Packit 366192
	.get_rtable = (void *)dbase_llist_get_rtable
Packit 366192
};