/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_DATABASE_H_ #define _SEMANAGE_DATABASE_H_ #ifndef DBASE_RECORD_DEFINED typedef void *record_t; typedef void *record_key_t; #define DBASE_RECORD_DEFINED #endif #ifndef DBASE_DEFINED typedef void *dbase_t; #define DBASE_DEFINED #endif /* Circular dependency */ struct semanage_handle; /* RECORD interface - method table */ typedef struct record_table { /* Create a record */ int (*create) (struct semanage_handle * handle, record_t ** rec); /* Extract key from record */ int (*key_extract) (struct semanage_handle * handle, const record_t * rec, record_key_t ** key); /* Free record key */ void (*key_free) (record_key_t * key); /* Return 0 if the record matches the key, * -1 if the key represents a record that should * be ordered before this record, and 1 if vice-versa */ int (*compare) (const record_t * rec, const record_key_t * key); /* Return 0 if the record matches record2, * -1 if record2 should be ordered before this record, * and 1 if vice-versa */ int (*compare2) (const record_t * rec, const record_t * rec2); /* Same as above, but dereferences the pointer first. * This function is intenteded to be used as a qsort * comparator. */ int (*compare2_qsort) (const record_t ** rec, const record_t ** rec2); /* Deep-copy clone of this record */ int (*clone) (struct semanage_handle * handle, const record_t * rec, record_t ** new_rec); /* Deallocate record resources. Must sucessfully handle NULL. */ void (*free) (record_t * rec); } record_table_t; /* DBASE interface - method table */ typedef struct dbase_table { /* --------------- Database Functionality ----------- */ /* Note: In all the functions below, the key is property * of the caller, and will not be modified by the database. * In add/set/modify, the data is also property of the caller */ /* Add the specified record to * the database. No check for duplicates is performed */ int (*add) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, const record_t * data); /* Add the specified record to the * database if it not present. * If it's present, replace it */ int (*modify) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, const record_t * data); /* Modify the specified record in the database * if it is present. Fail if it does not yet exist */ int (*set) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, const record_t * data); /* Delete a record */ int (*del) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key); /* Clear all records, and leave the database in * cached, modified state. This function does * not require a call to cache() */ int (*clear) (struct semanage_handle * handle, dbase_t * dbase); /* Retrieve a record * * Note: the resultant record * becomes property of the caller, and * must be freed accordingly */ int (*query) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, record_t ** response); /* Check if a record exists */ int (*exists) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, int *response); /* Count the number of records */ int (*count) (struct semanage_handle * handle, dbase_t * dbase, unsigned int *response); /* Execute the specified handler over * the records of this database. The handler * can signal a successful exit by returning 1, * an error exit by returning -1, and continue by * returning 0 * * Note: The record passed into the iterate handler * may or may not persist after the handler invocation, * and writing to it has unspecified behavior. It *must* * be cloned if modified, or preserved. * * Note: The iterate handler may not invoke any other * semanage read functions outside a transaction. It is only * reentrant while in transaction. The iterate handler may * not modify the underlying database. */ int (*iterate) (struct semanage_handle * handle, dbase_t * dbase, int (*fn) (const record_t * record, void *varg), void *fn_arg); /* Construct a list of all records in this database * * Note: The list returned becomes property of the caller, * and must be freed accordingly. */ int (*list) (struct semanage_handle * handle, dbase_t * dbase, record_t *** records, unsigned int *count); /* ---------- Cache/Transaction Management ---------- */ /* Cache the database (if supported). * This function must be invoked before using * any of the database functions above. It may be invoked * multiple times, and will update the cache if a commit * occurred between invocations */ int (*cache) (struct semanage_handle * handle, dbase_t * dbase); /* Forgets all changes that haven't been written * to the database backend */ void (*drop_cache) (dbase_t * dbase); /* Checks if there are any changes not written to the backend */ int (*is_modified) (dbase_t * dbase); /* Writes the database changes to its backend */ int (*flush) (struct semanage_handle * handle, dbase_t * dbase); /* ------------- Polymorphism ----------------------- */ /* Retrieves the record table for this database, * which specifies how to perform basic operations * on each record. */ record_table_t *(*get_rtable) (dbase_t * dbase); } dbase_table_t; typedef struct dbase_config { /* Database state */ dbase_t *dbase; /* Database methods */ dbase_table_t *dtable; } dbase_config_t; extern int dbase_add(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, const record_t * data); extern int dbase_modify(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, const record_t * data); extern int dbase_set(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, const record_t * data); extern int dbase_del(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key); extern int dbase_query(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, record_t ** response); extern int dbase_exists(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, int *response); extern int dbase_count(struct semanage_handle *handle, dbase_config_t * dconfig, unsigned int *response); extern int dbase_iterate(struct semanage_handle *handle, dbase_config_t * dconfig, int (*fn) (const record_t * record, void *fn_arg), void *fn_arg); extern int dbase_list(struct semanage_handle *handle, dbase_config_t * dconfig, record_t *** records, unsigned int *count); #endif