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}