113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Copyright (C) 2005 Red Hat, Inc. */
213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Object: dbase_llist_t (Linked List)
413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Partially Implements: dbase_t (Database)
513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */
613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestruct dbase_llist;
813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef struct dbase_llist dbase_t;
913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define DBASE_DEFINED
1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h>
1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "debug.h"
1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "handle.h"
1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "database_llist.h"
1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_needs_resync(semanage_handle_t * handle, dbase_llist_t * dbase)
1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int cache_serial;
2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (dbase->cache_serial < 0)
2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 1;
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_serial = handle->funcs->get_serial(handle);
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (cache_serial < 0)
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 1;
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (cache_serial != dbase->cache_serial) {
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		dbase_llist_drop_cache(dbase);
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		dbase->cache_serial = -1;
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 1;
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Helper for adding records to the cache */
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_cache_prepend(semanage_handle_t * handle,
3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      dbase_llist_t * dbase, const record_t * data)
3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Initialize */
4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *entry = (cache_entry_t *) malloc(sizeof(cache_entry_t));
4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (entry == NULL)
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto omem;
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (dbase->rtable->clone(handle, data, &entry->data) < 0)
4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	entry->prev = NULL;
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	entry->next = dbase->cache;
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Link */
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (dbase->cache != NULL)
5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		dbase->cache->prev = entry;
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (dbase->cache_tail == NULL)
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		dbase->cache_tail = entry;
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->cache = entry;
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->cache_sz++;
5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      omem:
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "out of memory");
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not cache record");
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(entry);
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid dbase_llist_drop_cache(dbase_llist_t * dbase)
7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (dbase->cache_serial < 0)
7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return;
7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *prev, *ptr = dbase->cache;
7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	while (ptr != NULL) {
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		prev = ptr;
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ptr = ptr->next;
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		dbase->rtable->free(prev->data);
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		free(prev);
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->cache_serial = -1;
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->modified = 0;
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_set_serial(semanage_handle_t * handle, dbase_llist_t * dbase)
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int cache_serial = handle->funcs->get_serial(handle);
9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (cache_serial < 0) {
9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "could not update cache serial");
9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->cache_serial = cache_serial;
9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Helper for finding records in the cache */
10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int dbase_llist_cache_locate(semanage_handle_t * handle,
10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    dbase_llist_t * dbase,
10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    const record_key_t * key,
10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    cache_entry_t ** entry)
10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *ptr;
10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Implemented in parent */
11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (dbase->dtable->cache(handle, dbase) < 0)
11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (ptr = dbase->cache; ptr != NULL; ptr = ptr->next) {
11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!dbase->rtable->compare(ptr->data, key)) {
11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			*entry = ptr;
11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return STATUS_SUCCESS;
11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_NODATA;
12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not complete cache lookup");
12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_exists(semanage_handle_t * handle,
12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		       dbase_llist_t * dbase,
13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		       const record_key_t * key, int *response)
13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *entry;
13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int status;
13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	status = dbase_llist_cache_locate(handle, dbase, key, &entry);
13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (status < 0)
13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*response = (status != STATUS_NODATA);
14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not check if record exists");
14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_add(semanage_handle_t * handle,
14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    dbase_llist_t * dbase,
150f7dd4ca760de5f2dfa962749dddf8a99587f2257Justin P. Mattock		    const record_key_t * key __attribute__ ((unused)),
151f7dd4ca760de5f2dfa962749dddf8a99587f2257Justin P. Mattock			 const record_t * data)
15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (dbase_llist_cache_prepend(handle, dbase, data) < 0)
15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	key = NULL;
15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->modified = 1;
15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not add record to the database");
16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_set(semanage_handle_t * handle,
16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    dbase_llist_t * dbase,
16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    const record_key_t * key, const record_t * data)
16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *entry;
17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int status;
17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	status = dbase_llist_cache_locate(handle, dbase, key, &entry);
17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (status < 0)
17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (status == STATUS_NODATA) {
17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "record not found in the database");
17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	} else {
18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		dbase->rtable->free(entry->data);
18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (dbase->rtable->clone(handle, data, &entry->data) < 0)
18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto err;
18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->modified = 1;
18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not set record value");
19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_modify(semanage_handle_t * handle,
19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		       dbase_llist_t * dbase,
19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		       const record_key_t * key, const record_t * data)
19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *entry;
20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int status;
20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	status = dbase_llist_cache_locate(handle, dbase, key, &entry);
20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (status < 0)
20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (status == STATUS_NODATA) {
20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (dbase_llist_cache_prepend(handle, dbase, data) < 0)
20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto err;
20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	} else {
20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		dbase->rtable->free(entry->data);
21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (dbase->rtable->clone(handle, data, &entry->data) < 0)
21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto err;
21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->modified = 1;
21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not modify record value");
21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
222f7dd4ca760de5f2dfa962749dddf8a99587f2257Justin P. Mattockhidden int dbase_llist_count(semanage_handle_t * handle __attribute__ ((unused)),
22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			     dbase_llist_t * dbase, unsigned int *response)
22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*response = dbase->cache_sz;
22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	handle = NULL;
22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_query(semanage_handle_t * handle,
23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		      dbase_llist_t * dbase,
23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		      const record_key_t * key, record_t ** response)
23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *entry;
23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int status;
23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	status = dbase_llist_cache_locate(handle, dbase, key, &entry);
24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (status < 0 || status == STATUS_NODATA)
24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (dbase->rtable->clone(handle, entry->data, response) < 0)
24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not query record value");
25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_iterate(semanage_handle_t * handle,
25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			dbase_llist_t * dbase,
25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			int (*fn) (const record_t * record,
25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				   void *fn_arg), void *arg)
25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int rc;
26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *ptr;
26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (ptr = dbase->cache_tail; ptr != NULL; ptr = ptr->prev) {
26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		rc = fn(ptr->data, arg);
26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (rc < 0)
26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto err;
26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		else if (rc > 1)
26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not iterate over records");
27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
279f7dd4ca760de5f2dfa962749dddf8a99587f2257Justin P. Mattockint dbase_llist_del(semanage_handle_t * handle __attribute__ ((unused)),
28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    dbase_llist_t * dbase, const record_key_t * key)
28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *ptr, *prev = NULL;
28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (ptr = dbase->cache; ptr != NULL; ptr = ptr->next) {
28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!dbase->rtable->compare(ptr->data, key)) {
28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (prev != NULL)
28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				prev->next = ptr->next;
28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			else
29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				dbase->cache = ptr->next;
29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (ptr->next != NULL)
29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				ptr->next->prev = ptr->prev;
29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			else
29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				dbase->cache_tail = ptr->prev;
29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			dbase->rtable->free(ptr->data);
29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			dbase->cache_sz--;
29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			free(ptr);
30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			dbase->modified = 1;
30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return STATUS_SUCCESS;
30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		} else
30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			prev = ptr;
30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	handle = NULL;
30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_clear(semanage_handle_t * handle, dbase_llist_t * dbase)
31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int old_serial = dbase->cache_serial;
31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (dbase_llist_set_serial(handle, dbase) < 0) {
31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "could not set serial of cleared dbase");
31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (old_serial >= 0) {
32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		cache_entry_t *prev, *ptr = dbase->cache;
32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		while (ptr != NULL) {
32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			prev = ptr;
32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			ptr = ptr->next;
32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			dbase->rtable->free(prev->data);
32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			free(prev);
32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->cache = NULL;
33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->cache_tail = NULL;
33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->cache_sz = 0;
33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dbase->modified = 1;
33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint dbase_llist_list(semanage_handle_t * handle,
33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		     dbase_llist_t * dbase,
33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		     record_t *** records, unsigned int *count)
34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cache_entry_t *ptr;
34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	record_t **tmp_records = NULL;
34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	unsigned int tmp_count;
34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int i = 0;
34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_count = dbase->cache_sz;
34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (tmp_count > 0) {
34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		tmp_records = (record_t **)
35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    calloc(tmp_count, sizeof(record_t *));
35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (tmp_records == NULL)
35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto omem;
35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		for (ptr = dbase->cache_tail; ptr != NULL; ptr = ptr->prev) {
35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (dbase->rtable->clone(handle,
35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						 ptr->data,
35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						 &tmp_records[i]) < 0)
35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				goto err;
36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			i++;
36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*records = tmp_records;
36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*count = tmp_count;
36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      omem:
36913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "out of memory");
37013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
37113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
3722276a2fa51517ead7f4cf028263dee4b5e2bb46aEric Paris	if (tmp_records) {
3732276a2fa51517ead7f4cf028263dee4b5e2bb46aEric Paris		for (; i >= 0; i--)
3742276a2fa51517ead7f4cf028263dee4b5e2bb46aEric Paris			dbase->rtable->free(tmp_records[i]);
3752276a2fa51517ead7f4cf028263dee4b5e2bb46aEric Paris		free(tmp_records);
3762276a2fa51517ead7f4cf028263dee4b5e2bb46aEric Paris	}
37713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not allocate record array");
37813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
380