main netmisc / compat / db.c
  1#include <sys/types.h>
  2
  3#include <errno.h>
  4#include <stdlib.h>
  5#include <string.h>
  6
  7#include "db.h"
  8
  9struct compat_db_entry {
 10	DBT key;
 11	DBT value;
 12	struct compat_db_entry *next;
 13};
 14
 15struct compat_db_state {
 16	struct compat_db_entry *head;
 17	struct compat_db_entry *iter;
 18};
 19
 20static int
 21compat_db_close(DB *db)
 22{
 23	struct compat_db_state *state;
 24	struct compat_db_entry *entry;
 25	struct compat_db_entry *next;
 26
 27	if (db == NULL)
 28		return 0;
 29	state = db->internal;
 30	if (state != NULL) {
 31		for (entry = state->head; entry != NULL; entry = next) {
 32			next = entry->next;
 33			free(entry->key.data);
 34			free(entry->value.data);
 35			free(entry);
 36		}
 37		free(state);
 38	}
 39	free(db);
 40	return 0;
 41}
 42
 43static int
 44compat_db_get(DB *db, DBT *key, DBT *data, unsigned int flags)
 45{
 46	struct compat_db_state *state;
 47	struct compat_db_entry *entry;
 48
 49	(void)flags;
 50	state = db->internal;
 51	for (entry = state->head; entry != NULL; entry = entry->next) {
 52		if (entry->key.size == key->size &&
 53		    memcmp(entry->key.data, key->data, key->size) == 0) {
 54			data->data = entry->value.data;
 55			data->size = entry->value.size;
 56			return 0;
 57		}
 58	}
 59	return 1;
 60}
 61
 62static int
 63compat_db_put(DB *db, DBT *key, DBT *data, unsigned int flags)
 64{
 65	struct compat_db_state *state;
 66	struct compat_db_entry *entry;
 67	void *copy;
 68
 69	(void)flags;
 70	state = db->internal;
 71	for (entry = state->head; entry != NULL; entry = entry->next) {
 72		if (entry->key.size == key->size &&
 73		    memcmp(entry->key.data, key->data, key->size) == 0) {
 74			copy = malloc(data->size);
 75			if (copy == NULL)
 76				return -1;
 77			memcpy(copy, data->data, data->size);
 78			free(entry->value.data);
 79			entry->value.data = copy;
 80			entry->value.size = data->size;
 81			return 0;
 82		}
 83	}
 84
 85	entry = calloc(1, sizeof(*entry));
 86	if (entry == NULL)
 87		return -1;
 88	entry->key.data = malloc(key->size);
 89	entry->value.data = malloc(data->size);
 90	if (entry->key.data == NULL || entry->value.data == NULL) {
 91		free(entry->key.data);
 92		free(entry->value.data);
 93		free(entry);
 94		return -1;
 95	}
 96	memcpy(entry->key.data, key->data, key->size);
 97	memcpy(entry->value.data, data->data, data->size);
 98	entry->key.size = key->size;
 99	entry->value.size = data->size;
100	entry->next = state->head;
101	state->head = entry;
102	return 0;
103}
104
105static int
106compat_db_seq(DB *db, DBT *key, DBT *data, unsigned int flags)
107{
108	struct compat_db_state *state;
109	struct compat_db_entry *entry;
110
111	state = db->internal;
112	if (flags == R_FIRST)
113		state->iter = state->head;
114	else if (flags == R_NEXT && state->iter != NULL)
115		state->iter = state->iter->next;
116
117	entry = state->iter;
118	if (entry == NULL)
119		return 1;
120
121	key->data = entry->key.data;
122	key->size = entry->key.size;
123	data->data = entry->value.data;
124	data->size = entry->value.size;
125	return 0;
126}
127
128DB *
129dbopen(const char *fname, int flags, int mode, int type, const void *openinfo)
130{
131	DB *db;
132	struct compat_db_state *state;
133
134	(void)flags;
135	(void)mode;
136	(void)type;
137	(void)openinfo;
138
139	if (fname != NULL) {
140		errno = ENOTSUP;
141		return NULL;
142	}
143
144	db = calloc(1, sizeof(*db));
145	state = calloc(1, sizeof(*state));
146	if (db == NULL || state == NULL) {
147		free(db);
148		free(state);
149		return NULL;
150	}
151
152	db->close = compat_db_close;
153	db->get = compat_db_get;
154	db->put = compat_db_put;
155	db->seq = compat_db_seq;
156	db->internal = state;
157	return db;
158}