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