Home | History | Annotate | Download | only in src
      1 /* Copyright (C) 2005 Red Hat, Inc. */
      2 
      3 /* Object: dbase_activedb_t (Active/Kernel)
      4  * Extends: dbase_llist_t (Linked List)
      5  * Implements: dbase_t (Database)
      6  */
      7 
      8 struct dbase_activedb;
      9 typedef struct dbase_activedb dbase_t;
     10 #define DBASE_DEFINED
     11 
     12 #include <stdlib.h>
     13 #include <string.h>
     14 #include <errno.h>
     15 #include "debug.h"
     16 #include "handle.h"
     17 #include "database_activedb.h"
     18 #include "database_llist.h"
     19 
     20 /* ACTIVEDB dbase */
     21 struct dbase_activedb {
     22 
     23 	/* Parent object - must always be
     24 	 * the first field - here we are using
     25 	 * a linked list to store the records */
     26 	dbase_llist_t llist;
     27 
     28 	/* ACTIVEDB extension */
     29 	record_activedb_table_t *ratable;
     30 };
     31 
     32 static int dbase_activedb_cache(semanage_handle_t * handle,
     33 				dbase_activedb_t * dbase)
     34 {
     35 
     36 	record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
     37 	record_activedb_table_t *ratable = dbase->ratable;
     38 
     39 	record_t **records = NULL;
     40 	unsigned int rcount = 0;
     41 	unsigned int i = 0;
     42 
     43 	/* Already cached */
     44 	if (!dbase_llist_needs_resync(handle, &dbase->llist))
     45 		return STATUS_SUCCESS;
     46 
     47 	/* Update cache serial */
     48 	dbase_llist_cache_init(&dbase->llist);
     49 	if (dbase_llist_set_serial(handle, &dbase->llist) < 0)
     50 		goto err;
     51 
     52 	/* Fetch the entire list */
     53 	if (ratable->read_list(handle, &records, &rcount) < 0)
     54 		goto err;
     55 
     56 	/* Add records one by one */
     57 	for (; i < rcount; i++) {
     58 		if (dbase_llist_cache_prepend(handle, &dbase->llist, records[i])
     59 		    < 0)
     60 			goto err;
     61 		rtable->free(records[i]);
     62 	}
     63 
     64 	free(records);
     65 	return STATUS_SUCCESS;
     66 
     67       err:
     68 	ERR(handle, "could not cache active database");
     69 	for (; i < rcount; i++)
     70 		rtable->free(records[i]);
     71 	dbase_llist_drop_cache(&dbase->llist);
     72 	free(records);
     73 	return STATUS_ERR;
     74 }
     75 
     76 static int dbase_activedb_flush(semanage_handle_t * handle,
     77 				dbase_activedb_t * dbase)
     78 {
     79 
     80 	record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
     81 	record_activedb_table_t *ratable = dbase->ratable;
     82 
     83 	record_t **records = NULL;
     84 	unsigned int rcount = 0;
     85 	unsigned int i;
     86 
     87 	/* Not cached, or not modified - flush is not necessary */
     88 	if (!dbase_llist_is_modified(&dbase->llist))
     89 		return STATUS_SUCCESS;
     90 
     91 	/* Fetch list */
     92 	if (dbase_llist_list(handle, &dbase->llist, &records, &rcount) < 0)
     93 		goto err;
     94 
     95 	/* Commit */
     96 	if (ratable->commit_list(handle, records, rcount) < 0)
     97 		goto err;
     98 
     99 	for (i = 0; i < rcount; i++)
    100 		rtable->free(records[i]);
    101 	free(records);
    102 	dbase_llist_set_modified(&dbase->llist, 0);
    103 	return STATUS_SUCCESS;
    104 
    105       err:
    106 	for (i = 0; i < rcount; i++)
    107 		rtable->free(records[i]);
    108 	free(records);
    109 	ERR(handle, "could not flush active database");
    110 	return STATUS_ERR;
    111 }
    112 
    113 int dbase_activedb_init(semanage_handle_t * handle,
    114 			record_table_t * rtable,
    115 			record_activedb_table_t * ratable,
    116 			dbase_activedb_t ** dbase)
    117 {
    118 
    119 	dbase_activedb_t *tmp_dbase =
    120 	    (dbase_activedb_t *) malloc(sizeof(dbase_activedb_t));
    121 
    122 	if (!tmp_dbase)
    123 		goto omem;
    124 
    125 	tmp_dbase->ratable = ratable;
    126 	dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_ACTIVEDB_DTABLE);
    127 
    128 	*dbase = tmp_dbase;
    129 
    130 	return STATUS_SUCCESS;
    131 
    132       omem:
    133 	ERR(handle, "out of memory, could not initialize active database");
    134 	free(tmp_dbase);
    135 	return STATUS_ERR;
    136 }
    137 
    138 /* Release dbase resources */
    139 void dbase_activedb_release(dbase_activedb_t * dbase)
    140 {
    141 
    142 	dbase_llist_drop_cache(&dbase->llist);
    143 	free(dbase);
    144 }
    145 
    146 /* ACTIVEDB dbase - method table implementation */
    147 dbase_table_t SEMANAGE_ACTIVEDB_DTABLE = {
    148 
    149 	/* Cache/Transactions */
    150 	.cache = dbase_activedb_cache,
    151 	.drop_cache = (void *)dbase_llist_drop_cache,
    152 	.flush = dbase_activedb_flush,
    153 	.is_modified = (void *)dbase_llist_is_modified,
    154 
    155 	/* Database API */
    156 	.iterate = (void *)dbase_llist_iterate,
    157 	.exists = (void *)dbase_llist_exists,
    158 	.list = (void *)dbase_llist_list,
    159 	.add = (void *)dbase_llist_add,
    160 	.set = (void *)dbase_llist_set,
    161 	.del = (void *)dbase_llist_del,
    162 	.clear = (void *)dbase_llist_clear,
    163 	.modify = (void *)dbase_llist_modify,
    164 	.query = (void *)dbase_llist_query,
    165 	.count = (void *)dbase_llist_count,
    166 
    167 	/* Polymorphism */
    168 	.get_rtable = (void *)dbase_llist_get_rtable
    169 };
    170